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(). */
| 1801 | * to the lexicographically previous element. The 'noup' option has a similar |
| 1802 | * effect to the one of raxIteratorNextStep(). */ |
| 1803 | int raxIteratorPrevStep(raxIterator *it, int noup) { |
| 1804 | if (it->flags & RAX_ITER_EOF) { |
| 1805 | return 1; |
| 1806 | } else if (it->flags & RAX_ITER_JUST_SEEKED) { |
| 1807 | it->flags &= ~RAX_ITER_JUST_SEEKED; |
| 1808 | return 1; |
| 1809 | } |
| 1810 | |
| 1811 | /* Save key len, stack items and the node where we are currently |
| 1812 | * so that on iterator EOF we can restore the current key and state. */ |
| 1813 | size_t orig_key_len = it->key_len; |
| 1814 | size_t orig_stack_items = it->stack.items; |
| 1815 | raxNode *orig_node = it->node; |
| 1816 | int orig_flags = it->flags; |
| 1817 | void *orig_data = it->data; |
| 1818 | int orig_node_child = it->node_child; |
| 1819 | |
| 1820 | if (raxIteratorIsInlineLeaf(it)) { |
| 1821 | raxIteratorClearInlineLeaf(it); |
| 1822 | noup = 1; |
| 1823 | } |
| 1824 | |
| 1825 | while(1) { |
| 1826 | int old_noup = noup; |
| 1827 | |
| 1828 | /* Already on head? Can't go up, iteration finished. */ |
| 1829 | if (!noup && it->node == it->rt->head) { |
| 1830 | it->flags = orig_flags | RAX_ITER_EOF; |
| 1831 | it->stack.items = orig_stack_items; |
| 1832 | it->key_len = orig_key_len; |
| 1833 | it->node = orig_node; |
| 1834 | it->data = orig_data; |
| 1835 | it->node_child = orig_node_child; |
| 1836 | return 1; |
| 1837 | } |
| 1838 | |
| 1839 | unsigned char prevchild = it->key[it->key_len-1]; |
| 1840 | int prevchildidx = it->node_child; |
| 1841 | if (!noup) { |
| 1842 | it->node = raxStackPop(&it->stack); |
| 1843 | it->node_child = -1; |
| 1844 | } else { |
| 1845 | noup = 0; |
| 1846 | } |
| 1847 | |
| 1848 | /* Adjust the current key to represent the node we are |
| 1849 | * at. */ |
| 1850 | int todel = it->node->iscompr ? it->node->size : 1; |
| 1851 | raxIteratorDelChars(it,todel); |
| 1852 | |
| 1853 | /* Try visiting the prev child if there is at least one |
| 1854 | * child. */ |
| 1855 | if (!it->node->iscompr && it->node->size > (old_noup ? 0 : 1)) { |
| 1856 | raxNode **cp; |
| 1857 | int i; |
| 1858 | |
| 1859 | if (prevchildidx != -1) { |
| 1860 | i = prevchildidx-1; |
no test coverage detected