-
Notifications
You must be signed in to change notification settings - Fork 696
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace dict with new hashtable: hash datatype #1502
base: unstable
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## unstable #1502 +/- ##
============================================
- Coverage 70.93% 70.91% -0.03%
============================================
Files 120 120
Lines 64981 64965 -16
============================================
- Hits 46095 46068 -27
- Misses 18886 18897 +11
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I skimmed through it. I looks strait-forward. The only material thing to focus on seems to be the hashTypeEntry abstraction.
It would be good to have a clear abstraction and separation, even within t_hash.c, so we don't have too many direct accesses into the hashTypeEntry internals. It will help us later when we want to add things like TTL and embedded value.
61772d3
to
d357204
Compare
Signed-off-by: Rain Valentine <[email protected]>
…eld/value pairs Signed-off-by: Rain Valentine <[email protected]>
d357204
to
bc7d761
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome! Just a few nits.
Introducing the sds_const
type can preferably be a follow-up. It might trigger a long discussion.
/* takes ownership of value, does not take ownership of field */ | ||
hashTypeEntry *hashTypeCreateEntry(const sds field, sds value) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
const sds
is meaningless. Is it time to introduce theconst_sds
typedef in sds.h now? -
Take ownership of field but not value seems asymmetrical, but anything else is suboptimal, right? That's what we do for keys too IIRC. It's OK.
-
Shall we add a comment for the entry API, like the one below for the hash type API?
/*-----------------------------------------------------------------------------
* Hash entry API
*----------------------------------------------------------------------------*/
hashTypeEntry *hash_entry = entry; | ||
sds sds_val = hashTypeEntryGetValue(hash_entry); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The entry can be cast implicitly. You did that for sds sds_field = hashTypeEntryGetField(entry);
a few lines above.
hashTypeEntry *hash_entry = entry; | |
sds sds_val = hashTypeEntryGetValue(hash_entry); | |
sds sds_val = hashTypeEntryGetValue(entry); |
static void scanLaterSet(robj *ob, unsigned long *cursor) { | ||
if (ob->type != OBJ_SET || ob->encoding != OBJ_ENCODING_HASHTABLE) return; | ||
hashtable *ht = ob->ptr; | ||
*cursor = hashtableScanDefrag(ht, *cursor, activeDefragSdsHashtableCallback, NULL, activeDefragAlloc, HASHTABLE_SCAN_EMIT_REF); | ||
} | ||
|
||
static void activeDefragHashTypeEntry(void *privdata, void *element_ref) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a comment saying it's used as a scan callback.
sds hashTypeEntryGetField(const hashTypeEntry *entry) { | ||
const unsigned char *field = entry->field_data + entry->field_offset; | ||
return (sds)field; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This (and the GetValue) should probably return const_sds
if we add that type.
return size; | ||
} | ||
|
||
hashTypeEntry *hashTypeEntryDefrag(hashTypeEntry *entry, void *(*defragfn)(void *), sds (*sdsdefragfn)(sds)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a short comment above each of the functions, at least the non-trivial ones like this one.
sdsfree(dictGetVal(existing)); | ||
dictSetVal(ht, existing, v); | ||
/* exists: replace value */ | ||
hashTypeEntryReplaceValue(existing, v); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think hashTypeEntryReplaceValue
should return the entry, so we don't have to change the signature in the future. With embedded value, this function may need to reallocate the entry.
For now, we can just assert that it returns existing
.
hashTypeEntryReplaceValue(existing, v); | |
serverAssert(hashTypeEntryReplaceValue(existing, v) == existing); |
if (withvalues) value = hashTypeCurrentObjectNewSds(&hi, OBJ_HASH_VALUE); | ||
ret = dictAdd(d, key, value); | ||
ret = dictAdd(d, field, value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Follow-up: Let's replace this sdsReplyDictType with a hashtable.
@@ -1069,25 +1116,25 @@ void hrandfieldWithCountCommand(client *c, long l, int withvalues) { | |||
else { | |||
/* Hashtable encoding (generic implementation) */ | |||
unsigned long added = 0; | |||
listpackEntry key, value; | |||
listpackEntry field, value; | |||
dict *d = dictCreate(&hashDictType); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Follow-up: Let's replace this dict with a hashtable. Then we can delete that dict type.
This PR replaces dict with the new hashtable data structure in the HASH datatype. There is a new struct for hashtable items which contains a pointer to value sds string and the embedded key sds string. These values were previously stored in dictEntry. This structure is kept opaque so we can easily add small value embedding or other optimizations in the future.
closes #1095