diff options
author | Viktor Söderqvist <viktor.soderqvist@est.tech> | 2021-09-14 16:48:06 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-14 17:48:06 +0300 |
commit | ea36d4de17101f05b03d267a4afbae0f7b33a27c (patch) | |
tree | c51e89d23d286f768314a9f9e4a3cdc27c3098c7 /src/t_list.c | |
parent | 1376d83363cf0e9c9f872762854518b16d8cedef (diff) | |
download | redis-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.c | 21 |
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) { |