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
d2ee16ab
Commit
d2ee16ab
authored
May 30, 2010
by
Pieter Noordhuis
Browse files
update LREM to support dual encoding via extra iteration primitives
parent
9ae6b0be
Changes
1
Hide whitespace changes
Inline
Side-by-side
redis.c
View file @
d2ee16ab
...
@@ -4864,6 +4864,17 @@ static void lReleaseIterator(lIterator *li) {
...
@@ -4864,6 +4864,17 @@ static void lReleaseIterator(lIterator *li) {
zfree
(
li
);
zfree
(
li
);
}
}
/* Whether the entry pointed at is a valid entry. */
static
int
lIsEntry
(
lIterator
*
li
)
{
if
(
li
->
encoding
==
REDIS_ENCODING_ZIPLIST
)
{
return
li
->
zi
!=
NULL
;
}
else
if
(
li
->
encoding
==
REDIS_ENCODING_LIST
)
{
return
li
->
ln
!=
NULL
;
}
else
{
redisPanic
(
"Unknown list encoding"
);
}
}
/* Return entry or NULL at the current position of the iterator. */
/* Return entry or NULL at the current position of the iterator. */
static
robj
*
lGet
(
lIterator
*
li
)
{
static
robj
*
lGet
(
lIterator
*
li
)
{
robj
*
value
=
NULL
;
robj
*
value
=
NULL
;
...
@@ -4889,6 +4900,36 @@ static robj *lGet(lIterator *li) {
...
@@ -4889,6 +4900,36 @@ static robj *lGet(lIterator *li) {
return
value
;
return
value
;
}
}
/* Delete the element pointed to. */
static
void
lDelete
(
lIterator
*
li
,
int
direction
)
{
if
(
li
->
encoding
==
REDIS_ENCODING_ZIPLIST
)
{
direction
=
(
direction
==
REDIS_HEAD
)
?
ZIPLIST_HEAD
:
ZIPLIST_TAIL
;
li
->
subject
->
ptr
=
ziplistDelete
(
li
->
subject
->
ptr
,
&
li
->
zi
,
direction
);
}
else
if
(
li
->
encoding
==
REDIS_ENCODING_LIST
)
{
listNode
*
next
;
if
(
direction
==
REDIS_HEAD
)
next
=
li
->
ln
->
prev
;
else
next
=
li
->
ln
->
next
;
listDelNode
(
li
->
subject
->
ptr
,
li
->
ln
);
li
->
ln
=
next
;
}
else
{
redisPanic
(
"Unknown list encoding"
);
}
}
/* Compare the given object with the entry at the current position. */
static
int
lEqualTo
(
lIterator
*
li
,
robj
*
o
)
{
if
(
li
->
encoding
==
REDIS_ENCODING_ZIPLIST
)
{
redisAssert
(
o
->
encoding
==
REDIS_ENCODING_RAW
);
return
ziplistCompare
(
li
->
zi
,
o
->
ptr
,
sdslen
(
o
->
ptr
));
}
else
if
(
li
->
encoding
==
REDIS_ENCODING_LIST
)
{
return
equalStringObjects
(
o
,
listNodeValue
(
li
->
ln
));
}
else
{
redisPanic
(
"Unknown list encoding"
);
}
}
/* Move to the next or previous entry in the list. */
/* Move to the next or previous entry in the list. */
static
void
lMove
(
lIterator
*
li
,
int
where
)
{
static
void
lMove
(
lIterator
*
li
,
int
where
)
{
if
(
li
->
encoding
==
REDIS_ENCODING_ZIPLIST
)
{
if
(
li
->
encoding
==
REDIS_ENCODING_ZIPLIST
)
{
...
@@ -5129,35 +5170,45 @@ static void ltrimCommand(redisClient *c) {
...
@@ -5129,35 +5170,45 @@ static void ltrimCommand(redisClient *c) {
}
}
static
void
lremCommand
(
redisClient
*
c
)
{
static
void
lremCommand
(
redisClient
*
c
)
{
robj
*
o
;
robj
*
subject
,
*
obj
=
c
->
argv
[
3
];
list
*
list
;
listNode
*
ln
,
*
next
;
int
toremove
=
atoi
(
c
->
argv
[
2
]
->
ptr
);
int
toremove
=
atoi
(
c
->
argv
[
2
]
->
ptr
);
int
removed
=
0
;
int
removed
=
0
;
int
fromtail
=
0
;
int
direction
;
if
((
o
=
lookupKeyWriteOrReply
(
c
,
c
->
argv
[
1
],
shared
.
czero
))
==
NULL
||
subject
=
lookupKeyWriteOrReply
(
c
,
c
->
argv
[
1
],
shared
.
czero
);
checkType
(
c
,
o
,
REDIS_LIST
))
return
;
if
(
subject
==
NULL
||
checkType
(
c
,
subject
,
REDIS_LIST
))
return
;
list
=
o
->
ptr
;
/* Make sure obj is raw when we're dealing with a ziplist */
if
(
subject
->
encoding
==
REDIS_ENCODING_ZIPLIST
)
obj
=
getDecodedObject
(
obj
);
lIterator
*
li
;
if
(
toremove
<
0
)
{
if
(
toremove
<
0
)
{
toremove
=
-
toremove
;
toremove
=
-
toremove
;
fromtail
=
1
;
direction
=
REDIS_HEAD
;
li
=
lInitIterator
(
subject
,
-
1
);
}
else
{
direction
=
REDIS_TAIL
;
li
=
lInitIterator
(
subject
,
0
);
}
}
ln
=
fromtail
?
list
->
tail
:
list
->
head
;
while
(
ln
)
{
robj
*
ele
=
listNodeValue
(
ln
);
next
=
fromtail
?
ln
->
prev
:
ln
->
next
;
while
(
toremove
&&
lIsEntry
(
li
))
{
if
(
e
qual
StringObjects
(
ele
,
c
->
argv
[
3
]
))
{
if
(
lE
qual
To
(
li
,
obj
))
{
l
istDelNode
(
list
,
l
n
);
l
Delete
(
li
,
directio
n
);
server
.
dirty
++
;
server
.
dirty
++
;
toremove
--
;
removed
++
;
removed
++
;
if
(
toremove
&&
removed
==
toremove
)
break
;
}
else
{
lMove
(
li
,
direction
);
}
}
ln
=
next
;
}
}
if
(
listLength
(
list
)
==
0
)
deleteKey
(
c
->
db
,
c
->
argv
[
1
]);
lReleaseIterator
(
li
);
/* Clean up raw encoded object */
if
(
subject
->
encoding
==
REDIS_ENCODING_ZIPLIST
)
decrRefCount
(
obj
);
if
(
lLength
(
subject
)
==
0
)
deleteKey
(
c
->
db
,
c
->
argv
[
1
]);
addReplySds
(
c
,
sdscatprintf
(
sdsempty
(),
":%d
\r\n
"
,
removed
));
addReplySds
(
c
,
sdscatprintf
(
sdsempty
(),
":%d
\r\n
"
,
removed
));
}
}
...
...
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