1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
|
unsigned char *zipmapSet(unsigned char *zm, unsigned char *key, unsigned int klen, unsigned char *val, unsigned int vlen, int *update) { unsigned int zmlen, offset; unsigned int freelen, reqlen = zipmapRequiredLength(klen,vlen); unsigned int empty, vempty; unsigned char *p;
freelen = reqlen; if (update) *update = 0; p = zipmapLookupRaw(zm,key,klen,&zmlen); if (p == NULL) { zm = zipmapResize(zm, zmlen+reqlen); p = zm+zmlen-1; zmlen = zmlen+reqlen;
if (zm[0] < ZIPMAP_BIGLEN) zm[0]++; } else { if (update) *update = 1; freelen = zipmapRawEntryLength(p); if (freelen < reqlen) {
offset = p-zm; zm = zipmapResize(zm, zmlen-freelen+reqlen); p = zm+offset;
memmove(p+reqlen, p+freelen, zmlen-(offset+freelen+1)); zmlen = zmlen-freelen+reqlen; freelen = reqlen; } }
empty = freelen-reqlen; if (empty >= ZIPMAP_VALUE_MAX_FREE) {
offset = p-zm; memmove(p+reqlen, p+freelen, zmlen-(offset+freelen+1)); zmlen -= empty; zm = zipmapResize(zm, zmlen); p = zm+offset; vempty = 0; } else { vempty = empty; }
p += zipmapEncodeLength(p,klen); memcpy(p,key,klen); p += klen; p += zipmapEncodeLength(p,vlen); *p++ = vempty; memcpy(p,val,vlen); return zm; }
|