]> git.saurik.com Git - redis.git/commitdiff
Merge branch 'ltrim-tests' of git://github.com/pietern/redis
authorantirez <antirez@gmail.com>
Mon, 14 Jun 2010 08:22:38 +0000 (10:22 +0200)
committerantirez <antirez@gmail.com>
Mon, 14 Jun 2010 08:22:38 +0000 (10:22 +0200)
redis.c
tests/support/test.tcl
tests/unit/type/list.tcl

diff --git a/redis.c b/redis.c
index 3fe9af1c7ca45229694cdf2f95e5b28138651be6..f6a765dad4299c86900449b8c78f1864fd806198 100644 (file)
--- a/redis.c
+++ b/redis.c
 #define REDIS_ENCODING_INT 1     /* Encoded as integer */
 #define REDIS_ENCODING_HT 2      /* Encoded as hash table */
 #define REDIS_ENCODING_ZIPMAP 3  /* Encoded as zipmap */
-#define REDIS_ENCODING_LIST 4    /* Encoded as zipmap */
+#define REDIS_ENCODING_LINKEDLIST 4 /* Encoded as regular linked list */
 #define REDIS_ENCODING_ZIPLIST 5 /* Encoded as ziplist */
 
 static char* strencoding[] = {
-    "raw", "int", "hashtable", "zipmap", "list", "ziplist"
+    "raw", "int", "hashtable", "zipmap", "linkedlist", "ziplist"
 };
 
 /* Object types only used for dumping to disk */
@@ -3059,7 +3059,7 @@ static robj *createListObject(void) {
     list *l = listCreate();
     robj *o = createObject(REDIS_LIST,l);
     listSetFreeMethod(l,decrRefCount);
-    o->encoding = REDIS_ENCODING_LIST;
+    o->encoding = REDIS_ENCODING_LINKEDLIST;
     return o;
 }
 
