]> git.saurik.com Git - redis.git/commitdiff
updated iteration code to work well with different encodings
authorPieter Noordhuis <pcnoordhuis@gmail.com>
Sat, 22 May 2010 13:48:27 +0000 (15:48 +0200)
committerPieter Noordhuis <pcnoordhuis@gmail.com>
Sat, 29 May 2010 19:10:16 +0000 (21:10 +0200)
ziplist.c

index c2e56bfb0556123ebfc8b5fddf858c4ab00c7236..fe2bfaf6ccebafa8f0d218dc9e107562a5fc2701 100644 (file)
--- a/ziplist.c
+++ b/ziplist.c
@@ -296,18 +296,31 @@ unsigned char *ziplistIndex(unsigned char *zl, unsigned int index) {
     return p;
 }
 
-/* Store entry at current position in sds *value and return pointer
- * to the next entry. */
-unsigned char *ziplistNext(unsigned char *p, unsigned char **q, unsigned char **entry, unsigned int *elen) {
-    unsigned int lensize;
-    if (*p == ZIP_END) return NULL;
-    if (entry) {
-        *elen = zipDecodeLength(p,&lensize);
-        *entry = p+lensize;
+/* Return pointer to next entry in ziplist. */
+unsigned char *ziplistNext(unsigned char *p) {
+    return *p == ZIP_END ? p : p+zipRawEntryLength(p);
+}
+
+/* Get entry pointer to by 'p' and store in either 'e' or 'v' depending
+ * on the encoding of the entry. 'e' is always set to NULL to be able
+ * to find out whether the string pointer or the integer value was set.
+ * Return 0 if 'p' points to the end of the zipmap, 1 otherwise. */
+unsigned int ziplistGet(unsigned char *p, unsigned char **e, unsigned int *elen, long long *v) {
+    unsigned int len, lensize;
+    if (*p == ZIP_END) return 0;
+    if (e) *e = NULL;
+    len = zipDecodeLength(p,&lensize);
+    if (ZIP_ENCODING(p) == ZIP_ENC_RAW) {
+        if (e) {
+            *elen = len;
+            *e = p+lensize;
+        }
+    } else {
+        if (v) {
+            *v = zipLoadInteger(p+lensize,ZIP_ENCODING(p));
+        }
     }
-    if (q != NULL) *q = p;
-    p += zipRawEntryLength(p);
-    return p;
+    return 1;
 }
 
 /* Delete a range of entries from the ziplist. */
@@ -382,6 +395,7 @@ unsigned char *createList() {
     zl = ziplistPush(zl, (unsigned char*)"foo", 3, ZIPLIST_TAIL);
     zl = ziplistPush(zl, (unsigned char*)"quux", 4, ZIPLIST_TAIL);
     zl = ziplistPush(zl, (unsigned char*)"hello", 5, ZIPLIST_HEAD);
+    zl = ziplistPush(zl, (unsigned char*)"1024", 4, ZIPLIST_TAIL);
     return zl;
 }
 
@@ -407,6 +421,7 @@ unsigned char *createIntList() {
 int main(int argc, char **argv) {
     unsigned char *zl, *p, *q, *entry;
     unsigned int elen;
+    long long value;
     sds s;
 
     zl = createIntList();
@@ -427,10 +442,15 @@ int main(int argc, char **argv) {
     {
         zl = createList();
         p = ziplistIndex(zl, 0);
-        while ((p = ziplistNext(p, NULL, &entry, &elen)) != NULL) {
+        while (ziplistGet(p, &entry, &elen, &value)) {
             printf("Entry: ");
-            fwrite(entry,elen,1,stdout);
-            printf(" (length %d)\n", elen);
+            if (entry) {
+                fwrite(entry,elen,1,stdout);
+            } else {
+                printf("%lld", value);
+            }
+            p = ziplistNext(p);
+            printf("\n");
         }
         printf("\n");
     }
@@ -439,10 +459,15 @@ int main(int argc, char **argv) {
     {
         zl = createList();
         p = ziplistIndex(zl, 1);
-        while ((p = ziplistNext(p, NULL, &entry, &elen)) != NULL) {
+        while (ziplistGet(p, &entry, &elen, &value)) {
             printf("Entry: ");
-            fwrite(entry,elen,1,stdout);
-            printf(" (length %d)\n", elen);
+            if (entry) {
+                fwrite(entry,elen,1,stdout);
+            } else {
+                printf("%lld", value);
+            }
+            p = ziplistNext(p);
+            printf("\n");
         }
         printf("\n");
     }
@@ -451,10 +476,15 @@ int main(int argc, char **argv) {
     {
         zl = createList();
         p = ziplistIndex(zl, 2);
-        while ((p = ziplistNext(p, NULL, &entry, &elen)) != NULL) {
+        while (ziplistGet(p, &entry, &elen, &value)) {
             printf("Entry: ");
-            fwrite(entry,elen,1,stdout);
-            printf(" (length %d)\n", elen);
+            if (entry) {
+                fwrite(entry,elen,1,stdout);
+            } else {
+                printf("%lld", value);
+            }
+            p = ziplistNext(p);
+            printf("\n");
         }
         printf("\n");
     }
@@ -462,8 +492,8 @@ int main(int argc, char **argv) {
     printf("Iterate starting out of range:\n");
     {
         zl = createList();
-        p = ziplistIndex(zl, 3);
-        if (ziplistNext(p, &entry, NULL, &elen) == NULL) {
+        p = ziplistIndex(zl, 4);
+        if (!ziplistGet(p, &entry, &elen, &value)) {
             printf("No entry\n");
         } else {
             printf("ERROR\n");
@@ -510,15 +540,19 @@ int main(int argc, char **argv) {
     {
         zl = createList();
         p = ziplistIndex(zl, 0);
-        while ((p = ziplistNext(p, &q, &entry, &elen)) != NULL) {
-            if (strncmp("foo", entry, elen) == 0) {
+        while (ziplistGet(p, &entry, &elen, &value)) {
+            if (entry && strncmp("foo", entry, elen) == 0) {
                 printf("Delete foo\n");
-                zl = ziplistDelete(zl, &q);
-                p = q;
+                zl = ziplistDelete(zl, &p);
             } else {
                 printf("Entry: ");
-                fwrite(entry,elen,1,stdout);
-                printf(" (length %d)\n", elen);
+                if (entry) {
+                    fwrite(entry,elen,1,stdout);
+                } else {
+                    printf("%lld", value);
+                }
+                p = ziplistNext(p);
+                printf("\n");
             }
         }
         printf("\n");