From 273f6169301eba5461d90f07ec683ae06572e931 Mon Sep 17 00:00:00 2001 From: Pieter Noordhuis Date: Sun, 13 Jun 2010 21:42:04 +0200 Subject: [PATCH] make sure sets have the right encoding when loaded from rdb --- redis.c | 34 ++++++++++++++++++++++++++++------ tests/unit/type/set.tcl | 15 +++++++++++++++ 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/redis.c b/redis.c index 0cf768ac..0d6648ee 100644 --- a/redis.c +++ b/redis.c @@ -4234,16 +4234,38 @@ static robj *rdbLoadObject(int type, FILE *fp) { } else if (type == REDIS_SET) { /* Read list/set value */ if ((len = rdbLoadLen(fp,NULL)) == REDIS_RDB_LENERR) return NULL; - o = createSetObject(); - /* It's faster to expand the dict to the right size asap in order - * to avoid rehashing */ - if (len > DICT_HT_INITIAL_SIZE) - dictExpand(o->ptr,len); + + /* Use a regular set when there are too many entries. */ + if (len > server.set_max_intset_entries) { + o = createSetObject(); + /* It's faster to expand the dict to the right size asap in order + * to avoid rehashing */ + if (len > DICT_HT_INITIAL_SIZE) + dictExpand(o->ptr,len); + } else { + o = createIntsetObject(); + } + /* Load every single element of the list/set */ while(len--) { + long long llval; if ((ele = rdbLoadEncodedStringObject(fp)) == NULL) return NULL; ele = tryObjectEncoding(ele); - dictAdd((dict*)o->ptr,ele,NULL); + + if (o->encoding == REDIS_ENCODING_INTSET) { + /* Fetch integer value from element */ + if (getLongLongFromObject(ele,&llval) == REDIS_OK) { + o->ptr = intsetAdd(o->ptr,llval,NULL); + } else { + setTypeConvert(o,REDIS_ENCODING_HT); + } + } + + /* This will also be called when the set was just converted + * to regular hashtable encoded set */ + if (o->encoding == REDIS_ENCODING_HT) { + dictAdd((dict*)o->ptr,ele,NULL); + } } } else if (type == REDIS_ZSET) { /* Read list/set value */ diff --git a/tests/unit/type/set.tcl b/tests/unit/type/set.tcl index f9e7f4bd..a1b655ef 100644 --- a/tests/unit/type/set.tcl +++ b/tests/unit/type/set.tcl @@ -53,6 +53,21 @@ start_server { assert_encoding hashtable myset } + test "Set encoding after DEBUG RELOAD" { + r del myintset myhashset mylargeintset + for {set i 0} {$i < 100} {incr i} { r sadd myintset $i } + for {set i 0} {$i < 1280} {incr i} { r sadd mylargeintset $i } + for {set i 0} {$i < 256} {incr i} { r sadd myhashset [format "i%03d" $i] } + assert_encoding intset myintset + assert_encoding hashtable mylargeintset + assert_encoding hashtable myhashset + + r debug reload + assert_encoding intset myintset + assert_encoding hashtable mylargeintset + assert_encoding hashtable myhashset + } + test {SREM basics - regular set} { create_set myset {foo bar ciao} assert_encoding hashtable myset -- 2.47.2