diff options
Diffstat (limited to 'src/rdb.c')
-rw-r--r-- | src/rdb.c | 29 |
1 files changed, 18 insertions, 11 deletions
@@ -704,23 +704,30 @@ ssize_t rdbSaveObject(rio *rdb, robj *o) { nwritten += n; } else if (o->encoding == OBJ_ENCODING_SKIPLIST) { zset *zs = o->ptr; - dictIterator *di = dictGetIterator(zs->dict); - dictEntry *de; + zskiplist *zsl = zs->zsl; - if ((n = rdbSaveLen(rdb,dictSize(zs->dict))) == -1) return -1; + if ((n = rdbSaveLen(rdb,zsl->length)) == -1) return -1; nwritten += n; - while((de = dictNext(di)) != NULL) { - sds ele = dictGetKey(de); - double *score = dictGetVal(de); - - if ((n = rdbSaveRawString(rdb,(unsigned char*)ele,sdslen(ele))) - == -1) return -1; + /* We save the skiplist elements from the greatest to the smallest + * (that's trivial since the elements are already ordered in the + * skiplist): this improves the load process, since the next loaded + * element will always be the smaller, so adding to the skiplist + * will always immediately stop at the head, making the insertion + * O(1) instead of O(log(N)). */ + zskiplistNode *zn = zsl->tail; + while (zn != NULL) { + if ((n = rdbSaveRawString(rdb, + (unsigned char*)zn->ele,sdslen(zn->ele))) == -1) + { + return -1; + } nwritten += n; - if ((n = rdbSaveBinaryDoubleValue(rdb,*score)) == -1) return -1; + if ((n = rdbSaveBinaryDoubleValue(rdb,zn->score)) == -1) + return -1; nwritten += n; + zn = zn->backward; } - dictReleaseIterator(di); } else { serverPanic("Unknown sorted set encoding"); } |