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
6435c767
Commit
6435c767
authored
May 29, 2010
by
Pieter Noordhuis
Browse files
function to insert an element at an arbitrary position in the list
parent
0c0d0564
Changes
1
Hide whitespace changes
Inline
Side-by-side
ziplist.c
View file @
6435c767
...
@@ -286,66 +286,79 @@ static unsigned char *__ziplistDelete(unsigned char *zl, unsigned char *p, int n
...
@@ -286,66 +286,79 @@ static unsigned char *__ziplistDelete(unsigned char *zl, unsigned char *p, int n
return
zl
;
return
zl
;
}
}
unsigned
char
*
ziplistPush
(
unsigned
char
*
zl
,
unsigned
char
*
entry
,
unsigned
int
elen
,
int
where
)
{
/* Insert item at "p". */
unsigned
int
curlen
=
ZIPLIST_BYTES
(
zl
),
reqlen
,
prevlen
;
static
unsigned
char
*
__ziplistInsert
(
unsigned
char
*
zl
,
unsigned
char
*
p
,
unsigned
char
*
s
,
unsigned
int
slen
)
{
unsigned
char
*
p
,
*
curtail
;
unsigned
int
curlen
=
ZIPLIST_BYTES
(
zl
),
reqlen
,
prevlen
=
0
;
unsigned
int
offset
,
nextdiff
=
0
;
unsigned
char
*
tail
;
char
encoding
=
ZIP_ENC_RAW
;
char
encoding
=
ZIP_ENC_RAW
;
long
long
value
;
long
long
value
;
zlentry
entry
;
/* We need to store the length of the current tail when the list
/* Find out prevlen for the entry that is inserted. */
* is non-empty and we push at the tail. */
if
(
p
[
0
]
!=
ZIP_END
)
{
curtail
=
zl
+
ZIPLIST_TAIL_OFFSET
(
zl
);
entry
=
zipEntry
(
p
);
if
(
where
==
ZIPLIST_TAIL
&&
curtail
[
0
]
!=
ZIP_END
)
{
prevlen
=
entry
.
prevrawlen
;
prevlen
=
zipRawEntryLength
(
curtail
);
}
else
{
}
else
{
prevlen
=
0
;
tail
=
ziplistTail
(
zl
);
if
(
tail
[
0
]
!=
ZIP_END
)
{
prevlen
=
zipRawEntryLength
(
tail
);
}
}
}
/* See if the entry can be encoded */
/* See if the entry can be encoded */
if
(
zipTryEncoding
(
entry
,
&
value
,
&
encoding
))
{
if
(
zipTryEncoding
(
s
,
&
value
,
&
encoding
))
{
reqlen
=
zipEncodingSize
(
encoding
);
reqlen
=
zipEncodingSize
(
encoding
);
}
else
{
}
else
{
reqlen
=
e
len
;
reqlen
=
s
len
;
}
}
/* We need space for both the length of the previous entry and
/* We need space for both the length of the previous entry and
* the length of the payload. */
* the length of the payload. */
reqlen
+=
zipEncodeLength
(
NULL
,
ZIP_ENC_RAW
,
prevlen
);
reqlen
+=
zipEncodeLength
(
NULL
,
ZIP_ENC_RAW
,
prevlen
);
reqlen
+=
zipEncodeLength
(
NULL
,
encoding
,
elen
);
reqlen
+=
zipEncodeLength
(
NULL
,
encoding
,
slen
);
/* Resize the ziplist and move if needed */
/* When the insert position is not equal to the tail, we need to
zl
=
ziplistResize
(
zl
,
curlen
+
reqlen
);
* make sure that the next entry can hold this entry's length in
if
(
where
==
ZIPLIST_HEAD
)
{
* its prevlen field. */
p
=
zl
+
ZIPLIST_HEADER_SIZE
;
nextdiff
=
p
[
0
]
!=
ZIP_END
?
zipPrevLenByteDiff
(
p
,
reqlen
)
:
0
;
if
(
*
p
!=
ZIP_END
)
{
/* Subtract one because of the ZIP_END bytes */
/* Store offset because a realloc may change the address of zl. */
memmove
(
p
+
reqlen
,
p
,
curlen
-
ZIPLIST_HEADER_SIZE
-
1
);
offset
=
p
-
zl
;
}
zl
=
ziplistResize
(
zl
,
curlen
+
reqlen
+
nextdiff
);
p
=
zl
+
offset
;
/* Apply memory move when necessary and update tail offset. */
if
(
p
[
0
]
!=
ZIP_END
)
{
/* Subtract one because of the ZIP_END bytes */
memmove
(
p
+
reqlen
,
p
-
nextdiff
,
curlen
-
offset
-
1
+
nextdiff
);
/* Encode this entry's raw length in the next entry. */
zipEncodeLength
(
p
+
reqlen
,
ZIP_ENC_RAW
,
reqlen
);
/* Update offset for tail */
ZIPLIST_TAIL_OFFSET
(
zl
)
+=
reqlen
+
nextdiff
;
}
else
{
}
else
{
p
=
zl
+
curlen
-
1
;
/* This element will be the new tail. */
}
ZIPLIST_TAIL_OFFSET
(
zl
)
=
p
-
zl
;
/* Update tail offset if this is not the first element */
if
(
curtail
[
0
]
!=
ZIP_END
)
{
if
(
where
==
ZIPLIST_HEAD
)
{
ZIPLIST_TAIL_OFFSET
(
zl
)
+=
reqlen
;
}
else
{
ZIPLIST_TAIL_OFFSET
(
zl
)
+=
prevlen
;
}
}
}
/* Write the entry */
/* Write the entry */
p
+=
zipEncodeLength
(
p
,
ZIP_ENC_RAW
,
prevlen
);
p
+=
zipEncodeLength
(
p
,
ZIP_ENC_RAW
,
prevlen
);
p
+=
zipEncodeLength
(
p
,
encoding
,
e
len
);
p
+=
zipEncodeLength
(
p
,
encoding
,
s
len
);
if
(
encoding
!=
ZIP_ENC_RAW
)
{
if
(
encoding
!=
ZIP_ENC_RAW
)
{
zipSaveInteger
(
p
,
value
,
encoding
);
zipSaveInteger
(
p
,
value
,
encoding
);
}
else
{
}
else
{
memcpy
(
p
,
entry
,
e
len
);
memcpy
(
p
,
s
,
s
len
);
}
}
ZIPLIST_INCR_LENGTH
(
zl
,
1
);
ZIPLIST_INCR_LENGTH
(
zl
,
1
);
return
zl
;
return
zl
;
}
}
unsigned
char
*
ziplistPush
(
unsigned
char
*
zl
,
unsigned
char
*
s
,
unsigned
int
slen
,
int
where
)
{
unsigned
char
*
p
;
p
=
(
where
==
ZIPLIST_HEAD
)
?
ziplistHead
(
zl
)
:
(
zl
+
ZIPLIST_BYTES
(
zl
)
-
1
);
return
__ziplistInsert
(
zl
,
p
,
s
,
slen
);
}
unsigned
char
*
ziplistPop
(
unsigned
char
*
zl
,
sds
*
target
,
int
where
)
{
unsigned
char
*
ziplistPop
(
unsigned
char
*
zl
,
sds
*
target
,
int
where
)
{
zlentry
entry
;
zlentry
entry
;
unsigned
char
*
p
;
unsigned
char
*
p
;
...
...
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