1
0
Fork 0
mirror of https://github.com/dragonflydb/dragonfly.git synced 2024-12-14 11:58:02 +00:00

chore: now it's not needed to allocate quicklistIter on heap (#3814)

This commit is contained in:
Roman Gershman 2024-09-29 12:46:57 +03:00 committed by GitHub
parent 520dea06bf
commit ee2f00de27
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 69 additions and 23 deletions

View file

@ -1276,6 +1276,11 @@ void quicklistReleaseIterator(quicklistIter *iter) {
zfree(iter);
}
// Based on quicklistReleaseIterator
void quicklistCompressIterator(quicklistIter* iter) {
if (iter->current) quicklistCompress(iter->quicklist, iter->current);
}
/* Get next element in iterator.
*
* Note: You must NOT insert into the list while iterating over it.

View file

@ -5,6 +5,7 @@
#include "crc64.h"
#include "endianconv.h"
#include "quicklist.h"
#include "zmalloc.h"
Server server;
@ -67,4 +68,56 @@ void memrev64(void* p) {
uint64_t intrev64(uint64_t v) {
memrev64(&v);
return v;
}
// Based on quicklistGetIteratorAtIdx but without allocations
void quicklistInitIterator(quicklistIter* iter, quicklist *quicklist, int direction,
const long long idx) {
quicklistNode *n = NULL;
unsigned long long accum = 0;
int forward = idx < 0 ? 0 : 1; /* < 0 -> reverse, 0+ -> forward */
unsigned long long index = forward ? idx : (-idx) - 1;
iter->direction = direction;
iter->quicklist = quicklist;
iter->current = NULL;
iter->zi = NULL;
if (index >= quicklist->count) return;
/* Seek in the other direction if that way is shorter. */
int seek_forward = forward;
unsigned long long seek_index = index;
if (index > (quicklist->count - 1) / 2) {
seek_forward = !forward;
seek_index = quicklist->count - 1 - index;
}
n = seek_forward ? quicklist->head : quicklist->tail;
while (likely(n)) {
if ((accum + n->count) > seek_index) {
break;
} else {
accum += n->count;
n = seek_forward ? n->next : n->prev;
}
}
if (!n)
return;
iter->current = n;
/* Fix accum so it looks like we seeked in the other direction. */
if (seek_forward != forward)
accum = quicklist->count - n->count - accum;
if (forward) {
/* forward = normal head-to-tail offset. */
iter->offset = index - accum;
} else {
/* reverse = need negative offset for tail-to-head, so undo
* the result of the original index = (-idx) - 1 above. */
iter->offset = (-index) - 1 + accum;
}
}

View file

@ -14,25 +14,6 @@
#define CONFIG_RUN_ID_SIZE 40U
/* To improve the quality of the LRU approximation we take a set of keys
* that are good candidate for eviction across performEvictions() calls.
*
* Entries inside the eviction pool are taken ordered by idle time, putting
* greater idle times to the right (ascending order).
*
* When an LFU policy is used instead, a reverse frequency indication is used
* instead of the idle time, so that we still evict by larger value (larger
* inverse frequency means to evict keys with the least frequent accesses).
*
* Empty entries have the key pointer set to NULL. */
typedef struct dict dict;
uint64_t dictSdsHash(const void* key);
int dictSdsKeyCompare(dict* privdata, const void* key1, const void* key2);
void dictSdsDestructor(dict* privdata, void* val);
size_t sdsZmallocSize(sds s);
typedef struct ServerStub {
size_t max_map_field_len, max_listpack_map_bytes;
@ -76,4 +57,10 @@ const char *strEncoding(int encoding);
#define OBJ_ENCODING_LISTPACK 11 /* Encoded as a listpack */
#define OBJ_ENCODING_COMPRESS_INTERNAL 15U /* Kept as lzf compressed, to pass compressed blob to another thread */
typedef struct quicklistIter quicklistIter;
typedef struct quicklist quicklist;
void quicklistInitIterator(quicklistIter* iter, quicklist *quicklist, int direction, const long long idx);
void quicklistCompressIterator(quicklistIter* iter);
#endif /* __REDIS_AUX_H */

View file

@ -543,14 +543,15 @@ OpResult<uint32_t> OpRem(const OpArgs& op_args, string_view key, string_view ele
index = -1;
}
quicklistIter* qiter = quicklistGetIteratorAtIdx(ql, iter_direction, index);
quicklistIter qiter;
quicklistInitIterator(&qiter, ql, iter_direction, index);
quicklistEntry entry;
unsigned removed = 0;
const uint8_t* elem_ptr = reinterpret_cast<const uint8_t*>(elem.data());
while (quicklistNext(qiter, &entry)) {
while (quicklistNext(&qiter, &entry)) {
if (quicklistCompare(&entry, elem_ptr, elem.size())) {
quicklistDelEntry(qiter, &entry);
quicklistDelEntry(&qiter, &entry);
removed++;
if (count && removed == count)
break;
@ -559,7 +560,7 @@ OpResult<uint32_t> OpRem(const OpArgs& op_args, string_view key, string_view ele
it_res->post_updater.Run();
quicklistReleaseIterator(qiter);
quicklistCompressIterator(&qiter);
if (quicklistCount(ql) == 0) {
CHECK(db_slice.Del(op_args.db_cntx, it));