MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / raxIteratorPrevStep

Function raxIteratorPrevStep

src/rax.c:1433–1504  ·  view source on GitHub ↗

Like raxIteratorNextStep() but implements an iteration step moving * to the lexicographically previous element. The 'noup' option has a similar * effect to the one of raxIteratorNextStep(). */

Source from the content-addressed store, hash-verified

1431 * to the lexicographically previous element. The 'noup' option has a similar
1432 * effect to the one of raxIteratorNextStep(). */
1433int raxIteratorPrevStep(raxIterator *it, int noup) {
1434 if (it->flags & RAX_ITER_EOF) {
1435 return 1;
1436 } else if (it->flags & RAX_ITER_JUST_SEEKED) {
1437 it->flags &= ~RAX_ITER_JUST_SEEKED;
1438 return 1;
1439 }
1440
1441 /* Save key len, stack items and the node where we are currently
1442 * so that on iterator EOF we can restore the current key and state. */
1443 size_t orig_key_len = it->key_len;
1444 size_t orig_stack_items = it->stack.items;
1445 raxNode *orig_node = it->node;
1446
1447 while(1) {
1448 int old_noup = noup;
1449
1450 /* Already on head? Can't go up, iteration finished. */
1451 if (!noup && it->node == it->rt->head) {
1452 it->flags |= RAX_ITER_EOF;
1453 it->stack.items = orig_stack_items;
1454 it->key_len = orig_key_len;
1455 it->node = orig_node;
1456 return 1;
1457 }
1458
1459 unsigned char prevchild = it->key[it->key_len-1];
1460 if (!noup) {
1461 it->node = raxStackPop(&it->stack);
1462 } else {
1463 noup = 0;
1464 }
1465
1466 /* Adjust the current key to represent the node we are
1467 * at. */
1468 int todel = it->node->iscompr ? it->node->size : 1;
1469 raxIteratorDelChars(it,todel);
1470
1471 /* Try visiting the prev child if there is at least one
1472 * child. */
1473 if (!it->node->iscompr && it->node->size > (old_noup ? 0 : 1)) {
1474 raxNode **cp = raxNodeLastChildPtr(it->node);
1475 int i = it->node->size-1;
1476 while (i >= 0) {
1477 debugf("SCAN PREV %c\n", it->node->data[i]);
1478 if (it->node->data[i] < prevchild) break;
1479 i--;
1480 cp--;
1481 }
1482 /* If we found a new subtree to explore in this node,
1483 * go deeper following all the last children in order to
1484 * find the key lexicographically greater. */
1485 if (i != -1) {
1486 debugf("SCAN found a new node\n");
1487 /* Enter the node we just found. */
1488 if (!raxIteratorAddChars(it,it->node->data+i,1)) return 0;
1489 if (!raxStackPush(&it->stack,it->node)) return 0;
1490 memcpy(&it->node,cp,sizeof(it->node));

Callers 2

raxSeekFunction · 0.85
raxPrevFunction · 0.85

Calls 6

raxStackPopFunction · 0.85
raxIteratorDelCharsFunction · 0.85
raxIteratorAddCharsFunction · 0.85
raxStackPushFunction · 0.85
raxSeekGreatestFunction · 0.85
raxGetDataFunction · 0.85

Tested by

no test coverage detected