summaryrefslogtreecommitdiff
path: root/src/aof.c
diff options
context:
space:
mode:
authorViktor Söderqvist <viktor.soderqvist@est.tech>2022-11-09 18:50:07 +0100
committerGitHub <noreply@github.com>2022-11-09 19:50:07 +0200
commit4e472a1a7fc0dc2c7da2b48ac7342e9385b4f92a (patch)
tree62715e6a8fb51264449aa6ef0866f92d9d1e00bf /src/aof.c
parent07d187066a86a9a3124af740373bf5bf49e345ff (diff)
downloadredis-4e472a1a7fc0dc2c7da2b48ac7342e9385b4f92a.tar.gz
Listpack encoding for sets (#11290)
Small sets with not only integer elements are listpack encoded, by default up to 128 elements, max 64 bytes per element, new config `set-max-listpack-entries` and `set-max-listpack-value`. This saves memory for small sets compared to using a hashtable. Sets with only integers, even very small sets, are still intset encoded (up to 1G limit, etc.). Larger sets are hashtable encoded. This PR increments the RDB version, and has an effect on OBJECT ENCODING Possible conversions when elements are added: intset -> listpack listpack -> hashtable intset -> hashtable Note: No conversion happens when elements are deleted. If all elements are deleted and then added again, the set is deleted and recreated, thus implicitly converted to a smaller encoding.
Diffstat (limited to 'src/aof.c')
-rw-r--r--src/aof.c67
1 files changed, 21 insertions, 46 deletions
diff --git a/src/aof.c b/src/aof.c
index 52026ab24..f1bf9a1a6 100644
--- a/src/aof.c
+++ b/src/aof.c
@@ -1818,56 +1818,31 @@ int rewriteListObject(rio *r, robj *key, robj *o) {
* The function returns 0 on error, 1 on success. */
int rewriteSetObject(rio *r, robj *key, robj *o) {
long long count = 0, items = setTypeSize(o);
-
- if (o->encoding == OBJ_ENCODING_INTSET) {
- int ii = 0;
- int64_t llval;
-
- while(intsetGet(o->ptr,ii++,&llval)) {
- if (count == 0) {
- int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ?
- AOF_REWRITE_ITEMS_PER_CMD : items;
-
- if (!rioWriteBulkCount(r,'*',2+cmd_items) ||
- !rioWriteBulkString(r,"SADD",4) ||
- !rioWriteBulkObject(r,key))
- {
- return 0;
- }
+ setTypeIterator *si = setTypeInitIterator(o);
+ char *str;
+ size_t len;
+ int64_t llval;
+ while (setTypeNext(si, &str, &len, &llval) != -1) {
+ if (count == 0) {
+ int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ?
+ AOF_REWRITE_ITEMS_PER_CMD : items;
+ if (!rioWriteBulkCount(r,'*',2+cmd_items) ||
+ !rioWriteBulkString(r,"SADD",4) ||
+ !rioWriteBulkObject(r,key))
+ {
+ return 0;
}
- if (!rioWriteBulkLongLong(r,llval)) return 0;
- if (++count == AOF_REWRITE_ITEMS_PER_CMD) count = 0;
- items--;
}
- } else if (o->encoding == OBJ_ENCODING_HT) {
- dictIterator *di = dictGetIterator(o->ptr);
- dictEntry *de;
-
- while((de = dictNext(di)) != NULL) {
- sds ele = dictGetKey(de);
- if (count == 0) {
- int cmd_items = (items > AOF_REWRITE_ITEMS_PER_CMD) ?
- AOF_REWRITE_ITEMS_PER_CMD : items;
-
- if (!rioWriteBulkCount(r,'*',2+cmd_items) ||
- !rioWriteBulkString(r,"SADD",4) ||
- !rioWriteBulkObject(r,key))
- {
- dictReleaseIterator(di);
- return 0;
- }
- }
- if (!rioWriteBulkString(r,ele,sdslen(ele))) {
- dictReleaseIterator(di);
- return 0;
- }
- if (++count == AOF_REWRITE_ITEMS_PER_CMD) count = 0;
- items--;
+ size_t written = str ?
+ rioWriteBulkString(r, str, len) : rioWriteBulkLongLong(r, llval);
+ if (!written) {
+ setTypeReleaseIterator(si);
+ return 0;
}
- dictReleaseIterator(di);
- } else {
- serverPanic("Unknown set encoding");
+ if (++count == AOF_REWRITE_ITEMS_PER_CMD) count = 0;
+ items--;
}
+ setTypeReleaseIterator(si);
return 1;
}