change delete function to accept a direction argument, so "p" can be properly updated

This commit is contained in:
Pieter Noordhuis 2010-05-30 01:39:41 +02:00
parent 033fb554be
commit 0f3dfa87bc
2 changed files with 45 additions and 5 deletions

View File

@ -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. /* Delete a single entry from the ziplist, pointed to by *p.
* Also update *p in place, to be able to iterate over the * Also update *p in place, to be able to iterate over the
* ziplist, while deleting entries. */ * 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; unsigned int offset = *p-zl;
zl = __ziplistDelete(zl,*p,1); zl = __ziplistDelete(zl,*p,1);
/* Store pointer to current element in p, because ziplistDelete will /* Store pointer to current element in p, because ziplistDelete will
* do a realloc which might result in a different "zl"-pointer. */ * 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; *p = zl+offset;
}
return zl; return zl;
} }
@ -755,6 +761,40 @@ int main(int argc, char **argv) {
printf("\n"); 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"); printf("Delete inclusive range 0,0:\n");
{ {
zl = createList(); zl = createList();
@ -797,7 +837,7 @@ int main(int argc, char **argv) {
while (ziplistGet(p, &entry, &elen, &value)) { while (ziplistGet(p, &entry, &elen, &value)) {
if (entry && strncmp("foo", entry, elen) == 0) { if (entry && strncmp("foo", entry, elen) == 0) {
printf("Delete foo\n"); printf("Delete foo\n");
zl = ziplistDelete(zl, &p); zl = ziplistDelete(zl, &p, ZIPLIST_TAIL);
} else { } else {
printf("Entry: "); printf("Entry: ");
if (entry) { if (entry) {

View File

@ -8,8 +8,8 @@ unsigned char *ziplistIndex(unsigned char *zl, int index);
unsigned char *ziplistNext(unsigned char *p); unsigned char *ziplistNext(unsigned char *p);
unsigned char *ziplistPrev(unsigned char *p); unsigned char *ziplistPrev(unsigned char *p);
unsigned int ziplistGet(unsigned char *p, char **sstr, unsigned int *slen, long long *sval); 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 *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 char *ziplistDeleteRange(unsigned char *zl, unsigned int index, unsigned int num);
unsigned int ziplistCompare(unsigned char *p, char *entry, unsigned int elen); unsigned int ziplistCompare(unsigned char *p, char *entry, unsigned int elen);
unsigned int ziplistLen(unsigned char *zl); unsigned int ziplistLen(unsigned char *zl);