Return the pointer-to-pointer in the tree that references the element * currently selected by the iterator. For regular key nodes this is the * parent link (or the tree head itself). For inline leaves it is the child * slot inside the parent node holding the raw value pointer. */
| 1601 | * parent link (or the tree head itself). For inline leaves it is the child |
| 1602 | * slot inside the parent node holding the raw value pointer. */ |
| 1603 | static raxNode **raxIteratorCurrentParentLink(raxIterator *it, raxNode **parent) { |
| 1604 | raxNode *p; |
| 1605 | raxNode **cp; |
| 1606 | int childidx, numchildren; |
| 1607 | |
| 1608 | if (raxIteratorIsInlineLeaf(it)) { |
| 1609 | p = it->node; |
| 1610 | if (p == NULL) return NULL; |
| 1611 | numchildren = p->iscompr ? 1 : p->size; |
| 1612 | childidx = it->node_child; |
| 1613 | if (childidx < 0 || childidx >= numchildren || |
| 1614 | !raxIsInlineLeaf(p,childidx)) |
| 1615 | { |
| 1616 | if (p->iscompr) { |
| 1617 | childidx = 0; |
| 1618 | } else { |
| 1619 | if (it->key_len == 0) return NULL; |
| 1620 | unsigned char c = it->key[it->key_len-1]; |
| 1621 | for (childidx = 0; childidx < numchildren; childidx++) { |
| 1622 | if (p->data[childidx] == c && raxIsInlineLeaf(p,childidx)) |
| 1623 | break; |
| 1624 | } |
| 1625 | if (childidx == numchildren) return NULL; |
| 1626 | } |
| 1627 | it->node_child = childidx; |
| 1628 | } |
| 1629 | if (parent) *parent = p; |
| 1630 | return raxNodeFirstChildPtr(p)+childidx; |
| 1631 | } |
| 1632 | |
| 1633 | if (it->node == NULL) return NULL; |
| 1634 | if (it->node == it->rt->head) { |
| 1635 | if (parent) *parent = NULL; |
| 1636 | return &it->rt->head; |
| 1637 | } |
| 1638 | |
| 1639 | p = raxStackPeek(&it->stack); |
| 1640 | if (p == NULL) return NULL; |
| 1641 | cp = raxNodeFirstChildPtr(p); |
| 1642 | numchildren = p->iscompr ? 1 : p->size; |
| 1643 | childidx = it->node_child; |
| 1644 | |
| 1645 | if (childidx >= 0 && childidx < numchildren) { |
| 1646 | raxNode *child; |
| 1647 | memcpy(&child,cp+childidx,sizeof(child)); |
| 1648 | if (child == it->node) { |
| 1649 | if (parent) *parent = p; |
| 1650 | return cp+childidx; |
| 1651 | } |
| 1652 | } |
| 1653 | |
| 1654 | for (childidx = 0; childidx < numchildren; childidx++) { |
| 1655 | raxNode *child; |
| 1656 | memcpy(&child,cp+childidx,sizeof(child)); |
| 1657 | if (child == it->node) { |
| 1658 | it->node_child = childidx; |
| 1659 | if (parent) *parent = p; |
| 1660 | return cp+childidx; |
no test coverage detected