Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
3d04d29e
Commit
3d04d29e
authored
May 21, 2010
by
Pieter Noordhuis
Browse files
extracted general methods to zip.c for reuse in other zip* structures
parent
d55d5c5d
Changes
2
Show whitespace changes
Inline
Side-by-side
zip.c
0 → 100644
View file @
3d04d29e
#define ZIP_BIGLEN 254
#define ZIP_END 255
/* The following macro returns the number of bytes needed to encode the length
* for the integer value _l, that is, 1 byte for lengths < ZIP_BIGLEN and
* 5 bytes for all the other lengths. */
#define ZIP_LEN_BYTES(_l) (((_l) < ZIP_BIGLEN) ? 1 : sizeof(unsigned int)+1)
/* Decode the encoded length pointed by 'p' */
static
unsigned
int
zipDecodeLength
(
unsigned
char
*
p
)
{
unsigned
int
len
=
*
p
;
if
(
len
<
ZIP_BIGLEN
)
return
len
;
memcpy
(
&
len
,
p
+
1
,
sizeof
(
unsigned
int
));
return
len
;
}
/* Encode the length 'l' writing it in 'p'. If p is NULL it just returns
* the amount of bytes required to encode such a length. */
static
unsigned
int
zipEncodeLength
(
unsigned
char
*
p
,
unsigned
int
len
)
{
if
(
p
==
NULL
)
{
return
ZIP_LEN_BYTES
(
len
);
}
else
{
if
(
len
<
ZIP_BIGLEN
)
{
p
[
0
]
=
len
;
return
1
;
}
else
{
p
[
0
]
=
ZIP_BIGLEN
;
memcpy
(
p
+
1
,
&
len
,
sizeof
(
len
));
return
1
+
sizeof
(
len
);
}
}
}
/* Return the total amount used by an entry (encoded length + payload). */
static
unsigned
int
zipRawEntryLength
(
unsigned
char
*
p
)
{
unsigned
int
l
=
zipDecodeLength
(
p
);
return
zipEncodeLength
(
NULL
,
l
)
+
l
;
}
/* Resize the zip* structure. */
static
unsigned
char
*
zipResize
(
unsigned
char
*
z
,
unsigned
int
len
)
{
z
=
zrealloc
(
z
,
len
);
z
[
len
-
1
]
=
ZIP_END
;
return
z
;
}
zipmap.c
View file @
3d04d29e
...
@@ -80,54 +80,21 @@
...
@@ -80,54 +80,21 @@
#include <string.h>
#include <string.h>
#include <assert.h>
#include <assert.h>
#include "zmalloc.h"
#include "zmalloc.h"
#include "zip.c"
#define ZIPMAP_BIGLEN 254
#define ZIPMAP_END 255
/* The following defines the max value for the <free> field described in the
/* The following defines the max value for the <free> field described in the
* 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 4
#define ZIPMAP_VALUE_MAX_FREE 4
/* 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
);
zm
[
0
]
=
0
;
/* Length */
zm
[
0
]
=
0
;
/* Length */
zm
[
1
]
=
ZIP
MAP
_END
;
zm
[
1
]
=
ZIP_END
;
return
zm
;
return
zm
;
}
}
/* Decode the encoded length pointed by 'p' */
static
unsigned
int
zipmapDecodeLength
(
unsigned
char
*
p
)
{
unsigned
int
len
=
*
p
;
if
(
len
<
ZIPMAP_BIGLEN
)
return
len
;
memcpy
(
&
len
,
p
+
1
,
sizeof
(
unsigned
int
));
return
len
;
}
/* Encode the length 'l' writing it in 'p'. If p is NULL it just returns
* the amount of bytes required to encode such a length. */
static
unsigned
int
zipmapEncodeLength
(
unsigned
char
*
p
,
unsigned
int
len
)
{
if
(
p
==
NULL
)
{
return
ZIPMAP_LEN_BYTES
(
len
);
}
else
{
if
(
len
<
ZIPMAP_BIGLEN
)
{
p
[
0
]
=
len
;
return
1
;
}
else
{
p
[
0
]
=
ZIPMAP_BIGLEN
;
memcpy
(
p
+
1
,
&
len
,
sizeof
(
len
));
return
1
+
sizeof
(
len
);
}
}
}
/* Search for a matching key, returning a pointer to the entry inside the
/* Search for a matching key, returning a pointer to the entry inside the
* zipmap. Returns NULL if the key is not found.
* zipmap. Returns NULL if the key is not found.
*
*
...
@@ -138,12 +105,12 @@ static unsigned char *zipmapLookupRaw(unsigned char *zm, unsigned char *key, uns
...
@@ -138,12 +105,12 @@ static unsigned char *zipmapLookupRaw(unsigned char *zm, unsigned char *key, uns
unsigned
char
*
p
=
zm
+
1
,
*
k
=
NULL
;
unsigned
char
*
p
=
zm
+
1
,
*
k
=
NULL
;
unsigned
int
l
,
llen
;
unsigned
int
l
,
llen
;
while
(
*
p
!=
ZIP
MAP
_END
)
{
while
(
*
p
!=
ZIP_END
)
{
unsigned
char
free
;
unsigned
char
free
;
/* Match or skip the key */
/* Match or skip the key */
l
=
zip
map
DecodeLength
(
p
);
l
=
zipDecodeLength
(
p
);
llen
=
zip
map
EncodeLength
(
NULL
,
l
);
llen
=
zipEncodeLength
(
NULL
,
l
);
if
(
k
==
NULL
&&
l
==
klen
&&
!
memcmp
(
p
+
llen
,
key
,
l
))
{
if
(
k
==
NULL
&&
l
==
klen
&&
!
memcmp
(
p
+
llen
,
key
,
l
))
{
/* Only return when the user doesn't care
/* Only return when the user doesn't care
* for the total length of the zipmap. */
* for the total length of the zipmap. */
...
@@ -155,8 +122,8 @@ static unsigned char *zipmapLookupRaw(unsigned char *zm, unsigned char *key, uns
...
@@ -155,8 +122,8 @@ static unsigned char *zipmapLookupRaw(unsigned char *zm, unsigned char *key, uns
}
}
p
+=
llen
+
l
;
p
+=
llen
+
l
;
/* Skip the value as well */
/* Skip the value as well */
l
=
zip
map
DecodeLength
(
p
);
l
=
zipDecodeLength
(
p
);
p
+=
zip
map
EncodeLength
(
NULL
,
l
);
p
+=
zipEncodeLength
(
NULL
,
l
);
free
=
p
[
0
];
free
=
p
[
0
];
p
+=
l
+
1
+
free
;
/* +1 to skip the free byte */
p
+=
l
+
1
+
free
;
/* +1 to skip the free byte */
}
}
...
@@ -168,25 +135,23 @@ static unsigned long zipmapRequiredLength(unsigned int klen, unsigned int vlen)
...
@@ -168,25 +135,23 @@ static unsigned long zipmapRequiredLength(unsigned int klen, unsigned int vlen)
unsigned
int
l
;
unsigned
int
l
;
l
=
klen
+
vlen
+
3
;
l
=
klen
+
vlen
+
3
;
if
(
klen
>=
ZIP
MAP
_BIGLEN
)
l
+=
4
;
if
(
klen
>=
ZIP_BIGLEN
)
l
+=
4
;
if
(
vlen
>=
ZIP
MAP
_BIGLEN
)
l
+=
4
;
if
(
vlen
>=
ZIP_BIGLEN
)
l
+=
4
;
return
l
;
return
l
;
}
}
/* Return the total amount used by a key (encoded length + payload) */
/* Return the total amount used by a key (encoded length + payload) */
static
unsigned
int
zipmapRawKeyLength
(
unsigned
char
*
p
)
{
static
unsigned
int
zipmapRawKeyLength
(
unsigned
char
*
p
)
{
unsigned
int
l
=
zipmapDecodeLength
(
p
);
return
zipRawEntryLength
(
p
);
return
zipmapEncodeLength
(
NULL
,
l
)
+
l
;
}
}
/* Return the total amount used by a value
/* Return the total amount used by a value
* (encoded length + single byte free count + payload) */
* (encoded length + single byte free count + payload) */
static
unsigned
int
zipmapRawValueLength
(
unsigned
char
*
p
)
{
static
unsigned
int
zipmapRawValueLength
(
unsigned
char
*
p
)
{
unsigned
int
l
=
zip
map
DecodeLength
(
p
);
unsigned
int
l
=
zipDecodeLength
(
p
);
unsigned
int
used
;
unsigned
int
used
;
used
=
zip
map
EncodeLength
(
NULL
,
l
);
used
=
zipEncodeLength
(
NULL
,
l
);
used
+=
p
[
used
]
+
1
+
l
;
used
+=
p
[
used
]
+
1
+
l
;
return
used
;
return
used
;
}
}
...
@@ -199,12 +164,6 @@ static unsigned int zipmapRawEntryLength(unsigned char *p) {
...
@@ -199,12 +164,6 @@ static unsigned int zipmapRawEntryLength(unsigned char *p) {
return
l
+
zipmapRawValueLength
(
p
+
l
);
return
l
+
zipmapRawValueLength
(
p
+
l
);
}
}
static
inline
unsigned
char
*
zipmapResize
(
unsigned
char
*
zm
,
unsigned
int
len
)
{
zm
=
zrealloc
(
zm
,
len
);
zm
[
len
-
1
]
=
ZIPMAP_END
;
return
zm
;
}
/* 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.
* If 'update' is not NULL, *update is set to 1 if the key was
* If 'update' is not NULL, *update is set to 1 if the key was
* already preset, otherwise to 0. */
* already preset, otherwise to 0. */
...
@@ -219,12 +178,12 @@ unsigned char *zipmapSet(unsigned char *zm, unsigned char *key, unsigned int kle
...
@@ -219,12 +178,12 @@ unsigned char *zipmapSet(unsigned char *zm, unsigned char *key, unsigned int kle
p
=
zipmapLookupRaw
(
zm
,
key
,
klen
,
&
zmlen
);
p
=
zipmapLookupRaw
(
zm
,
key
,
klen
,
&
zmlen
);
if
(
p
==
NULL
)
{
if
(
p
==
NULL
)
{
/* Key not found: enlarge */
/* Key not found: enlarge */
zm
=
zip
map
Resize
(
zm
,
zmlen
+
reqlen
);
zm
=
zipResize
(
zm
,
zmlen
+
reqlen
);
p
=
zm
+
zmlen
-
1
;
p
=
zm
+
zmlen
-
1
;
zmlen
=
zmlen
+
reqlen
;
zmlen
=
zmlen
+
reqlen
;
/* Increase zipmap length (this is an insert) */
/* Increase zipmap length (this is an insert) */
if
(
zm
[
0
]
<
ZIP
MAP
_BIGLEN
)
zm
[
0
]
++
;
if
(
zm
[
0
]
<
ZIP_BIGLEN
)
zm
[
0
]
++
;
}
else
{
}
else
{
/* 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: */
...
@@ -235,7 +194,7 @@ unsigned char *zipmapSet(unsigned char *zm, unsigned char *key, unsigned int kle
...
@@ -235,7 +194,7 @@ unsigned char *zipmapSet(unsigned char *zm, unsigned char *key, unsigned int kle
* it can be resized. Then, move the tail backwards so this
* it can be resized. Then, move the tail backwards so this
* pair fits at the current position. */
* pair fits at the current position. */
offset
=
p
-
zm
;
offset
=
p
-
zm
;
zm
=
zip
map
Resize
(
zm
,
zmlen
-
freelen
+
reqlen
);
zm
=
zipResize
(
zm
,
zmlen
-
freelen
+
reqlen
);
p
=
zm
+
offset
;
p
=
zm
+
offset
;
/* The +1 in the number of bytes to be moved is caused by the
/* The +1 in the number of bytes to be moved is caused by the
...
@@ -257,7 +216,7 @@ unsigned char *zipmapSet(unsigned char *zm, unsigned char *key, unsigned int kle
...
@@ -257,7 +216,7 @@ unsigned char *zipmapSet(unsigned char *zm, unsigned char *key, unsigned int kle
offset
=
p
-
zm
;
offset
=
p
-
zm
;
memmove
(
p
+
reqlen
,
p
+
freelen
,
zmlen
-
(
offset
+
freelen
+
1
));
memmove
(
p
+
reqlen
,
p
+
freelen
,
zmlen
-
(
offset
+
freelen
+
1
));
zmlen
-=
empty
;
zmlen
-=
empty
;
zm
=
zip
map
Resize
(
zm
,
zmlen
);
zm
=
zipResize
(
zm
,
zmlen
);
p
=
zm
+
offset
;
p
=
zm
+
offset
;
vempty
=
0
;
vempty
=
0
;
}
else
{
}
else
{
...
@@ -266,11 +225,11 @@ unsigned char *zipmapSet(unsigned char *zm, unsigned char *key, unsigned int kle
...
@@ -266,11 +225,11 @@ unsigned char *zipmapSet(unsigned char *zm, unsigned char *key, unsigned int kle
/* Just write the key + value and we are done. */
/* Just write the key + value and we are done. */
/* Key: */
/* Key: */
p
+=
zip
map
EncodeLength
(
p
,
klen
);
p
+=
zipEncodeLength
(
p
,
klen
);
memcpy
(
p
,
key
,
klen
);
memcpy
(
p
,
key
,
klen
);
p
+=
klen
;
p
+=
klen
;
/* Value: */
/* Value: */
p
+=
zip
map
EncodeLength
(
p
,
vlen
);
p
+=
zipEncodeLength
(
p
,
vlen
);
*
p
++
=
vempty
;
*
p
++
=
vempty
;
memcpy
(
p
,
val
,
vlen
);
memcpy
(
p
,
val
,
vlen
);
return
zm
;
return
zm
;
...
@@ -284,10 +243,10 @@ unsigned char *zipmapDel(unsigned char *zm, unsigned char *key, unsigned int kle
...
@@ -284,10 +243,10 @@ unsigned char *zipmapDel(unsigned char *zm, unsigned char *key, unsigned int kle
if
(
p
)
{
if
(
p
)
{
freelen
=
zipmapRawEntryLength
(
p
);
freelen
=
zipmapRawEntryLength
(
p
);
memmove
(
p
,
p
+
freelen
,
zmlen
-
((
p
-
zm
)
+
freelen
+
1
));
memmove
(
p
,
p
+
freelen
,
zmlen
-
((
p
-
zm
)
+
freelen
+
1
));
zm
=
zip
map
Resize
(
zm
,
zmlen
-
freelen
);
zm
=
zipResize
(
zm
,
zmlen
-
freelen
);
/* Decrease zipmap length */
/* Decrease zipmap length */
if
(
zm
[
0
]
<
ZIP
MAP
_BIGLEN
)
zm
[
0
]
--
;
if
(
zm
[
0
]
<
ZIP_BIGLEN
)
zm
[
0
]
--
;
if
(
deleted
)
*
deleted
=
1
;
if
(
deleted
)
*
deleted
=
1
;
}
else
{
}
else
{
...
@@ -313,17 +272,17 @@ unsigned char *zipmapRewind(unsigned char *zm) {
...
@@ -313,17 +272,17 @@ unsigned char *zipmapRewind(unsigned char *zm) {
* }
* }
*/
*/
unsigned
char
*
zipmapNext
(
unsigned
char
*
zm
,
unsigned
char
**
key
,
unsigned
int
*
klen
,
unsigned
char
**
value
,
unsigned
int
*
vlen
)
{
unsigned
char
*
zipmapNext
(
unsigned
char
*
zm
,
unsigned
char
**
key
,
unsigned
int
*
klen
,
unsigned
char
**
value
,
unsigned
int
*
vlen
)
{
if
(
zm
[
0
]
==
ZIP
MAP
_END
)
return
NULL
;
if
(
zm
[
0
]
==
ZIP_END
)
return
NULL
;
if
(
key
)
{
if
(
key
)
{
*
key
=
zm
;
*
key
=
zm
;
*
klen
=
zip
map
DecodeLength
(
zm
);
*
klen
=
zipDecodeLength
(
zm
);
*
key
+=
ZIP
MAP
_LEN_BYTES
(
*
klen
);
*
key
+=
ZIP_LEN_BYTES
(
*
klen
);
}
}
zm
+=
zipmapRawKeyLength
(
zm
);
zm
+=
zipmapRawKeyLength
(
zm
);
if
(
value
)
{
if
(
value
)
{
*
value
=
zm
+
1
;
*
value
=
zm
+
1
;
*
vlen
=
zip
map
DecodeLength
(
zm
);
*
vlen
=
zipDecodeLength
(
zm
);
*
value
+=
ZIP
MAP
_LEN_BYTES
(
*
vlen
);
*
value
+=
ZIP_LEN_BYTES
(
*
vlen
);
}
}
zm
+=
zipmapRawValueLength
(
zm
);
zm
+=
zipmapRawValueLength
(
zm
);
return
zm
;
return
zm
;
...
@@ -336,8 +295,8 @@ int zipmapGet(unsigned char *zm, unsigned char *key, unsigned int klen, unsigned
...
@@ -336,8 +295,8 @@ int zipmapGet(unsigned char *zm, unsigned char *key, unsigned int klen, unsigned
if
((
p
=
zipmapLookupRaw
(
zm
,
key
,
klen
,
NULL
))
==
NULL
)
return
0
;
if
((
p
=
zipmapLookupRaw
(
zm
,
key
,
klen
,
NULL
))
==
NULL
)
return
0
;
p
+=
zipmapRawKeyLength
(
p
);
p
+=
zipmapRawKeyLength
(
p
);
*
vlen
=
zip
map
DecodeLength
(
p
);
*
vlen
=
zipDecodeLength
(
p
);
*
value
=
p
+
ZIP
MAP
_LEN_BYTES
(
*
vlen
)
+
1
;
*
value
=
p
+
ZIP_LEN_BYTES
(
*
vlen
)
+
1
;
return
1
;
return
1
;
}
}
...
@@ -349,14 +308,14 @@ int zipmapExists(unsigned char *zm, unsigned char *key, unsigned int klen) {
...
@@ -349,14 +308,14 @@ int zipmapExists(unsigned char *zm, unsigned char *key, unsigned int klen) {
/* Return the number of entries inside a zipmap */
/* Return the number of entries inside a zipmap */
unsigned
int
zipmapLen
(
unsigned
char
*
zm
)
{
unsigned
int
zipmapLen
(
unsigned
char
*
zm
)
{
unsigned
int
len
=
0
;
unsigned
int
len
=
0
;
if
(
zm
[
0
]
<
ZIP
MAP
_BIGLEN
)
{
if
(
zm
[
0
]
<
ZIP_BIGLEN
)
{
len
=
zm
[
0
];
len
=
zm
[
0
];
}
else
{
}
else
{
unsigned
char
*
p
=
zipmapRewind
(
zm
);
unsigned
char
*
p
=
zipmapRewind
(
zm
);
while
((
p
=
zipmapNext
(
p
,
NULL
,
NULL
,
NULL
,
NULL
))
!=
NULL
)
len
++
;
while
((
p
=
zipmapNext
(
p
,
NULL
,
NULL
,
NULL
,
NULL
))
!=
NULL
)
len
++
;
/* Re-store length if small enough */
/* Re-store length if small enough */
if
(
len
<
ZIP
MAP
_BIGLEN
)
zm
[
0
]
=
len
;
if
(
len
<
ZIP_BIGLEN
)
zm
[
0
]
=
len
;
}
}
return
len
;
return
len
;
}
}
...
@@ -366,21 +325,21 @@ void zipmapRepr(unsigned char *p) {
...
@@ -366,21 +325,21 @@ void zipmapRepr(unsigned char *p) {
printf
(
"{status %u}"
,
*
p
++
);
printf
(
"{status %u}"
,
*
p
++
);
while
(
1
)
{
while
(
1
)
{
if
(
p
[
0
]
==
ZIP
MAP
_END
)
{
if
(
p
[
0
]
==
ZIP_END
)
{
printf
(
"{end}"
);
printf
(
"{end}"
);
break
;
break
;
}
else
{
}
else
{
unsigned
char
e
;
unsigned
char
e
;
l
=
zip
map
DecodeLength
(
p
);
l
=
zipDecodeLength
(
p
);
printf
(
"{key %u}"
,
l
);
printf
(
"{key %u}"
,
l
);
p
+=
zip
map
EncodeLength
(
NULL
,
l
);
p
+=
zipEncodeLength
(
NULL
,
l
);
fwrite
(
p
,
l
,
1
,
stdout
);
fwrite
(
p
,
l
,
1
,
stdout
);
p
+=
l
;
p
+=
l
;
l
=
zip
map
DecodeLength
(
p
);
l
=
zipDecodeLength
(
p
);
printf
(
"{value %u}"
,
l
);
printf
(
"{value %u}"
,
l
);
p
+=
zip
map
EncodeLength
(
NULL
,
l
);
p
+=
zipEncodeLength
(
NULL
,
l
);
e
=
*
p
++
;
e
=
*
p
++
;
fwrite
(
p
,
l
,
1
,
stdout
);
fwrite
(
p
,
l
,
1
,
stdout
);
p
+=
l
+
e
;
p
+=
l
+
e
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment