Add listpack support, hgetf and hsetf commands (#13209)
**Changes:**
- Adds listpack support to hash field expiration
- Implements hgetf/hsetf commands
**Listpack support for hash field expiration**
We keep field name and value pairs in listpack for the hash type. With
this PR, if one of hash field expiration command is called on the key
for the first time, it converts listpack layout to triplets to hold
field name, value and ttl per field. If a field does not have a TTL, we
store zero as the ttl value. Zero is encoded as two bytes in the
listpack. So, once we convert listpack to hold triplets, for the fields
that don't have a TTL, it will be consuming those extra 2 bytes per
item. Fields are ordered by ttl in the listpack to find the field with
minimum expiry time efficiently.
**New command implementations as part of this PR:**
- HGETF command
For each specified field get its value and optionally set the field's
expiration time in sec/msec /unix-sec/unix-msec:
```
HGETF key
[NX | XX | GT | LT]
[EX seconds | PX milliseconds | EXAT unix-time-seconds | PXAT
unix-time-milliseconds | PERSIST]
<FIELDS count field [field ...]>
```
- HSETF command
For each specified field value pair: set field to value and optionally
set the field's expiration time in sec/msec /unix-sec/unix-msec:
```
HSETF key
[DC]
[DCF | DOF]
[NX | XX | GT | LT]
[GETNEW | GETOLD]
[EX seconds | PX milliseconds | EXAT unix-time-seconds | PXAT
unix-time-milliseconds | KEEPTTL]
<FVS count field value [field value …]>
```
Todo:
- Performance improvement.
- rdb load/save
- aof
- defrag
This commit is contained in:
+5
-11
@@ -333,17 +333,7 @@ void freeZsetObject(robj *o) {
|
||||
}
|
||||
|
||||
void freeHashObject(robj *o) {
|
||||
switch (o->encoding) {
|
||||
case OBJ_ENCODING_HT:
|
||||
dictRelease((dict*) o->ptr);
|
||||
break;
|
||||
case OBJ_ENCODING_LISTPACK:
|
||||
lpFree(o->ptr);
|
||||
break;
|
||||
default:
|
||||
serverPanic("Unknown hash encoding type");
|
||||
break;
|
||||
}
|
||||
hashTypeFree(o);
|
||||
}
|
||||
|
||||
void freeModuleObject(robj *o) {
|
||||
@@ -939,6 +929,7 @@ char *strEncoding(int encoding) {
|
||||
case OBJ_ENCODING_HT: return "hashtable";
|
||||
case OBJ_ENCODING_QUICKLIST: return "quicklist";
|
||||
case OBJ_ENCODING_LISTPACK: return "listpack";
|
||||
case OBJ_ENCODING_LISTPACK_EX: return "listpackex";
|
||||
case OBJ_ENCODING_INTSET: return "intset";
|
||||
case OBJ_ENCODING_SKIPLIST: return "skiplist";
|
||||
case OBJ_ENCODING_EMBSTR: return "embstr";
|
||||
@@ -1051,6 +1042,9 @@ size_t objectComputeSize(robj *key, robj *o, size_t sample_size, int dbid) {
|
||||
} else if (o->type == OBJ_HASH) {
|
||||
if (o->encoding == OBJ_ENCODING_LISTPACK) {
|
||||
asize = sizeof(*o)+zmalloc_size(o->ptr);
|
||||
} else if (o->encoding == OBJ_ENCODING_LISTPACK_EX) {
|
||||
listpackEx *lpt = o->ptr;
|
||||
asize = sizeof(*o) + zmalloc_size(lpt) + zmalloc_size(lpt->lp);
|
||||
} else if (o->encoding == OBJ_ENCODING_HT) {
|
||||
d = o->ptr;
|
||||
di = dictGetIterator(d);
|
||||
|
||||
Reference in New Issue
Block a user