1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
int quicklistIndex(const quicklist *quicklist, const long long idx, quicklistEntry *entry) { quicklistNode *n; unsigned long long accum = 0; unsigned long long index; int forward = idx < 0 ? 0 : 1;
initEntry(entry); entry->quicklist = quicklist;
if (!forward) { index = (-idx) - 1; n = quicklist->tail; } else { index = idx; n = quicklist->head; }
if (index >= quicklist->count) return 0;
while (likely(n)) { if ((accum + n->count) > index) { break; } else { D("Skipping over (%p) %u at accum %lld", (void *)n, n->count, accum); accum += n->count; n = forward ? n->next : n->prev; } }
if (!n) return 0;
D("Found node: %p at accum %llu, idx %llu, sub+ %llu, sub- %llu", (void *)n, accum, index, index - accum, (-index) - 1 + accum);
entry->node = n; if (forward) { entry->offset = index - accum; } else {
entry->offset = (-index) - 1 + accum; }
quicklistDecompressNodeForUse(entry->node); entry->zi = ziplistIndex(entry->node->zl, entry->offset); if (!ziplistGet(entry->zi, &entry->value, &entry->sz, &entry->longval)) assert(0);
return 1; }
|