From 56538477143b144f2267ce98805a7b6edc763528 Mon Sep 17 00:00:00 2001 From: antirez Date: Wed, 8 Feb 2012 22:59:35 +0100 Subject: [PATCH] ziplist.c fixes for bigendian --- src/endian.c | 17 +++++++++++++++++ src/endian.h | 6 ++++++ src/ziplist.c | 52 +++++++++++++++++++++++++++------------------------ 3 files changed, 51 insertions(+), 24 deletions(-) diff --git a/src/endian.c b/src/endian.c index aff2425a..741f8bf2 100644 --- a/src/endian.c +++ b/src/endian.c @@ -1,3 +1,5 @@ +#include + /* Toggle the 16 bit unsigned integer pointed by *p from little endian to * big endian */ void memrev16(void *p) { @@ -40,6 +42,21 @@ void memrev64(void *p) { x[4] = t; } +uint16_t intrev16(uint16_t v) { + memrev16(&v); + return v; +} + +uint32_t intrev32(uint32_t v) { + memrev32(&v); + return v; +} + +uint64_t intrev64(uint64_t v) { + memrev64(&v); + return v; +} + #ifdef TESTMAIN #include diff --git a/src/endian.h b/src/endian.h index bef82272..03a5b094 100644 --- a/src/endian.h +++ b/src/endian.h @@ -11,10 +11,16 @@ void memrev64(void *p); #define memrev16ifbe(p) #define memrev32ifbe(p) #define memrev64ifbe(p) +#define intrev16ifbe(v) (v) +#define intrev32ifbe(v) (v) +#define intrev64ifbe(v) (v) #else #define memrev16ifbe(p) memrev16(p) #define memrev32ifbe(p) memrev32(p) #define memrev64ifbe(p) memrev64(p) +#define intrev16ifbe(v) intrev16(v) +#define intrev32ifbe(v) intrev32(v) +#define intrev64ifbe(v) intrev64(v) #endif #endif diff --git a/src/ziplist.c b/src/ziplist.c index 639e4b61..c8fd64ac 100644 --- a/src/ziplist.c +++ b/src/ziplist.c @@ -98,7 +98,9 @@ /* We know a positive increment can only be 1 because entries can only be * pushed one at a time. */ #define ZIPLIST_INCR_LENGTH(zl,incr) { \ - if (ZIPLIST_LENGTH(zl) < UINT16_MAX) ZIPLIST_LENGTH(zl)+=incr; } + if (ZIPLIST_LENGTH(zl) < UINT16_MAX) \ + ZIPLIST_LENGTH(zl) += intrev16ifbe(incr); \ +} typedef struct zlentry { unsigned int prevrawlensize, prevrawlen; @@ -335,8 +337,8 @@ static unsigned int zipRawEntryLength(unsigned char *p) { unsigned char *ziplistNew(void) { unsigned int bytes = ZIPLIST_HEADER_SIZE+1; unsigned char *zl = zmalloc(bytes); - ZIPLIST_BYTES(zl) = bytes; - ZIPLIST_TAIL_OFFSET(zl) = ZIPLIST_HEADER_SIZE; + ZIPLIST_BYTES(zl) = intrev32ifbe(bytes); + ZIPLIST_TAIL_OFFSET(zl) = intrev32ifbe(ZIPLIST_HEADER_SIZE); ZIPLIST_LENGTH(zl) = 0; zl[bytes-1] = ZIP_END; return zl; @@ -345,7 +347,7 @@ unsigned char *ziplistNew(void) { /* Resize the ziplist. */ static unsigned char *ziplistResize(unsigned char *zl, unsigned int len) { zl = zrealloc(zl,len); - ZIPLIST_BYTES(zl) = len; + ZIPLIST_BYTES(zl) = intrev32ifbe(len); zl[len-1] = ZIP_END; return zl; } @@ -371,7 +373,7 @@ static unsigned char *ziplistResize(unsigned char *zl, unsigned int len) { * The pointer "p" points to the first entry that does NOT need to be * updated, i.e. consecutive fields MAY need an update. */ static unsigned char *__ziplistCascadeUpdate(unsigned char *zl, unsigned char *p) { - size_t curlen = ZIPLIST_BYTES(zl), rawlen, rawlensize; + size_t curlen = intrev32ifbe(ZIPLIST_BYTES(zl)), rawlen, rawlensize; size_t offset, noffset, extra; unsigned char *np; zlentry cur, next; @@ -401,8 +403,8 @@ static unsigned char *__ziplistCascadeUpdate(unsigned char *zl, unsigned char *p noffset = np-zl; /* Update tail offset when next element is not the tail element. */ - if ((zl+ZIPLIST_TAIL_OFFSET(zl)) != np) - ZIPLIST_TAIL_OFFSET(zl) += extra; + if ((zl+intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl))) != np) + ZIPLIST_TAIL_OFFSET(zl) += intrev32ifbe(extra); /* Move the tail to the back. */ memmove(np+rawlensize, @@ -453,25 +455,27 @@ static unsigned char *__ziplistDelete(unsigned char *zl, unsigned char *p, unsig zipPrevEncodeLength(p-nextdiff,first.prevrawlen); /* Update offset for tail */ - ZIPLIST_TAIL_OFFSET(zl) -= totlen; + ZIPLIST_TAIL_OFFSET(zl) -= intrev32ifbe(totlen); /* When the tail contains more than one entry, we need to take * "nextdiff" in account as well. Otherwise, a change in the * size of prevlen doesn't have an effect on the *tail* offset. */ tail = zipEntry(p); if (p[tail.headersize+tail.len] != ZIP_END) - ZIPLIST_TAIL_OFFSET(zl) += nextdiff; + ZIPLIST_TAIL_OFFSET(zl) += intrev32ifbe(nextdiff); /* Move tail to the front of the ziplist */ - memmove(first.p,p-nextdiff,ZIPLIST_BYTES(zl)-(p-zl)-1+nextdiff); + memmove(first.p,p-nextdiff, + intrev32ifbe(ZIPLIST_BYTES(zl))-(p-zl)-1+nextdiff); } else { /* The entire tail was deleted. No need to move memory. */ - ZIPLIST_TAIL_OFFSET(zl) = (first.p-zl)-first.prevrawlen; + ZIPLIST_TAIL_OFFSET(zl) = + intrev32ifbe((first.p-zl)-first.prevrawlen); } /* Resize and update length */ offset = first.p-zl; - zl = ziplistResize(zl, ZIPLIST_BYTES(zl)-totlen+nextdiff); + zl = ziplistResize(zl, intrev32ifbe(ZIPLIST_BYTES(zl))-totlen+nextdiff); ZIPLIST_INCR_LENGTH(zl,-deleted); p = zl+offset; @@ -485,7 +489,7 @@ static unsigned char *__ziplistDelete(unsigned char *zl, unsigned char *p, unsig /* Insert item at "p". */ static unsigned char *__ziplistInsert(unsigned char *zl, unsigned char *p, unsigned char *s, unsigned int slen) { - size_t curlen = ZIPLIST_BYTES(zl), reqlen, prevlen = 0; + size_t curlen = intrev32ifbe(ZIPLIST_BYTES(zl)), reqlen, prevlen = 0; size_t offset; int nextdiff = 0; unsigned char encoding = 0; @@ -538,17 +542,17 @@ static unsigned char *__ziplistInsert(unsigned char *zl, unsigned char *p, unsig zipPrevEncodeLength(p+reqlen,reqlen); /* Update offset for tail */ - ZIPLIST_TAIL_OFFSET(zl) += reqlen; + ZIPLIST_TAIL_OFFSET(zl) += intrev32ifbe(reqlen); /* When the tail contains more than one entry, we need to take * "nextdiff" in account as well. Otherwise, a change in the * size of prevlen doesn't have an effect on the *tail* offset. */ tail = zipEntry(p+reqlen); if (p[reqlen+tail.headersize+tail.len] != ZIP_END) - ZIPLIST_TAIL_OFFSET(zl) += nextdiff; + ZIPLIST_TAIL_OFFSET(zl) += intrev32ifbe(nextdiff); } else { /* This element will be the new tail. */ - ZIPLIST_TAIL_OFFSET(zl) = p-zl; + ZIPLIST_TAIL_OFFSET(zl) = intrev32ifbe(p-zl); } /* When nextdiff != 0, the raw length of the next entry has changed, so @@ -720,8 +724,8 @@ unsigned int ziplistCompare(unsigned char *p, unsigned char *sstr, unsigned int /* Return length of ziplist. */ unsigned int ziplistLen(unsigned char *zl) { unsigned int len = 0; - if (ZIPLIST_LENGTH(zl) < UINT16_MAX) { - len = ZIPLIST_LENGTH(zl); + if (intrev16ifbe(ZIPLIST_LENGTH(zl)) < UINT16_MAX) { + len = intrev16ifbe(ZIPLIST_LENGTH(zl)); } else { unsigned char *p = zl+ZIPLIST_HEADER_SIZE; while (*p != ZIP_END) { @@ -730,14 +734,14 @@ unsigned int ziplistLen(unsigned char *zl) { } /* Re-store length if small enough */ - if (len < UINT16_MAX) ZIPLIST_LENGTH(zl) = len; + if (len < UINT16_MAX) ZIPLIST_LENGTH(zl) = intrev16ifbe(len); } return len; } /* Return ziplist blob size in bytes. */ size_t ziplistBlobLen(unsigned char *zl) { - return ZIPLIST_BYTES(zl); + return intrev32ifbe(ZIPLIST_BYTES(zl)); } void ziplistRepr(unsigned char *zl) { @@ -749,9 +753,9 @@ void ziplistRepr(unsigned char *zl) { "{total bytes %d} " "{length %u}\n" "{tail offset %u}\n", - ZIPLIST_BYTES(zl), - ZIPLIST_LENGTH(zl), - ZIPLIST_TAIL_OFFSET(zl)); + intrev32ifbe(ZIPLIST_BYTES(zl)), + intrev16ifbe(ZIPLIST_LENGTH(zl)), + intrev32ifbe(ZIPLIST_TAIL_OFFSET(zl))); p = ZIPLIST_ENTRY_HEAD(zl); while(*p != ZIP_END) { entry = zipEntry(p); @@ -852,7 +856,7 @@ void stress(int pos, int num, int maxsize, int dnum) { zl = ziplistDeleteRange(zl,0,1); } printf("List size: %8d, bytes: %8d, %dx push+pop (%s): %6lld usec\n", - i,ZIPLIST_BYTES(zl),num,posstr[pos],usec()-start); + i,intrev32ifbe(ZIPLIST_BYTES(zl)),num,posstr[pos],usec()-start); zfree(zl); } } -- GitLab