]> git.saurik.com Git - redis.git/commitdiff
ziplistPrev should return the tail when the argument is ZIP_END
authorPieter Noordhuis <pcnoordhuis@gmail.com>
Mon, 31 May 2010 18:17:21 +0000 (20:17 +0200)
committerPieter Noordhuis <pcnoordhuis@gmail.com>
Mon, 31 May 2010 18:17:21 +0000 (20:17 +0200)
ziplist.c
ziplist.h

index 1354b4ea1621ecdfd3a56ec68b74b8ee5ab77316..2aeffa41f55f65129dfa6d0364c19a3066e4c11a 100644 (file)
--- a/ziplist.c
+++ b/ziplist.c
@@ -428,14 +428,27 @@ unsigned char *ziplistIndex(unsigned char *zl, int index) {
 }
 
 /* Return pointer to next entry in ziplist. */
-unsigned char *ziplistNext(unsigned char *p) {
+unsigned char *ziplistNext(unsigned char *zl, unsigned char *p) {
+    ((void) zl);
     return (p[0] == ZIP_END) ? NULL : p+zipRawEntryLength(p);
 }
 
 /* Return pointer to previous entry in ziplist. */
-unsigned char *ziplistPrev(unsigned char *p) {
-    zlentry entry = zipEntry(p);
-    return (entry.prevrawlen == 0) ? NULL : p-entry.prevrawlen;
+unsigned char *ziplistPrev(unsigned char *zl, unsigned char *p) {
+    zlentry entry;
+
+    /* Iterating backwards from ZIP_END should return the tail. When "p" is
+     * equal to the first element of the list, we're already at the head,
+     * and should return NULL. */
+    if (p[0] == ZIP_END) {
+        p = ZIPLIST_ENTRY_TAIL(zl);
+        return (p[0] == ZIP_END) ? NULL : p;
+    } else if (p == ZIPLIST_ENTRY_HEAD(zl)) {
+        return NULL;
+    } else {
+        entry = zipEntry(p);
+        return p-entry.prevrawlen;
+    }
 }
 
 /* Get entry pointer to by 'p' and store in either 'e' or 'v' depending
@@ -709,7 +722,7 @@ int main(int argc, char **argv) {
             } else {
                 printf("%lld", value);
             }
-            p = ziplistNext(p);
+            p = ziplistNext(zl,p);
             printf("\n");
         }
         printf("\n");
@@ -726,7 +739,7 @@ int main(int argc, char **argv) {
             } else {
                 printf("%lld", value);
             }
-            p = ziplistNext(p);
+            p = ziplistNext(zl,p);
             printf("\n");
         }
         printf("\n");
@@ -743,7 +756,7 @@ int main(int argc, char **argv) {
             } else {
                 printf("%lld", value);
             }
-            p = ziplistNext(p);
+            p = ziplistNext(zl,p);
             printf("\n");
         }
         printf("\n");
@@ -772,7 +785,7 @@ int main(int argc, char **argv) {
             } else {
                 printf("%lld", value);
             }
-            p = ziplistPrev(p);
+            p = ziplistPrev(zl,p);
             printf("\n");
         }
         printf("\n");
@@ -789,7 +802,8 @@ int main(int argc, char **argv) {
             } else {
                 printf("%lld", value);
             }
-            zl = ziplistDelete(zl, &p, ZIPLIST_HEAD);
+            zl = ziplistDelete(zl,&p);
+            p = ziplistPrev(zl,p);
             printf("\n");
         }
         printf("\n");
index 08035dd5e317f931b5025808212869e30e1273f2..15153fea5548ee479f37aeb7dfa24ad760e8c0a4 100644 (file)
--- a/ziplist.h
+++ b/ziplist.h
@@ -5,8 +5,8 @@ unsigned char *ziplistNew(void);
 unsigned char *ziplistPush(unsigned char *zl, char *s, unsigned int slen, int where);
 unsigned char *ziplistPop(unsigned char *zl, sds *target, int where);
 unsigned char *ziplistIndex(unsigned char *zl, int index);
-unsigned char *ziplistNext(unsigned char *p);
-unsigned char *ziplistPrev(unsigned char *p);
+unsigned char *ziplistNext(unsigned char *zl, unsigned char *p);
+unsigned char *ziplistPrev(unsigned char *zl, unsigned char *p);
 unsigned int ziplistGet(unsigned char *p, char **sstr, unsigned int *slen, long long *sval);
 unsigned char *ziplistInsert(unsigned char *zl, unsigned char *p, char *s, unsigned int slen);
 unsigned char *ziplistDelete(unsigned char *zl, unsigned char **p, int direction);