summaryrefslogtreecommitdiff
path: root/src/t_list.c
diff options
context:
space:
mode:
authorViktor Söderqvist <viktor.soderqvist@est.tech>2021-09-14 16:48:06 +0200
committerGitHub <noreply@github.com>2021-09-14 17:48:06 +0300
commitea36d4de17101f05b03d267a4afbae0f7b33a27c (patch)
treec51e89d23d286f768314a9f9e4a3cdc27c3098c7 /src/t_list.c
parent1376d83363cf0e9c9f872762854518b16d8cedef (diff)
downloadredis-ea36d4de17101f05b03d267a4afbae0f7b33a27c.tar.gz
Modules: Add remaining list API functions (#8439)
List functions operating on elements by index: * RM_ListGet * RM_ListSet * RM_ListInsert * RM_ListDelete Iteration is done using a simple for loop over indices. The index based functions use an internal iterator as an optimization. This is explained in the docs: ``` * Many of the list functions access elements by index. Since a list is in * essence a doubly-linked list, accessing elements by index is generally an * O(N) operation. However, if elements are accessed sequentially or with * indices close together, the functions are optimized to seek the index from * the previous index, rather than seeking from the ends of the list. * * This enables iteration to be done efficiently using a simple for loop: * * long n = RM_ValueLength(key); * for (long i = 0; i < n; i++) { * RedisModuleString *elem = RedisModule_ListGet(key, i); * // Do stuff... * } ```
Diffstat (limited to 'src/t_list.c')
-rw-r--r--src/t_list.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/src/t_list.c b/src/t_list.c
index fb63c1509..80715996e 100644
--- a/src/t_list.c
+++ b/src/t_list.c
@@ -103,6 +103,13 @@ listTypeIterator *listTypeInitIterator(robj *subject, long index,
return li;
}
+/* Sets the direction of an iterator. */
+void listTypeSetIteratorDirection(listTypeIterator *li, unsigned char direction) {
+ li->direction = direction;
+ int dir = direction == LIST_HEAD ? AL_START_TAIL : AL_START_HEAD;
+ quicklistSetDirection(li->iter, dir);
+}
+
/* Clean up the iterator. */
void listTypeReleaseIterator(listTypeIterator *li) {
zfree(li->iter);
@@ -159,6 +166,20 @@ void listTypeInsert(listTypeEntry *entry, robj *value, int where) {
}
}
+/* Replaces entry at the current position of the iterator. */
+void listTypeReplace(listTypeEntry *entry, robj *value) {
+ if (entry->li->encoding == OBJ_ENCODING_QUICKLIST) {
+ value = getDecodedObject(value);
+ sds str = value->ptr;
+ size_t len = sdslen(str);
+ quicklistReplaceEntry((quicklist *)entry->entry.quicklist,
+ &entry->entry, str, len);
+ decrRefCount(value);
+ } else {
+ serverPanic("Unknown list encoding");
+ }
+}
+
/* Compare the given object with the entry at the current position. */
int listTypeEqual(listTypeEntry *entry, robj *o) {
if (entry->li->encoding == OBJ_ENCODING_QUICKLIST) {