From 0f3dfa87bc8870c1da6867b7e2d9d70f7e21fc93 Mon Sep 17 00:00:00 2001 From: Pieter Noordhuis Date: Sun, 30 May 2010 01:39:41 +0200 Subject: [PATCH] change delete function to accept a direction argument, so "p" can be properly updated --- ziplist.c | 48 ++++++++++++++++++++++++++++++++++++++++++++---- ziplist.h | 2 +- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/ziplist.c b/ziplist.c index 4bc4f75c..71d965a8 100644 --- a/ziplist.c +++ b/ziplist.c @@ -469,13 +469,19 @@ unsigned char *ziplistInsert(unsigned char *zl, unsigned char *p, char *s, unsig /* Delete a single entry from the ziplist, pointed to by *p. * Also update *p in place, to be able to iterate over the * ziplist, while deleting entries. */ -unsigned char *ziplistDelete(unsigned char *zl, unsigned char **p) { +unsigned char *ziplistDelete(unsigned char *zl, unsigned char **p, int direction) { unsigned int offset = *p-zl; zl = __ziplistDelete(zl,*p,1); /* Store pointer to current element in p, because ziplistDelete will - * do a realloc which might result in a different "zl"-pointer. */ - *p = zl+offset; + * do a realloc which might result in a different "zl"-pointer. + * When the delete direction is back to front, we might delete the last + * entry and end up with "p" pointing to ZIP_END, so check this. */ + if (*(zl+offset) == ZIP_END && direction == ZIPLIST_HEAD) { + *p = ZIPLIST_ENTRY_TAIL(zl); + } else { + *p = zl+offset; + } return zl; } @@ -755,6 +761,40 @@ int main(int argc, char **argv) { printf("\n"); } + printf("Iterate from back to front:\n"); + { + zl = createList(); + p = ziplistIndex(zl, -1); + while (ziplistGet(p, &entry, &elen, &value)) { + printf("Entry: "); + if (entry) { + fwrite(entry,elen,1,stdout); + } else { + printf("%lld", value); + } + p = ziplistPrev(p); + printf("\n"); + } + printf("\n"); + } + + printf("Iterate from back to front, deleting all items:\n"); + { + zl = createList(); + p = ziplistIndex(zl, -1); + while (ziplistGet(p, &entry, &elen, &value)) { + printf("Entry: "); + if (entry) { + fwrite(entry,elen,1,stdout); + } else { + printf("%lld", value); + } + zl = ziplistDelete(zl, &p, ZIPLIST_HEAD); + printf("\n"); + } + printf("\n"); + } + printf("Delete inclusive range 0,0:\n"); { zl = createList(); @@ -797,7 +837,7 @@ int main(int argc, char **argv) { while (ziplistGet(p, &entry, &elen, &value)) { if (entry && strncmp("foo", entry, elen) == 0) { printf("Delete foo\n"); - zl = ziplistDelete(zl, &p); + zl = ziplistDelete(zl, &p, ZIPLIST_TAIL); } else { printf("Entry: "); if (entry) { diff --git a/ziplist.h b/ziplist.h index 8d37a8f5..08035dd5 100644 --- a/ziplist.h +++ b/ziplist.h @@ -8,8 +8,8 @@ unsigned char *ziplistIndex(unsigned char *zl, int index); unsigned char *ziplistNext(unsigned char *p); unsigned char *ziplistPrev(unsigned char *p); unsigned int ziplistGet(unsigned char *p, char **sstr, unsigned int *slen, long long *sval); -unsigned char *ziplistDelete(unsigned char *zl, unsigned char **p); 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); unsigned char *ziplistDeleteRange(unsigned char *zl, unsigned int index, unsigned int num); unsigned int ziplistCompare(unsigned char *p, char *entry, unsigned int elen); unsigned int ziplistLen(unsigned char *zl); -- GitLab