@@ -3101,7 +3101,7 @@ static void freeStringObject(robj *o) {
 
 static void freeListObject(robj *o) {
     switch (o->encoding) {
-    case REDIS_ENCODING_LIST:
+    case REDIS_ENCODING_LINKEDLIST:
         listRelease((list*) o->ptr);
         break;
     case REDIS_ENCODING_ZIPLIST:
@@ -3777,7 +3777,7 @@ static int rdbSaveObject(FILE *fp, robj *o) {
                 }
                 p = ziplistNext(o->ptr,p);
             }
-        } else if (o->encoding == REDIS_ENCODING_LIST) {
+        } else if (o->encoding == REDIS_ENCODING_LINKEDLIST) {
             list *list = o->ptr;
             listIter li;
             listNode *ln;
@@ -4187,7 +4187,7 @@ static robj *rdbLoadObject(int type, FILE *fp) {
             if (o->encoding == REDIS_ENCODING_ZIPLIST &&
                 ele->encoding == REDIS_ENCODING_RAW &&
                 sdslen(ele->ptr) > server.list_max_ziplist_value)
-                    listTypeConvert(o,REDIS_ENCODING_LIST);
+                    listTypeConvert(o,REDIS_ENCODING_LINKEDLIST);
 
             if (o->encoding == REDIS_ENCODING_ZIPLIST) {
                 dec = getDecodedObject(ele);
@@ -4927,7 +4927,7 @@ static void listTypeTryConversion(robj *subject, robj *value) {
     if (subject->encoding != REDIS_ENCODING_ZIPLIST) return;
     if (value->encoding == REDIS_ENCODING_RAW &&
         sdslen(value->ptr) > server.list_max_ziplist_value)
-            listTypeConvert(subject,REDIS_ENCODING_LIST);
+            listTypeConvert(subject,REDIS_ENCODING_LINKEDLIST);
 }
 
 static void listTypePush(robj *subject, robj *value, int where) {
@@ -4935,14 +4935,14 @@ static void listTypePush(robj *subject, robj *value, int where) {
     listTypeTryConversion(subject,value);
     if (subject->encoding == REDIS_ENCODING_ZIPLIST &&
         ziplistLen(subject->ptr) >= server.list_max_ziplist_entries)
-            listTypeConvert(subject,REDIS_ENCODING_LIST);
+            listTypeConvert(subject,REDIS_ENCODING_LINKEDLIST);
 
     if (subject->encoding == REDIS_ENCODING_ZIPLIST) {
         int pos = (where == REDIS_HEAD) ? ZIPLIST_HEAD : ZIPLIST_TAIL;
         value = getDecodedObject(value);
         subject->ptr = ziplistPush(subject->ptr,value->ptr,sdslen(value->ptr),pos);
         decrRefCount(value);
-    } else if (subject->encoding == REDIS_ENCODING_LIST) {
+    } else if (subject->encoding == REDIS_ENCODING_LINKEDLIST) {
         if (where == REDIS_HEAD) {
             listAddNodeHead(subject->ptr,value);
         } else {
@@ -4972,7 +4972,7 @@ static robj *listTypePop(robj *subject, int where) {
             /* We only need to delete an element when it exists */
             subject->ptr = ziplistDelete(subject->ptr,&p);
         }
-    } else if (subject->encoding == REDIS_ENCODING_LIST) {
+    } else if (subject->encoding == REDIS_ENCODING_LINKEDLIST) {
         list *list = subject->ptr;
         listNode *ln;
         if (where == REDIS_HEAD) {
@@ -4994,7 +4994,7 @@ static robj *listTypePop(robj *subject, int where) {
 static unsigned long listTypeLength(robj *subject) {
     if (subject->encoding == REDIS_ENCODING_ZIPLIST) {
         return ziplistLen(subject->ptr);
-    } else if (subject->encoding == REDIS_ENCODING_LIST) {
+    } else if (subject->encoding == REDIS_ENCODING_LINKEDLIST) {
         return listLength((list*)subject->ptr);
     } else {
         redisPanic("Unknown list encoding");
@@ -5025,7 +5025,7 @@ static listTypeIterator *listTypeInitIterator(robj *subject, int index, unsigned
     li->direction = direction;
     if (li->encoding == REDIS_ENCODING_ZIPLIST) {
         li->zi = ziplistIndex(subject->ptr,index);
-    } else if (li->encoding == REDIS_ENCODING_LIST) {
+    } else if (li->encoding == REDIS_ENCODING_LINKEDLIST) {
         li->ln = listIndex(subject->ptr,index);
     } else {
         redisPanic("Unknown list encoding");
@@ -5055,7 +5055,7 @@ static int listTypeNext(listTypeIterator *li, listTypeEntry *entry) {
                 li->zi = ziplistPrev(li->subject->ptr,li->zi);
             return 1;
         }
-    } else if (li->encoding == REDIS_ENCODING_LIST) {
+    } else if (li->encoding == REDIS_ENCODING_LINKEDLIST) {
         entry->ln = li->ln;
         if (entry->ln != NULL) {
             if (li->direction == REDIS_TAIL)
@@ -5086,7 +5086,7 @@ static robj *listTypeGet(listTypeEntry *entry) {
                 value = createStringObjectFromLongLong(vlong);
             }
         }
-    } else if (li->encoding == REDIS_ENCODING_LIST) {
+    } else if (li->encoding == REDIS_ENCODING_LINKEDLIST) {
         redisAssert(entry->ln != NULL);
         value = listNodeValue(entry->ln);
         incrRefCount(value);
@@ -5114,7 +5114,7 @@ static void listTypeInsert(listTypeEntry *entry, robj *value, int where) {
             subject->ptr = ziplistInsert(subject->ptr,entry->zi,value->ptr,sdslen(value->ptr));
         }
         decrRefCount(value);
-    } else if (entry->li->encoding == REDIS_ENCODING_LIST) {
+    } else if (entry->li->encoding == REDIS_ENCODING_LINKEDLIST) {
         if (where == REDIS_TAIL) {
             listInsertNode(subject->ptr,entry->ln,value,AL_START_TAIL);
         } else {
@@ -5132,7 +5132,7 @@ static int listTypeEqual(listTypeEntry *entry, robj *o) {
     if (li->encoding == REDIS_ENCODING_ZIPLIST) {
         redisAssert(o->encoding == REDIS_ENCODING_RAW);
         return ziplistCompare(entry->zi,o->ptr,sdslen(o->ptr));
-    } else if (li->encoding == REDIS_ENCODING_LIST) {
+    } else if (li->encoding == REDIS_ENCODING_LINKEDLIST) {
         return equalStringObjects(o,listNodeValue(entry->ln));
     } else {
         redisPanic("Unknown list encoding");
@@ -5151,7 +5151,7 @@ static void listTypeDelete(listTypeEntry *entry) {
             li->zi = p;
         else
             li->zi = ziplistPrev(li->subject->ptr,p);
-    } else if (entry->li->encoding == REDIS_ENCODING_LIST) {
+    } else if (entry->li->encoding == REDIS_ENCODING_LINKEDLIST) {
         listNode *next;
         if (li->direction == REDIS_TAIL)
             next = entry->ln->next;
@@ -5169,7 +5169,7 @@ static void listTypeConvert(robj *subject, int enc) {
     listTypeEntry entry;
     redisAssert(subject->type == REDIS_LIST);
 
-    if (enc == REDIS_ENCODING_LIST) {
+    if (enc == REDIS_ENCODING_LINKEDLIST) {
         list *l = listCreate();
         listSetFreeMethod(l,decrRefCount);
 
@@ -5178,7 +5178,7 @@ static void listTypeConvert(robj *subject, int enc) {
         while (listTypeNext(li,&entry)) listAddNodeTail(l,listTypeGet(&entry));
         listTypeReleaseIterator(li);
 
-        subject->encoding = REDIS_ENCODING_LIST;
+        subject->encoding = REDIS_ENCODING_LINKEDLIST;
         zfree(subject->ptr);
         subject->ptr = l;
     } else {
@@ -5254,7 +5254,7 @@ static void pushxGenericCommand(redisClient *c, robj *refval, robj *val, int whe
             /* Check if the length exceeds the ziplist length threshold. */
             if (subject->encoding == REDIS_ENCODING_ZIPLIST &&
                 ziplistLen(subject->ptr) > server.list_max_ziplist_entries)
-                    listTypeConvert(subject,REDIS_ENCODING_LIST);
+                    listTypeConvert(subject,REDIS_ENCODING_LINKEDLIST);
             server.dirty++;
         } else {
             /* Notify client of a failed insert */
@@ -5316,7 +5316,7 @@ static void lindexCommand(redisClient *c) {
         } else {
             addReply(c,shared.nullbulk);
         }
-    } else if (o->encoding == REDIS_ENCODING_LIST) {
+    } else if (o->encoding == REDIS_ENCODING_LINKEDLIST) {
         listNode *ln = listIndex(o->ptr,index);
         if (ln != NULL) {
             value = listNodeValue(ln);
@@ -5349,7 +5349,7 @@ static void lsetCommand(redisClient *c) {
             addReply(c,shared.ok);
             server.dirty++;
         }
-    } else if (o->encoding == REDIS_ENCODING_LIST) {
+    } else if (o->encoding == REDIS_ENCODING_LINKEDLIST) {
         listNode *ln = listIndex(o->ptr,index);
         if (ln == NULL) {
             addReply(c,shared.outofrangeerr);
@@ -5461,7 +5461,7 @@ static void ltrimCommand(redisClient *c) {
     if (o->encoding == REDIS_ENCODING_ZIPLIST) {
         o->ptr = ziplistDeleteRange(o->ptr,0,ltrim);
         o->ptr = ziplistDeleteRange(o->ptr,-rtrim,rtrim);
-    } else if (o->encoding == REDIS_ENCODING_LIST) {
+    } else if (o->encoding == REDIS_ENCODING_LINKEDLIST) {
         list = o->ptr;
         for (j = 0; j < ltrim; j++) {
             ln = listFirst(list);
@@ -9151,7 +9151,7 @@ static int rewriteAppendOnlyFile(char *filename) {
                         }
                         p = ziplistNext(zl,p);
                     }
-                } else if (o->encoding == REDIS_ENCODING_LIST) {
+                } else if (o->encoding == REDIS_ENCODING_LINKEDLIST) {
                     list *list = o->ptr;
                     listNode *ln;
                     listIter li;
index 4caa6ca79731ef97d626d4cde8025b757b37c0f6..988189bfa10887fbce8cbfe3fedf5290f1a75325 100644 (file)
@@ -26,6 +26,8 @@ proc assert_error {pattern code} {
 }
 
 proc assert_encoding {enc key} {
+    # swapped out value doesn't have encoding, so swap in first
+    r debug swapin $key
     assert_match "* encoding:$enc *" [r debug object $key]
 }
 
index 1d69a88f1891a43c3b774fdd3032f9d4fe864a70..ecae5d228f09f92e1b0fd6bce01d8bb1eea43864 100644 (file)
@@ -33,7 +33,7 @@ start_server {
 
         # first lpush then rpush
         assert_equal 1 [r lpush mylist1 $large_value]
-        assert_encoding list mylist1
+        assert_encoding linkedlist mylist1
         assert_equal 2 [r rpush mylist1 b]
         assert_equal 3 [r rpush mylist1 c]
         assert_equal 3 [r llen mylist1]
@@ -43,7 +43,7 @@ start_server {
 
         # first rpush then lpush
         assert_equal 1 [r rpush mylist2 $large_value]
-        assert_encoding list mylist2
+        assert_encoding linkedlist mylist2
         assert_equal 2 [r lpush mylist2 b]
         assert_equal 3 [r lpush mylist2 c]
         assert_equal 3 [r llen mylist2]
@@ -70,12 +70,12 @@ start_server {
         assert_encoding ziplist $key
     }
 
-    proc create_list {key entries} {
+    proc create_linkedlist {key entries} {
         r del $key
         r rpush $key "aaaaaaaaaaaaaaaaa"
         foreach entry $entries { r rpush $key $entry }
         assert_equal "aaaaaaaaaaaaaaaaa" [r lpop $key]
-        assert_encoding list $key
+        assert_encoding linkedlist $key
     }
 
     test {LPUSHX, RPUSHX - generic} {
@@ -86,7 +86,7 @@ start_server {
         assert_equal 0 [r llen xlist]
     }
 
-    foreach type {ziplist list} {
+    foreach type {ziplist linkedlist} {
         test "LPUSHX, RPUSHX - $type" {
             create_$type xlist {b c}
             assert_equal 3 [r rpushx xlist d]
@@ -119,18 +119,18 @@ start_server {
         # convert when a large value is pushed
         create_ziplist xlist a
         assert_equal 2 [r rpushx xlist $large_value]
-        assert_encoding list xlist
+        assert_encoding linkedlist xlist
         create_ziplist xlist a
         assert_equal 2 [r lpushx xlist $large_value]
-        assert_encoding list xlist
+        assert_encoding linkedlist xlist
 
         # convert when the length threshold is exceeded
         create_ziplist xlist [lrepeat 256 a]
         assert_equal 257 [r rpushx xlist b]
-        assert_encoding list xlist
+        assert_encoding linkedlist xlist
         create_ziplist xlist [lrepeat 256 a]
         assert_equal 257 [r lpushx xlist b]
-        assert_encoding list xlist
+        assert_encoding linkedlist xlist
     }
 
     test {LINSERT convert from ziplist to list} {
@@ -139,18 +139,18 @@ start_server {
         # convert when a large value is inserted
         create_ziplist xlist a
         assert_equal 2 [r linsert xlist before a $large_value]
-        assert_encoding list xlist
+        assert_encoding linkedlist xlist
         create_ziplist xlist a
         assert_equal 2 [r linsert xlist after a $large_value]
-        assert_encoding list xlist
+        assert_encoding linkedlist xlist
 
         # convert when the length threshold is exceeded
         create_ziplist xlist [lrepeat 256 a]
         assert_equal 257 [r linsert xlist before a a]
-        assert_encoding list xlist
+        assert_encoding linkedlist xlist
         create_ziplist xlist [lrepeat 256 a]
         assert_equal 257 [r linsert xlist after a a]
-        assert_encoding list xlist
+        assert_encoding linkedlist xlist
 
         # don't convert when the value could not be inserted
         create_ziplist xlist [lrepeat 256 a]
@@ -161,7 +161,7 @@ start_server {
         assert_encoding ziplist xlist
     }
 
-    foreach {type num} {ziplist 250 list 500} {
+    foreach {type num} {ziplist 250 linkedlist 500} {
         proc check_numbered_list_consistency {key} {
             set len [r llen $key]
             for {set i 0} {$i < $len} {incr i} {
@@ -227,7 +227,7 @@ start_server {
         assert_error ERR* {r rpush mylist 0}
     }
 
-    foreach type {ziplist list} {
+    foreach type {ziplist linkedlist} {
         test "RPOPLPUSH base case - $type" {
             r del mylist1 mylist2
             create_$type mylist1 {a b c d}
@@ -245,7 +245,7 @@ start_server {
             assert_equal {c a b} [r lrange mylist 0 -1]
         }
 
-        foreach othertype {ziplist list} {
+        foreach othertype {ziplist linkedlist} {
             test "RPOPLPUSH with $type source and existing target $othertype" {
                 create_$type srclist {a b c d}
                 create_$othertype dstlist {x}
@@ -285,7 +285,7 @@ start_server {
         assert_equal {} [r rpoplpush srclist dstlist]
     } {}
 
-    foreach type {ziplist list} {
+    foreach type {ziplist linkedlist} {
         test "Basic LPOP/RPOP - $type" {
             create_$type mylist {0 1 2}
             assert_equal 0 [r lpop mylist]
@@ -305,7 +305,7 @@ start_server {
         assert_error ERR*kind* {r rpop notalist}
     }
 
-    foreach {type num} {ziplist 250 list 500} {
+    foreach {type num} {ziplist 250 linkedlist 500} {
         test "Mass RPOP/LPOP - $type" {
             r del mylist
             set sum1 0
@@ -323,7 +323,7 @@ start_server {
         }
     }
 
-    foreach type {ziplist list} {
+    foreach type {ziplist linkedlist} {
         test "LRANGE basics - $type" {
             create_$type mylist {0 1 2 3 4 5 6 7 8 9}
             assert_equal {1 2 3 4 5 6 7 8} [r lrange mylist 1 -2]
@@ -346,36 +346,65 @@ start_server {
         assert_equal {} [r lrange nosuchkey 0 1]
     }
 
-    foreach type {ziplist list} {
-        test "LTRIM basics - $type" {
-            create_$type mylist "foo"
-            for {set i 0} {$i < 100} {incr i} {
-                r lpush mylist $i
-                r ltrim mylist 0 4
-            }
+    foreach type {ziplist linkedlist} {
+        proc trim_list {type min max} {
+            r del mylist
+            create_$type mylist {1 2 3 4 5}
+            r ltrim mylist $min $max
             r lrange mylist 0 -1
-        } {99 98 97 96 95}
-
-        test "LTRIM stress testing - $type" {
-            set mylist {}
-            for {set i 0} {$i < 20} {incr i} {
-                lappend mylist $i
-            }
+        }
 
-            for {set j 0} {$j < 100} {incr j} {
-                create_$type mylist $mylist
+        test "LTRIM basics - $type" {
+            assert_equal {1} [trim_list $type 0 0]
+            assert_equal {1 2} [trim_list $type 0 1]
+            assert_equal {1 2 3} [trim_list $type 0 2]
+            assert_equal {2 3} [trim_list $type 1 2]
+            assert_equal {2 3 4 5} [trim_list $type 1 -1]
+            assert_equal {2 3 4} [trim_list $type 1 -2]
+            assert_equal {4 5} [trim_list $type -2 -1]
+            assert_equal {5} [trim_list $type -1 -1]
+            assert_equal {1 2 3 4 5} [trim_list $type -5 -1]
+            assert_equal {1 2 3 4 5} [trim_list $type -10 10]
+            assert_equal {1 2 3 4 5} [trim_list $type 0 5]
+            assert_equal {1 2 3 4 5} [trim_list $type 0 10]
+        }
 
-                # Trim at random
-                set a [randomInt 20]
-                set b [randomInt 20]
-                r ltrim mylist $a $b
-                assert_equal [lrange $mylist $a $b] [r lrange mylist 0 -1]
+        tags {"slow"} {
+            test "LTRIM stress testing - $type" {
+                set mylist {}
+                set startlen 32
+                r del mylist
+                for {set i 0} {$i < $startlen} {incr i} {
+                    set str [randomInt 9223372036854775807]
+                    r rpush mylist $str
+                    lappend mylist $str
+                }
+
+                # do a push/pop of a large value to convert to a real list
+                if {$type eq "list"} {
+                    r rpush mylist "aaaaaaaaaaaaaaaaa"
+                    r rpop mylist
+                    assert_encoding linkedlist mylist
+                }
+
+                for {set i 0} {$i < 10000} {incr i} {
+                    set min [expr {int(rand()*$startlen)}]
+                    set max [expr {$min+int(rand()*$startlen)}]
+                    set mylist [lrange $mylist $min $max]
+                    r ltrim mylist $min $max
+                    assert_equal $mylist [r lrange mylist 0 -1]
+
+                    for {set j [r llen mylist]} {$j < $startlen} {incr j} {
+                        set str [randomInt 9223372036854775807]
+                        r rpush mylist $str
+                        lappend mylist $str
+                    }
+                }
             }
         }
-
     }
 
-    foreach type {ziplist list} {
+    foreach type {ziplist linkedlist} {
         test "LSET - $type" {
             create_$type mylist {99 98 97 96 95}
             r lset mylist 1 foo
@@ -397,7 +426,7 @@ start_server {
         assert_error ERR*value* {r lset nolist 0 foo}
     }
 
-    foreach type {ziplist list} {
+    foreach type {ziplist linkedlist} {
         test "LREM remove all the occurrences - $type" {
             create_$type mylist {foo bar foobar foobared zap bar test foo}
             assert_equal 2 [r lrem mylist 0 bar]