Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
37fff074
Commit
37fff074
authored
May 22, 2010
by
Pieter Noordhuis
Browse files
move code from zip.c to ziplist.c
parent
af5f66fb
Changes
2
Hide whitespace changes
Inline
Side-by-side
zip.c
deleted
100644 → 0
View file @
af5f66fb
#define ZIP_BIGLEN 254
#define ZIP_END 255
/* Entry encoding */
#define ZIP_ENC_RAW 0
#define ZIP_ENC_SHORT 1
#define ZIP_ENC_INT 2
#define ZIP_ENC_LLONG 3
#define ZIP_ENCODING(p) ((p)[0] >> 6)
/* Length encoding for raw entries */
#define ZIP_LEN_INLINE 0
#define ZIP_LEN_UINT16 1
#define ZIP_LEN_UINT32 2
static
unsigned
int
zipEncodingSize
(
char
encoding
)
{
if
(
encoding
==
ZIP_ENC_SHORT
)
{
return
sizeof
(
short
int
);
}
else
if
(
encoding
==
ZIP_ENC_INT
)
{
return
sizeof
(
int
);
}
else
if
(
encoding
==
ZIP_ENC_LLONG
)
{
return
sizeof
(
long
long
);
}
assert
(
NULL
);
}
/* Decode the encoded length pointed by 'p'. If a pointer to 'lensize' is
* provided, it is set to the number of bytes required to encode the length. */
static
unsigned
int
zipDecodeLength
(
unsigned
char
*
p
,
unsigned
int
*
lensize
)
{
unsigned
char
encoding
=
ZIP_ENCODING
(
p
),
lenenc
;
unsigned
int
len
;
if
(
encoding
==
ZIP_ENC_RAW
)
{
lenenc
=
(
p
[
0
]
>>
4
)
&
0x3
;
if
(
lenenc
==
ZIP_LEN_INLINE
)
{
len
=
p
[
0
]
&
0xf
;
if
(
lensize
)
*
lensize
=
1
;
}
else
if
(
lenenc
==
ZIP_LEN_UINT16
)
{
len
=
p
[
1
]
|
(
p
[
2
]
<<
8
);
if
(
lensize
)
*
lensize
=
3
;
}
else
{
len
=
p
[
1
]
|
(
p
[
2
]
<<
8
)
|
(
p
[
3
]
<<
16
)
|
(
p
[
4
]
<<
24
);
if
(
lensize
)
*
lensize
=
5
;
}
}
else
{
len
=
zipEncodingSize
(
encoding
);
if
(
lensize
)
*
lensize
=
1
;
}
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
,
char
encoding
,
unsigned
int
rawlen
)
{
unsigned
char
len
=
1
,
lenenc
,
buf
[
5
];
if
(
encoding
==
ZIP_ENC_RAW
)
{
if
(
rawlen
<=
0xf
)
{
if
(
!
p
)
return
len
;
lenenc
=
ZIP_LEN_INLINE
;
buf
[
0
]
=
rawlen
;
}
else
if
(
rawlen
<=
0xffff
)
{
len
+=
2
;
if
(
!
p
)
return
len
;
lenenc
=
ZIP_LEN_UINT16
;
buf
[
1
]
=
(
rawlen
)
&
0xff
;
buf
[
2
]
=
(
rawlen
>>
8
)
&
0xff
;
}
else
{
len
+=
4
;
if
(
!
p
)
return
len
;
lenenc
=
ZIP_LEN_UINT32
;
buf
[
1
]
=
(
rawlen
)
&
0xff
;
buf
[
2
]
=
(
rawlen
>>
8
)
&
0xff
;
buf
[
3
]
=
(
rawlen
>>
16
)
&
0xff
;
buf
[
4
]
=
(
rawlen
>>
24
)
&
0xff
;
}
buf
[
0
]
=
(
lenenc
<<
4
)
|
(
buf
[
0
]
&
0xf
);
}
if
(
!
p
)
return
len
;
/* Apparently we need to store the length in 'p' */
buf
[
0
]
=
(
encoding
<<
6
)
|
(
buf
[
0
]
&
0x3f
);
memcpy
(
p
,
buf
,
len
);
return
len
;
}
/* Check if string pointed to by 'entry' can be encoded as an integer.
* Stores the integer value in 'v' and its encoding in 'encoding'.
* Warning: this function requires a NULL-terminated string! */
static
int
zipTryEncoding
(
unsigned
char
*
entry
,
long
long
*
v
,
char
*
encoding
)
{
long
long
value
;
char
*
eptr
;
if
(
entry
[
0
]
==
'-'
||
(
entry
[
0
]
>=
'0'
&&
entry
[
0
]
<=
'9'
))
{
value
=
strtoll
(
entry
,
&
eptr
,
10
);
if
(
eptr
[
0
]
!=
'\0'
)
return
0
;
if
(
value
>=
SHRT_MIN
&&
value
<=
SHRT_MAX
)
{
*
encoding
=
ZIP_ENC_SHORT
;
}
else
if
(
value
>=
INT_MIN
&&
value
<=
INT_MAX
)
{
*
encoding
=
ZIP_ENC_INT
;
}
else
{
*
encoding
=
ZIP_ENC_LLONG
;
}
*
v
=
value
;
return
1
;
}
return
0
;
}
static
void
zipSaveInteger
(
unsigned
char
*
p
,
long
long
value
,
char
encoding
)
{
short
int
s
;
int
i
;
long
long
l
;
if
(
encoding
==
ZIP_ENC_SHORT
)
{
s
=
value
;
memcpy
(
p
,
&
s
,
sizeof
(
s
));
}
else
if
(
encoding
==
ZIP_ENC_INT
)
{
i
=
value
;
memcpy
(
p
,
&
i
,
sizeof
(
i
));
}
else
if
(
encoding
==
ZIP_ENC_LLONG
)
{
l
=
value
;
memcpy
(
p
,
&
l
,
sizeof
(
l
));
}
else
{
assert
(
NULL
);
}
}
static
long
long
zipLoadInteger
(
unsigned
char
*
p
,
char
encoding
)
{
short
int
s
;
int
i
;
long
long
l
,
ret
;
if
(
encoding
==
ZIP_ENC_SHORT
)
{
memcpy
(
&
s
,
p
,
sizeof
(
s
));
ret
=
s
;
}
else
if
(
encoding
==
ZIP_ENC_INT
)
{
memcpy
(
&
i
,
p
,
sizeof
(
i
));
ret
=
i
;
}
else
if
(
encoding
==
ZIP_ENC_LLONG
)
{
memcpy
(
&
l
,
p
,
sizeof
(
l
));
ret
=
l
;
}
else
{
assert
(
NULL
);
}
return
ret
;
}
/* Return the total amount used by an entry (encoded length + payload). */
static
unsigned
int
zipRawEntryLength
(
unsigned
char
*
p
)
{
unsigned
int
lensize
,
len
;
len
=
zipDecodeLength
(
p
,
&
lensize
);
return
lensize
+
len
;
}
/* 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
;
}
ziplist.c
View file @
37fff074
...
...
@@ -22,14 +22,168 @@
#include "zmalloc.h"
#include "sds.h"
#include "ziplist.h"
#include "zip.c"
#define ZIP_END 255
/* Entry encoding */
#define ZIP_ENC_RAW 0
#define ZIP_ENC_SHORT 1
#define ZIP_ENC_INT 2
#define ZIP_ENC_LLONG 3
#define ZIP_ENCODING(p) ((p)[0] >> 6)
/* Length encoding for raw entries */
#define ZIP_LEN_INLINE 0
#define ZIP_LEN_UINT16 1
#define ZIP_LEN_UINT32 2
/* Utility macros */
#define ZIPLIST_BYTES(zl) (*((unsigned int*)(zl)))
#define ZIPLIST_LENGTH(zl) (*((zl)+sizeof(unsigned int)))
#define ZIPLIST_HEADER_SIZE (sizeof(unsigned int)+1)
#define ZIPLIST_INCR_LENGTH(zl,incr) { \
if (ZIPLIST_LENGTH(zl) < (ZIP_END-1)) ZIPLIST_LENGTH(zl)+=incr; }
/* Return bytes needed to store integer encoded by 'encoding' */
static
unsigned
int
zipEncodingSize
(
char
encoding
)
{
if
(
encoding
==
ZIP_ENC_SHORT
)
{
return
sizeof
(
short
int
);
}
else
if
(
encoding
==
ZIP_ENC_INT
)
{
return
sizeof
(
int
);
}
else
if
(
encoding
==
ZIP_ENC_LLONG
)
{
return
sizeof
(
long
long
);
}
assert
(
NULL
);
}
/* Decode the encoded length pointed by 'p'. If a pointer to 'lensize' is
* provided, it is set to the number of bytes required to encode the length. */
static
unsigned
int
zipDecodeLength
(
unsigned
char
*
p
,
unsigned
int
*
lensize
)
{
unsigned
char
encoding
=
ZIP_ENCODING
(
p
),
lenenc
;
unsigned
int
len
;
if
(
encoding
==
ZIP_ENC_RAW
)
{
lenenc
=
(
p
[
0
]
>>
4
)
&
0x3
;
if
(
lenenc
==
ZIP_LEN_INLINE
)
{
len
=
p
[
0
]
&
0xf
;
if
(
lensize
)
*
lensize
=
1
;
}
else
if
(
lenenc
==
ZIP_LEN_UINT16
)
{
len
=
p
[
1
]
|
(
p
[
2
]
<<
8
);
if
(
lensize
)
*
lensize
=
3
;
}
else
{
len
=
p
[
1
]
|
(
p
[
2
]
<<
8
)
|
(
p
[
3
]
<<
16
)
|
(
p
[
4
]
<<
24
);
if
(
lensize
)
*
lensize
=
5
;
}
}
else
{
len
=
zipEncodingSize
(
encoding
);
if
(
lensize
)
*
lensize
=
1
;
}
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
,
char
encoding
,
unsigned
int
rawlen
)
{
unsigned
char
len
=
1
,
lenenc
,
buf
[
5
];
if
(
encoding
==
ZIP_ENC_RAW
)
{
if
(
rawlen
<=
0xf
)
{
if
(
!
p
)
return
len
;
lenenc
=
ZIP_LEN_INLINE
;
buf
[
0
]
=
rawlen
;
}
else
if
(
rawlen
<=
0xffff
)
{
len
+=
2
;
if
(
!
p
)
return
len
;
lenenc
=
ZIP_LEN_UINT16
;
buf
[
1
]
=
(
rawlen
)
&
0xff
;
buf
[
2
]
=
(
rawlen
>>
8
)
&
0xff
;
}
else
{
len
+=
4
;
if
(
!
p
)
return
len
;
lenenc
=
ZIP_LEN_UINT32
;
buf
[
1
]
=
(
rawlen
)
&
0xff
;
buf
[
2
]
=
(
rawlen
>>
8
)
&
0xff
;
buf
[
3
]
=
(
rawlen
>>
16
)
&
0xff
;
buf
[
4
]
=
(
rawlen
>>
24
)
&
0xff
;
}
buf
[
0
]
=
(
lenenc
<<
4
)
|
(
buf
[
0
]
&
0xf
);
}
if
(
!
p
)
return
len
;
/* Apparently we need to store the length in 'p' */
buf
[
0
]
=
(
encoding
<<
6
)
|
(
buf
[
0
]
&
0x3f
);
memcpy
(
p
,
buf
,
len
);
return
len
;
}
/* Check if string pointed to by 'entry' can be encoded as an integer.
* Stores the integer value in 'v' and its encoding in 'encoding'.
* Warning: this function requires a NULL-terminated string! */
static
int
zipTryEncoding
(
unsigned
char
*
entry
,
long
long
*
v
,
char
*
encoding
)
{
long
long
value
;
char
*
eptr
;
if
(
entry
[
0
]
==
'-'
||
(
entry
[
0
]
>=
'0'
&&
entry
[
0
]
<=
'9'
))
{
value
=
strtoll
(
entry
,
&
eptr
,
10
);
if
(
eptr
[
0
]
!=
'\0'
)
return
0
;
if
(
value
>=
SHRT_MIN
&&
value
<=
SHRT_MAX
)
{
*
encoding
=
ZIP_ENC_SHORT
;
}
else
if
(
value
>=
INT_MIN
&&
value
<=
INT_MAX
)
{
*
encoding
=
ZIP_ENC_INT
;
}
else
{
*
encoding
=
ZIP_ENC_LLONG
;
}
*
v
=
value
;
return
1
;
}
return
0
;
}
/* Store integer 'value' at 'p', encoded as 'encoding' */
static
void
zipSaveInteger
(
unsigned
char
*
p
,
long
long
value
,
char
encoding
)
{
short
int
s
;
int
i
;
long
long
l
;
if
(
encoding
==
ZIP_ENC_SHORT
)
{
s
=
value
;
memcpy
(
p
,
&
s
,
sizeof
(
s
));
}
else
if
(
encoding
==
ZIP_ENC_INT
)
{
i
=
value
;
memcpy
(
p
,
&
i
,
sizeof
(
i
));
}
else
if
(
encoding
==
ZIP_ENC_LLONG
)
{
l
=
value
;
memcpy
(
p
,
&
l
,
sizeof
(
l
));
}
else
{
assert
(
NULL
);
}
}
/* Read integer encoded as 'encoding' from 'p' */
static
long
long
zipLoadInteger
(
unsigned
char
*
p
,
char
encoding
)
{
short
int
s
;
int
i
;
long
long
l
,
ret
;
if
(
encoding
==
ZIP_ENC_SHORT
)
{
memcpy
(
&
s
,
p
,
sizeof
(
s
));
ret
=
s
;
}
else
if
(
encoding
==
ZIP_ENC_INT
)
{
memcpy
(
&
i
,
p
,
sizeof
(
i
));
ret
=
i
;
}
else
if
(
encoding
==
ZIP_ENC_LLONG
)
{
memcpy
(
&
l
,
p
,
sizeof
(
l
));
ret
=
l
;
}
else
{
assert
(
NULL
);
}
return
ret
;
}
/* Return the total amount used by an entry (encoded length + payload). */
static
unsigned
int
zipRawEntryLength
(
unsigned
char
*
p
)
{
unsigned
int
lensize
,
len
;
len
=
zipDecodeLength
(
p
,
&
lensize
);
return
lensize
+
len
;
}
/* Create a new empty ziplist. */
unsigned
char
*
ziplistNew
(
void
)
{
unsigned
int
bytes
=
ZIPLIST_HEADER_SIZE
+
1
;
...
...
@@ -40,8 +194,9 @@ unsigned char *ziplistNew(void) {
return
zl
;
}
/* Resize the ziplist. */
static
unsigned
char
*
ziplistResize
(
unsigned
char
*
zl
,
unsigned
int
len
)
{
zl
=
z
ipResize
(
zl
,
len
);
zl
=
z
realloc
(
zl
,
len
);
ZIPLIST_BYTES
(
zl
)
=
len
;
zl
[
len
-
1
]
=
ZIP_END
;
return
zl
;
...
...
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