zipmaps functions to get, iterate, test for existence. Initial works for Hash data type
This commit is contained in:
parent
b1ad58ed2f
commit
5234952bee
5
Makefile
5
Makefile
@ -14,7 +14,7 @@ endif
|
|||||||
CCOPT= $(CFLAGS) $(CCLINK) $(ARCH) $(PROF)
|
CCOPT= $(CFLAGS) $(CCLINK) $(ARCH) $(PROF)
|
||||||
DEBUG?= -g -rdynamic -ggdb
|
DEBUG?= -g -rdynamic -ggdb
|
||||||
|
|
||||||
OBJ = adlist.o ae.o anet.o dict.o redis.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o
|
OBJ = adlist.o ae.o anet.o dict.o redis.o sds.o zmalloc.o lzf_c.o lzf_d.o pqsort.o zipmap.o
|
||||||
BENCHOBJ = ae.o anet.o redis-benchmark.o sds.o adlist.o zmalloc.o
|
BENCHOBJ = ae.o anet.o redis-benchmark.o sds.o adlist.o zmalloc.o
|
||||||
CLIOBJ = anet.o sds.o adlist.o redis-cli.o zmalloc.o
|
CLIOBJ = anet.o sds.o adlist.o redis-cli.o zmalloc.o
|
||||||
|
|
||||||
@ -39,8 +39,9 @@ redis-benchmark.o: redis-benchmark.c fmacros.h ae.h anet.h sds.h adlist.h \
|
|||||||
zmalloc.h
|
zmalloc.h
|
||||||
redis-cli.o: redis-cli.c fmacros.h anet.h sds.h adlist.h zmalloc.h
|
redis-cli.o: redis-cli.c fmacros.h anet.h sds.h adlist.h zmalloc.h
|
||||||
redis.o: redis.c fmacros.h config.h redis.h ae.h sds.h anet.h dict.h \
|
redis.o: redis.c fmacros.h config.h redis.h ae.h sds.h anet.h dict.h \
|
||||||
adlist.h zmalloc.h lzf.h pqsort.h staticsymbols.h
|
adlist.h zmalloc.h lzf.h pqsort.h zipmap.h staticsymbols.h
|
||||||
sds.o: sds.c sds.h zmalloc.h
|
sds.o: sds.c sds.h zmalloc.h
|
||||||
|
zipmap.o: zipmap.c zmalloc.h
|
||||||
zmalloc.o: zmalloc.c config.h
|
zmalloc.o: zmalloc.c config.h
|
||||||
|
|
||||||
redis-server: $(OBJ)
|
redis-server: $(OBJ)
|
||||||
|
31
redis.c
31
redis.c
@ -75,6 +75,7 @@
|
|||||||
#include "zmalloc.h" /* total memory usage aware version of malloc/free */
|
#include "zmalloc.h" /* total memory usage aware version of malloc/free */
|
||||||
#include "lzf.h" /* LZF compression library */
|
#include "lzf.h" /* LZF compression library */
|
||||||
#include "pqsort.h" /* Partial qsort for SORT+LIMIT */
|
#include "pqsort.h" /* Partial qsort for SORT+LIMIT */
|
||||||
|
#include "zipmap.h"
|
||||||
|
|
||||||
/* Error codes */
|
/* Error codes */
|
||||||
#define REDIS_OK 0
|
#define REDIS_OK 0
|
||||||
@ -118,9 +119,13 @@
|
|||||||
#define REDIS_ZSET 3
|
#define REDIS_ZSET 3
|
||||||
#define REDIS_HASH 4
|
#define REDIS_HASH 4
|
||||||
|
|
||||||
/* Objects encoding */
|
/* Objects encoding. Some kind of objects like Strings and Hashes can be
|
||||||
|
* internally represented in multiple ways. The 'encoding' field of the object
|
||||||
|
* is set to one of this fields for this object. */
|
||||||
#define REDIS_ENCODING_RAW 0 /* Raw representation */
|
#define REDIS_ENCODING_RAW 0 /* Raw representation */
|
||||||
#define REDIS_ENCODING_INT 1 /* Encoded as integer */
|
#define REDIS_ENCODING_INT 1 /* Encoded as integer */
|
||||||
|
#define REDIS_ENCODING_ZIPMAP 2 /* Encoded as zipmap */
|
||||||
|
#define REDIS_ENCODING_HT 3 /* Encoded as an hash table */
|
||||||
|
|
||||||
/* Object types only used for dumping to disk */
|
/* Object types only used for dumping to disk */
|
||||||
#define REDIS_EXPIRETIME 253
|
#define REDIS_EXPIRETIME 253
|
||||||
@ -1011,7 +1016,7 @@ static dictType zsetDictType = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Db->dict */
|
/* Db->dict */
|
||||||
static dictType hashDictType = {
|
static dictType dbDictType = {
|
||||||
dictObjHash, /* hash function */
|
dictObjHash, /* hash function */
|
||||||
NULL, /* key dup */
|
NULL, /* key dup */
|
||||||
NULL, /* val dup */
|
NULL, /* val dup */
|
||||||
@ -1030,6 +1035,16 @@ static dictType keyptrDictType = {
|
|||||||
NULL /* val destructor */
|
NULL /* val destructor */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Hash type hash table (note that small hashes are represented with zimpaps) */
|
||||||
|
static dictType hashDictType = {
|
||||||
|
dictEncObjHash, /* hash function */
|
||||||
|
NULL, /* key dup */
|
||||||
|
NULL, /* val dup */
|
||||||
|
dictEncObjKeyCompare, /* key compare */
|
||||||
|
dictRedisObjectDestructor, /* key destructor */
|
||||||
|
dictRedisObjectDestructor /* val destructor */
|
||||||
|
};
|
||||||
|
|
||||||
/* Keylist hash table type has unencoded redis objects as keys and
|
/* Keylist hash table type has unencoded redis objects as keys and
|
||||||
* lists as values. It's used for blocking operations (BLPOP) and to
|
* lists as values. It's used for blocking operations (BLPOP) and to
|
||||||
* map swapped keys to a list of clients waiting for this keys to be loaded. */
|
* map swapped keys to a list of clients waiting for this keys to be loaded. */
|
||||||
@ -1493,7 +1508,7 @@ static void initServer() {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
for (j = 0; j < server.dbnum; j++) {
|
for (j = 0; j < server.dbnum; j++) {
|
||||||
server.db[j].dict = dictCreate(&hashDictType,NULL);
|
server.db[j].dict = dictCreate(&dbDictType,NULL);
|
||||||
server.db[j].expires = dictCreate(&keyptrDictType,NULL);
|
server.db[j].expires = dictCreate(&keyptrDictType,NULL);
|
||||||
server.db[j].blockingkeys = dictCreate(&keylistDictType,NULL);
|
server.db[j].blockingkeys = dictCreate(&keylistDictType,NULL);
|
||||||
if (server.vm_enabled)
|
if (server.vm_enabled)
|
||||||
@ -2543,6 +2558,16 @@ static robj *createSetObject(void) {
|
|||||||
return createObject(REDIS_SET,d);
|
return createObject(REDIS_SET,d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static robj *createHashObject(void) {
|
||||||
|
/* All the Hashes start as zipmaps. Will be automatically converted
|
||||||
|
* into hash tables if there are enough elements or big elements
|
||||||
|
* inside. */
|
||||||
|
unsigned char *zm = zipmapNew();
|
||||||
|
robj *o = createObject(REDIS_HASH,zm);
|
||||||
|
o->encoding = REDIS_ENCODING_ZIPMAP;
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
static robj *createZsetObject(void) {
|
static robj *createZsetObject(void) {
|
||||||
zset *zs = zmalloc(sizeof(*zs));
|
zset *zs = zmalloc(sizeof(*zs));
|
||||||
|
|
||||||
|
78
zipmap.c
78
zipmap.c
@ -97,6 +97,11 @@
|
|||||||
* comments above, that is, the max number of trailing bytes in a value. */
|
* comments above, that is, the max number of trailing bytes in a value. */
|
||||||
#define ZIPMAP_VALUE_MAX_FREE 5
|
#define ZIPMAP_VALUE_MAX_FREE 5
|
||||||
|
|
||||||
|
/* The following macro returns the number of bytes needed to encode the length
|
||||||
|
* for the integer value _l, that is, 1 byte for lengths < ZIPMAP_BIGLEN and
|
||||||
|
* 5 bytes for all the other lengths. */
|
||||||
|
#define ZIPMAP_LEN_BYTES(_l) (((_l) < ZIPMAP_BIGLEN) ? 1 : sizeof(unsigned int)+1)
|
||||||
|
|
||||||
/* Create a new empty zipmap. */
|
/* Create a new empty zipmap. */
|
||||||
unsigned char *zipmapNew(void) {
|
unsigned char *zipmapNew(void) {
|
||||||
unsigned char *zm = zmalloc(2);
|
unsigned char *zm = zmalloc(2);
|
||||||
@ -119,7 +124,7 @@ static unsigned int zipmapDecodeLength(unsigned char *p) {
|
|||||||
* the amount of bytes required to encode such a length. */
|
* the amount of bytes required to encode such a length. */
|
||||||
static unsigned int zipmapEncodeLength(unsigned char *p, unsigned int len) {
|
static unsigned int zipmapEncodeLength(unsigned char *p, unsigned int len) {
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
return (len < ZIPMAP_BIGLEN) ? 1 : 1+sizeof(unsigned int);
|
return ZIPMAP_LEN_BYTES(len);
|
||||||
} else {
|
} else {
|
||||||
if (len < ZIPMAP_BIGLEN) {
|
if (len < ZIPMAP_BIGLEN) {
|
||||||
p[0] = len;
|
p[0] = len;
|
||||||
@ -219,23 +224,24 @@ static unsigned int zipmapRawEntryLength(unsigned char *p) {
|
|||||||
return l + zipmapRawValueLength(p+l);
|
return l + zipmapRawValueLength(p+l);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set key to value, creating the key if it does not already exist. */
|
/* Set key to value, creating the key if it does not already exist.
|
||||||
unsigned char *zipmapSet(unsigned char *zm, unsigned char *key, unsigned int klen, unsigned char *val, unsigned int vlen) {
|
* If 'update' is not NULL, *update is set to 1 if the key was
|
||||||
|
* already preset, otherwise to 0. */
|
||||||
|
unsigned char *zipmapSet(unsigned char *zm, unsigned char *key, unsigned int klen, unsigned char *val, unsigned int vlen, int *update) {
|
||||||
unsigned int oldlen = 0, freeoff = 0, freelen;
|
unsigned int oldlen = 0, freeoff = 0, freelen;
|
||||||
unsigned int reqlen = zipmapRequiredLength(klen,vlen);
|
unsigned int reqlen = zipmapRequiredLength(klen,vlen);
|
||||||
unsigned int empty, vempty;
|
unsigned int empty, vempty;
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
|
|
||||||
freelen = reqlen;
|
freelen = reqlen;
|
||||||
|
if (update) *update = 0;
|
||||||
p = zipmapLookupRaw(zm,key,klen,&oldlen,&freeoff,&freelen);
|
p = zipmapLookupRaw(zm,key,klen,&oldlen,&freeoff,&freelen);
|
||||||
if (p == NULL && freelen == 0) {
|
if (p == NULL && freelen == 0) {
|
||||||
printf("HERE oldlen:%u required:%u\n",oldlen,reqlen);
|
|
||||||
/* Key not found, and not space for the new key. Enlarge */
|
/* Key not found, and not space for the new key. Enlarge */
|
||||||
zm = zrealloc(zm,oldlen+reqlen);
|
zm = zrealloc(zm,oldlen+reqlen);
|
||||||
p = zm+oldlen-1;
|
p = zm+oldlen-1;
|
||||||
zm[oldlen+reqlen-1] = ZIPMAP_END;
|
zm[oldlen+reqlen-1] = ZIPMAP_END;
|
||||||
freelen = reqlen;
|
freelen = reqlen;
|
||||||
printf("New total length is: %u\n", oldlen+reqlen);
|
|
||||||
} else if (p == NULL) {
|
} else if (p == NULL) {
|
||||||
/* Key not found, but there is enough free space. */
|
/* Key not found, but there is enough free space. */
|
||||||
p = zm+freeoff;
|
p = zm+freeoff;
|
||||||
@ -245,6 +251,7 @@ unsigned char *zipmapSet(unsigned char *zm, unsigned char *key, unsigned int kle
|
|||||||
|
|
||||||
/* Key found. Is there enough space for the new value? */
|
/* Key found. Is there enough space for the new value? */
|
||||||
/* Compute the total length: */
|
/* Compute the total length: */
|
||||||
|
if (update) *update = 1;
|
||||||
freelen = zipmapRawKeyLength(b);
|
freelen = zipmapRawKeyLength(b);
|
||||||
b += freelen;
|
b += freelen;
|
||||||
freelen += zipmapRawValueLength(b);
|
freelen += zipmapRawValueLength(b);
|
||||||
@ -253,7 +260,7 @@ unsigned char *zipmapSet(unsigned char *zm, unsigned char *key, unsigned int kle
|
|||||||
p[0] = ZIPMAP_EMPTY;
|
p[0] = ZIPMAP_EMPTY;
|
||||||
zipmapEncodeLength(p+1,freelen);
|
zipmapEncodeLength(p+1,freelen);
|
||||||
zm[0] |= ZIPMAP_STATUS_FRAGMENTED;
|
zm[0] |= ZIPMAP_STATUS_FRAGMENTED;
|
||||||
return zipmapSet(zm,key,klen,val,vlen);
|
return zipmapSet(zm,key,klen,val,vlen,NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,37 +311,58 @@ unsigned char *zipmapDel(unsigned char *zm, unsigned char *key, unsigned int kle
|
|||||||
return zm;
|
return zm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Call it before to iterate trought elements via zipmapNext() */
|
||||||
|
unsigned char *zipmapRewind(unsigned char *zm) {
|
||||||
|
return zm+1;
|
||||||
|
}
|
||||||
|
|
||||||
/* This function is used to iterate through all the zipmap elements.
|
/* This function is used to iterate through all the zipmap elements.
|
||||||
* In the first call the first argument is the pointer to the zipmap + 1.
|
* In the first call the first argument is the pointer to the zipmap + 1.
|
||||||
* In the next calls what zipmapNext returns is used as first argument.
|
* In the next calls what zipmapNext returns is used as first argument.
|
||||||
* Example:
|
* Example:
|
||||||
*
|
*
|
||||||
* unsigned char *i = my_zipmap+1;
|
* unsigned char *i = zipmapRewind(my_zipmap);
|
||||||
* while((i = zipmapNext(i,&key,&klen,&value,&vlen)) != NULL) {
|
* while((i = zipmapNext(i,&key,&klen,&value,&vlen)) != NULL) {
|
||||||
* printf("%d bytes key at $p\n", klen, key);
|
* printf("%d bytes key at $p\n", klen, key);
|
||||||
* printf("%d bytes value at $p\n", vlen, value);
|
* printf("%d bytes value at $p\n", vlen, value);
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
unsigned char *zipmapNext(unsigned char *zm, unsigned char **key,
|
unsigned char *zipmapNext(unsigned char *zm, unsigned char **key, unsigned int *klen, unsigned char **value, unsigned int *vlen) {
|
||||||
unsigned int *klen, unsigned char **value, unsigned int *vlen) {
|
|
||||||
while(zm[0] == ZIPMAP_EMPTY)
|
while(zm[0] == ZIPMAP_EMPTY)
|
||||||
zm += zipmapDecodeLength(zm+1);
|
zm += zipmapDecodeLength(zm+1);
|
||||||
if (zm[0] == ZIPMAP_END) return NULL;
|
if (zm[0] == ZIPMAP_END) return NULL;
|
||||||
if (key) {
|
if (key) {
|
||||||
*key = zm;
|
*key = zm;
|
||||||
*klen = zipmapDecodeLength(zm);
|
*klen = zipmapDecodeLength(zm);
|
||||||
*key += (*klen < ZIPMAP_BIGLEN) ? 1 : sizeof(unsigned int);
|
*key += ZIPMAP_LEN_BYTES(*klen);
|
||||||
}
|
}
|
||||||
zm += zipmapRawKeyLength(zm);
|
zm += zipmapRawKeyLength(zm);
|
||||||
if (value) {
|
if (value) {
|
||||||
*value = zm+1;
|
*value = zm+1;
|
||||||
*vlen = zipmapDecodeLength(zm);
|
*vlen = zipmapDecodeLength(zm);
|
||||||
*value += (*vlen < ZIPMAP_BIGLEN) ? 1 : sizeof(unsigned int);
|
*value += ZIPMAP_LEN_BYTES(*vlen);
|
||||||
}
|
}
|
||||||
zm += zipmapRawValueLength(zm);
|
zm += zipmapRawValueLength(zm);
|
||||||
return zm;
|
return zm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Search a key and retrieve the pointer and len of the associated value.
|
||||||
|
* If the key is found the function returns 1, otherwise 0. */
|
||||||
|
int zipmapGet(unsigned char *zm, unsigned char *key, unsigned int klen, unsigned char **value, unsigned int *vlen) {
|
||||||
|
unsigned char *p;
|
||||||
|
|
||||||
|
if ((p = zipmapLookupRaw(zm,key,klen,NULL,NULL,NULL)) == NULL) return 0;
|
||||||
|
p += zipmapRawKeyLength(p);
|
||||||
|
*vlen = zipmapDecodeLength(p);
|
||||||
|
*value = p + ZIPMAP_LEN_BYTES(*vlen) + 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return 1 if the key exists, otherwise 0 is returned. */
|
||||||
|
int zipmapExists(unsigned char *zm, unsigned char *key, unsigned int klen) {
|
||||||
|
return zipmapLookupRaw(zm,key,klen,NULL,NULL,NULL) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void zipmapRepr(unsigned char *p) {
|
void zipmapRepr(unsigned char *p) {
|
||||||
unsigned int l;
|
unsigned int l;
|
||||||
|
|
||||||
@ -372,29 +400,41 @@ void zipmapRepr(unsigned char *p) {
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ZIPMAP_TEST_MAIN
|
||||||
int main(void) {
|
int main(void) {
|
||||||
unsigned char *zm;
|
unsigned char *zm;
|
||||||
|
|
||||||
zm = zipmapNew();
|
zm = zipmapNew();
|
||||||
zm = zipmapSet(zm,(unsigned char*) "hello",5, (unsigned char*) "world!",6);
|
zm = zipmapSet(zm,(unsigned char*) "hello",5, (unsigned char*) "world!",6,NULL);
|
||||||
zm = zipmapSet(zm,(unsigned char*) "foo",3, (unsigned char*) "bar",3);
|
zm = zipmapSet(zm,(unsigned char*) "foo",3, (unsigned char*) "bar",3,NULL);
|
||||||
zm = zipmapSet(zm,(unsigned char*) "foo",3, (unsigned char*) "!",1);
|
zm = zipmapSet(zm,(unsigned char*) "foo",3, (unsigned char*) "!",1,NULL);
|
||||||
zipmapRepr(zm);
|
zipmapRepr(zm);
|
||||||
zm = zipmapSet(zm,(unsigned char*) "foo",3, (unsigned char*) "12345",5);
|
zm = zipmapSet(zm,(unsigned char*) "foo",3, (unsigned char*) "12345",5,NULL);
|
||||||
zipmapRepr(zm);
|
zipmapRepr(zm);
|
||||||
zm = zipmapSet(zm,(unsigned char*) "new",3, (unsigned char*) "xx",2);
|
zm = zipmapSet(zm,(unsigned char*) "new",3, (unsigned char*) "xx",2,NULL);
|
||||||
zipmapRepr(zm);
|
zipmapRepr(zm);
|
||||||
zm = zipmapDel(zm,(unsigned char*) "new",3,NULL);
|
zm = zipmapDel(zm,(unsigned char*) "new",3,NULL);
|
||||||
zipmapRepr(zm);
|
zipmapRepr(zm);
|
||||||
printf("Iterate trought elements:\n");
|
printf("\nPerform a direct lookup:\n");
|
||||||
{
|
{
|
||||||
unsigned char *i = zm+1;
|
unsigned char *value;
|
||||||
|
unsigned int vlen;
|
||||||
|
|
||||||
|
if (zipmapGet(zm,(unsigned char*) "foo",3,&value,&vlen)) {
|
||||||
|
printf(" foo is associated to the %d bytes value: %.*s\n",
|
||||||
|
vlen, vlen, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\nIterate trought elements:\n");
|
||||||
|
{
|
||||||
|
unsigned char *i = zipmapRewind(zm);
|
||||||
unsigned char *key, *value;
|
unsigned char *key, *value;
|
||||||
unsigned int klen, vlen;
|
unsigned int klen, vlen;
|
||||||
|
|
||||||
while((i = zipmapNext(i,&key,&klen,&value,&vlen)) != NULL) {
|
while((i = zipmapNext(i,&key,&klen,&value,&vlen)) != NULL) {
|
||||||
printf("%d:%.*s => %d:%.*s\n", klen, klen, key, vlen, vlen, value);
|
printf(" %d:%.*s => %d:%.*s\n", klen, klen, key, vlen, vlen, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
46
zipmap.h
Normal file
46
zipmap.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/* String -> String Map data structure optimized for size.
|
||||||
|
*
|
||||||
|
* See zipmap.c for more info.
|
||||||
|
*
|
||||||
|
* --------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009-2010, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of Redis nor the names of its contributors may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ZIMMAP_H
|
||||||
|
#define _ZIPMAP_H
|
||||||
|
|
||||||
|
unsigned char *zipmapNew(void);
|
||||||
|
unsigned char *zipmapSet(unsigned char *zm, unsigned char *key, unsigned int klen, unsigned char *val, unsigned int vlen, int *update);
|
||||||
|
unsigned char *zipmapDel(unsigned char *zm, unsigned char *key, unsigned int klen, int *deleted);
|
||||||
|
unsigned char *zipmapRewind(unsigned char *zm);
|
||||||
|
unsigned char *zipmapNext(unsigned char *zm, unsigned char **key, unsigned int *klen, unsigned char **value, unsigned int *vlen);
|
||||||
|
int zipmapGet(unsigned char *zm, unsigned char *key, unsigned int klen, unsigned char **value, unsigned int *vlen);
|
||||||
|
int zipmapExists(unsigned char *zm, unsigned char *key, unsigned int klen);
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user