Skip to content

Commit 2c4c312

Browse files
committed
switch hashtable type only when object has volatile items
Signed-off-by: Ran Shidlansik <ranshid@amazon.com>
1 parent 124acbe commit 2c4c312

File tree

5 files changed

+28
-8
lines changed

5 files changed

+28
-8
lines changed

src/hashtable.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1139,6 +1139,13 @@ hashtableType *hashtableGetType(hashtable *ht) {
11391139
return ht->type;
11401140
}
11411141

1142+
/* Set the hashtable type and returns the old type of the hashtable. */
1143+
hashtableType *hashtableSetType(hashtable *ht, hashtableType *type) {
1144+
hashtableType *oldtype = ht->type;
1145+
ht->type = type;
1146+
return oldtype;
1147+
}
1148+
11421149
/* Returns a pointer to the table's metadata (userdata) section. */
11431150
void *hashtableMetadata(hashtable *ht) {
11441151
return &ht->metadata;

src/hashtable.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ hashtable *hashtableCreate(hashtableType *type);
122122
void hashtableRelease(hashtable *ht);
123123
void hashtableEmpty(hashtable *ht, void(callback)(hashtable *));
124124
hashtableType *hashtableGetType(hashtable *ht);
125+
hashtableType *hashtableSetType(hashtable *ht, hashtableType *type);
125126
void *hashtableMetadata(hashtable *ht);
126127
size_t hashtableSize(const hashtable *ht);
127128
size_t hashtableBuckets(hashtable *ht);

src/server.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,15 @@ hashtableType hashHashtableType = {
688688
.accessElement = hashHashtableTypeAccess,
689689
};
690690

691+
hashtableType hashWithVolatileItemsHashtableType = {
692+
.hashFunction = dictSdsHash,
693+
.entryGetKey = hashHashtableTypeGetKey,
694+
.keyCompare = hashtableSdsKeyCompare,
695+
.entryDestructor = hashHashtableTypeDestructor,
696+
.getMetadataSize = hashHashtableTypeMetadataSize,
697+
.accessElement = hashHashtableTypeAccess,
698+
};
699+
691700
/* Hashtable type without destructor */
692701
hashtableType sdsReplyHashtableType = {
693702
.hashFunction = dictSdsCaseHash,

src/server.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2632,6 +2632,7 @@ extern hashtableType kvstoreKeysHashtableType;
26322632
extern hashtableType kvstoreExpiresHashtableType;
26332633
extern double R_Zero, R_PosInf, R_NegInf, R_Nan;
26342634
extern hashtableType hashHashtableType;
2635+
extern hashtableType hashWithVolatileItemsHashtableType;
26352636
extern dictType stringSetDictType;
26362637
extern dictType externalStringType;
26372638
extern dictType sdsHashDictType;

src/t_hash.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,8 @@ hashTypeGetOrcreateVolatileSet(robj *o) {
405405
void hashTypeTrackEntry(robj *o, void *entry) {
406406
volatile_set *set = hashTypeGetOrcreateVolatileSet(o);
407407
serverAssert(volatileSetAddEntry(set, entry, hashTypeEntryGetExpiry(entry)));
408+
/* serves mainly for optimization. Use type which supports access function only when needed. */
409+
hashtableSetType(o->ptr, &hashWithVolatileItemsHashtableType);
408410
}
409411

410412
void hashTypeUntrackEntry(robj *o, void *entry) {
@@ -416,6 +418,8 @@ void hashTypeUntrackEntry(robj *o, void *entry) {
416418
freeVolatileSet(set);
417419
volatile_set **volatile_set_ref = hashtableMetadata(o->ptr);
418420
*volatile_set_ref = NULL;
421+
/* serves mainly for optimization. by changing the hashtable type we can avoid extra function call in hashtable access */
422+
hashtableSetType(o->ptr, &hashHashtableType);
419423
}
420424
}
421425

@@ -1448,14 +1452,12 @@ void hsetexCommand(client *c) {
14481452
break;
14491453
}
14501454
}
1451-
/* In case missing fields argument or bad number of fields provided, bail with syntax error */
1452-
if (num_fields <= 0) {
1455+
/* Check that the parsed fields number matches the real provided number of fields */
1456+
if (num_fields != (c->argc - fields_index) / 2) {
14531457
addReplyErrorObject(c, shared.syntaxerr);
14541458
return;
14551459
}
14561460

1457-
if (num_fields > (c->argc - fields_index) / 2) num_fields = (c->argc - fields_index) / 2; // Potential user error, but we would like to make effort to comply with the request.
1458-
14591461
o = lookupKeyWrite(c->db, c->argv[1]);
14601462
if (checkType(c, o, OBJ_HASH))
14611463
return;
@@ -1555,8 +1557,8 @@ void hgetexCommand(client *c) {
15551557
}
15561558
}
15571559

1558-
/* In case missing fields argument or bad number of fields provided, bail with syntax error */
1559-
if (num_fields <= 0) {
1560+
/* Check that the parsed fields number matches the real provided number of fields */
1561+
if (num_fields != (c->argc - fields_index)) {
15601562
addReplyErrorObject(c, shared.syntaxerr);
15611563
return;
15621564
}
@@ -1749,8 +1751,8 @@ void hexpireGenericCommand(client *c, long long basetime, int unit) {
17491751
}
17501752
}
17511753

1752-
/* In case missing fields argument or bad number of fields provided, bail with syntax error */
1753-
if (num_fields <= 0) {
1754+
/* Check that the parsed fields number matches the real provided number of fields */
1755+
if (num_fields != (c->argc - fields_index)) {
17541756
addReplyErrorObject(c, shared.syntaxerr);
17551757
return;
17561758
}

0 commit comments

Comments
 (0)