summaryrefslogtreecommitdiff
path: root/src/rdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/rdb.c')
-rw-r--r--src/rdb.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/src/rdb.c b/src/rdb.c
index 2689b172d..1a5a7b2c5 100644
--- a/src/rdb.c
+++ b/src/rdb.c
@@ -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");
}