use integer types from stdint.h to be more verbose on the size in bytes of encoded elements. update list length to use 2 bytes instead of 1.

This commit is contained in:
Pieter Noordhuis 2010-06-01 18:55:37 +02:00
parent ffc1585267
commit e1f93d4b2c

View File

@ -17,6 +17,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdint.h>
#include <assert.h> #include <assert.h>
#include <limits.h> #include <limits.h>
#include "zmalloc.h" #include "zmalloc.h"
@ -33,9 +34,9 @@
/* Entry encoding */ /* Entry encoding */
#define ZIP_ENC_RAW 0 #define ZIP_ENC_RAW 0
#define ZIP_ENC_SHORT 1 #define ZIP_ENC_INT16 1
#define ZIP_ENC_INT 2 #define ZIP_ENC_INT32 2
#define ZIP_ENC_LLONG 3 #define ZIP_ENC_INT64 3
#define ZIP_ENCODING(p) ((p)[0] >> 6) #define ZIP_ENCODING(p) ((p)[0] >> 6)
/* Length encoding for raw entries */ /* Length encoding for raw entries */
@ -44,15 +45,18 @@
#define ZIP_LEN_UINT32 2 #define ZIP_LEN_UINT32 2
/* Utility macros */ /* Utility macros */
#define ZIPLIST_BYTES(zl) (*((unsigned int*)(zl))) #define ZIPLIST_BYTES(zl) (*((uint32_t*)(zl)))
#define ZIPLIST_TAIL_OFFSET(zl) (*((unsigned int*)((zl)+sizeof(unsigned int)))) #define ZIPLIST_TAIL_OFFSET(zl) (*((uint32_t*)((zl)+sizeof(uint32_t))))
#define ZIPLIST_LENGTH(zl) (*((zl)+2*sizeof(unsigned int))) #define ZIPLIST_LENGTH(zl) (*((uint16_t*)((zl)+sizeof(uint32_t)*2)))
#define ZIPLIST_HEADER_SIZE (2*sizeof(unsigned int)+1) #define ZIPLIST_HEADER_SIZE (sizeof(uint32_t)*2+sizeof(uint16_t))
#define ZIPLIST_ENTRY_HEAD(zl) ((zl)+ZIPLIST_HEADER_SIZE) #define ZIPLIST_ENTRY_HEAD(zl) ((zl)+ZIPLIST_HEADER_SIZE)
#define ZIPLIST_ENTRY_TAIL(zl) ((zl)+ZIPLIST_TAIL_OFFSET(zl)) #define ZIPLIST_ENTRY_TAIL(zl) ((zl)+ZIPLIST_TAIL_OFFSET(zl))
#define ZIPLIST_ENTRY_END(zl) ((zl)+ZIPLIST_BYTES(zl)-1) #define ZIPLIST_ENTRY_END(zl) ((zl)+ZIPLIST_BYTES(zl)-1)
/* 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) { \ #define ZIPLIST_INCR_LENGTH(zl,incr) { \
if (ZIPLIST_LENGTH(zl) < ZIP_BIGLEN) ZIPLIST_LENGTH(zl)+=incr; } if (ZIPLIST_LENGTH(zl) < UINT16_MAX) ZIPLIST_LENGTH(zl)+=incr; }
typedef struct zlentry { typedef struct zlentry {
unsigned int prevrawlensize, prevrawlen; unsigned int prevrawlensize, prevrawlen;
@ -64,12 +68,12 @@ typedef struct zlentry {
/* Return bytes needed to store integer encoded by 'encoding' */ /* Return bytes needed to store integer encoded by 'encoding' */
static unsigned int zipEncodingSize(unsigned char encoding) { static unsigned int zipEncodingSize(unsigned char encoding) {
if (encoding == ZIP_ENC_SHORT) { if (encoding == ZIP_ENC_INT16) {
return sizeof(short int); return sizeof(int16_t);
} else if (encoding == ZIP_ENC_INT) { } else if (encoding == ZIP_ENC_INT32) {
return sizeof(int); return sizeof(int32_t);
} else if (encoding == ZIP_ENC_LLONG) { } else if (encoding == ZIP_ENC_INT64) {
return sizeof(long long); return sizeof(int64_t);
} }
assert(NULL); assert(NULL);
} }
@ -180,12 +184,12 @@ static int zipTryEncoding(unsigned char *entry, long long *v, unsigned char *enc
if (entry[0] == '-' || (entry[0] >= '0' && entry[0] <= '9')) { if (entry[0] == '-' || (entry[0] >= '0' && entry[0] <= '9')) {
value = strtoll((char*)entry,&eptr,10); value = strtoll((char*)entry,&eptr,10);
if (eptr[0] != '\0') return 0; if (eptr[0] != '\0') return 0;
if (value >= SHRT_MIN && value <= SHRT_MAX) { if (value >= INT16_MIN && value <= INT16_MAX) {
*encoding = ZIP_ENC_SHORT; *encoding = ZIP_ENC_INT16;
} else if (value >= INT_MIN && value <= INT_MAX) { } else if (value >= INT32_MIN && value <= INT32_MAX) {
*encoding = ZIP_ENC_INT; *encoding = ZIP_ENC_INT32;
} else { } else {
*encoding = ZIP_ENC_LLONG; *encoding = ZIP_ENC_INT64;
} }
*v = value; *v = value;
return 1; return 1;
@ -194,38 +198,38 @@ static int zipTryEncoding(unsigned char *entry, long long *v, unsigned char *enc
} }
/* Store integer 'value' at 'p', encoded as 'encoding' */ /* Store integer 'value' at 'p', encoded as 'encoding' */
static void zipSaveInteger(unsigned char *p, long long value, unsigned char encoding) { static void zipSaveInteger(unsigned char *p, int64_t value, unsigned char encoding) {
short int s; int16_t i16;
int i; int32_t i32;
long long l; int64_t i64;
if (encoding == ZIP_ENC_SHORT) { if (encoding == ZIP_ENC_INT16) {
s = value; i16 = value;
memcpy(p,&s,sizeof(s)); memcpy(p,&i16,sizeof(i16));
} else if (encoding == ZIP_ENC_INT) { } else if (encoding == ZIP_ENC_INT32) {
i = value; i32 = value;
memcpy(p,&i,sizeof(i)); memcpy(p,&i32,sizeof(i32));
} else if (encoding == ZIP_ENC_LLONG) { } else if (encoding == ZIP_ENC_INT64) {
l = value; i64 = value;
memcpy(p,&l,sizeof(l)); memcpy(p,&i64,sizeof(i64));
} else { } else {
assert(NULL); assert(NULL);
} }
} }
/* Read integer encoded as 'encoding' from 'p' */ /* Read integer encoded as 'encoding' from 'p' */
static long long zipLoadInteger(unsigned char *p, unsigned char encoding) { static int64_t zipLoadInteger(unsigned char *p, unsigned char encoding) {
short int s; int16_t i16;
int i; int32_t i32;
long long l, ret; int64_t i64, ret;
if (encoding == ZIP_ENC_SHORT) { if (encoding == ZIP_ENC_INT16) {
memcpy(&s,p,sizeof(s)); memcpy(&i16,p,sizeof(i16));
ret = s; ret = i16;
} else if (encoding == ZIP_ENC_INT) { } else if (encoding == ZIP_ENC_INT32) {
memcpy(&i,p,sizeof(i)); memcpy(&i32,p,sizeof(i32));
ret = i; ret = i32;
} else if (encoding == ZIP_ENC_LLONG) { } else if (encoding == ZIP_ENC_INT64) {
memcpy(&l,p,sizeof(l)); memcpy(&i64,p,sizeof(i64));
ret = l; ret = i64;
} else { } else {
assert(NULL); assert(NULL);
} }
@ -539,7 +543,7 @@ unsigned int ziplistCompare(unsigned char *p, unsigned char *sstr, unsigned int
/* Return length of ziplist. */ /* Return length of ziplist. */
unsigned int ziplistLen(unsigned char *zl) { unsigned int ziplistLen(unsigned char *zl) {
unsigned int len = 0; unsigned int len = 0;
if (ZIPLIST_LENGTH(zl) < ZIP_BIGLEN) { if (ZIPLIST_LENGTH(zl) < UINT16_MAX) {
len = ZIPLIST_LENGTH(zl); len = ZIPLIST_LENGTH(zl);
} else { } else {
unsigned char *p = zl+ZIPLIST_HEADER_SIZE; unsigned char *p = zl+ZIPLIST_HEADER_SIZE;
@ -549,7 +553,7 @@ unsigned int ziplistLen(unsigned char *zl) {
} }
/* Re-store length if small enough */ /* Re-store length if small enough */
if (len < ZIP_BIGLEN) ZIPLIST_LENGTH(zl) = len; if (len < UINT16_MAX) ZIPLIST_LENGTH(zl) = len;
} }
return len; return len;
} }