mirror of
https://github.com/radareorg/radare2.git
synced 2025-02-25 08:43:16 +00:00
Implement r_rbtree_cont_node_prev (siol eternal) ##util
This commit is contained in:
parent
a3e3b5af7c
commit
3f96c6fda6
@ -112,6 +112,7 @@ R_API bool r_rbtree_cont_insert(RContRBTree *tree, void *data, RContRBCmp cmp, v
|
||||
R_API bool r_rbtree_cont_delete(RContRBTree *tree, void *data, RContRBCmp cmp, void *user);
|
||||
R_API RContRBNode *r_rbtree_cont_find_node(RContRBTree *tree, void *data, RContRBCmp cmp, void *user);
|
||||
R_API RContRBNode *r_rbtree_cont_node_next(RContRBNode *node);
|
||||
R_API RContRBNode *r_rbtree_cont_node_prev(RContRBNode *node);
|
||||
R_API void *r_rbtree_cont_find(RContRBTree *tree, void *data, RContRBCmp cmp, void *user);
|
||||
R_API void *r_rbtree_cont_first(RContRBTree *tree);
|
||||
R_API void *r_rbtree_cont_last(RContRBTree *tree);
|
||||
|
@ -540,6 +540,33 @@ R_API RContRBNode *r_rbtree_cont_node_next(RContRBNode *node) {
|
||||
return (container_of (parent, RContRBNode, node));
|
||||
}
|
||||
|
||||
R_API RContRBNode *r_rbtree_cont_node_prev(RContRBNode *node) {
|
||||
r_return_val_if_fail (node, NULL);
|
||||
RBNode *_node = &node->node;
|
||||
if (_node->child[0]) {
|
||||
_node = _node->child[0];
|
||||
// next node is the most right child-node of the left subtree
|
||||
// rightsided walk down that subtree until there is no more right child
|
||||
while (_node->child[1]) {
|
||||
_node = _node->child[1];
|
||||
}
|
||||
return (container_of (_node, RContRBNode, node));
|
||||
}
|
||||
RBNode *parent = _node->parent;
|
||||
if (!parent) {
|
||||
return NULL;
|
||||
}
|
||||
// walk up the tree, until _node is no longer left child of it's parent
|
||||
while (parent->child[0] == _node) {
|
||||
_node = parent;
|
||||
parent = _node->parent;
|
||||
if (!parent) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return (container_of (parent, RContRBNode, node));
|
||||
}
|
||||
|
||||
// not a direct pendant to r_rbtree_first, but similar
|
||||
// returns first element in the tree, not an iter or a node
|
||||
R_API void *r_rbtree_cont_first(RContRBTree *tree) {
|
||||
|
@ -94,11 +94,35 @@ bool test_r_rbtree_cont_node_next() {
|
||||
}
|
||||
mu_assert ("rbtree_cont_node_next", ret);
|
||||
mu_end;
|
||||
}
|
||||
}
|
||||
|
||||
bool test_r_rbtree_cont_node_prev() {
|
||||
RContRBTree *tree = r_rbtree_cont_new ();
|
||||
ut32 i;
|
||||
for (i = 0; i < 100; i++) {
|
||||
ut32 v = (ut32)r_num_rand (UT32_MAX >> 1);
|
||||
r_rbtree_cont_insert (tree, (void *)(size_t)v, simple_cmp, NULL);
|
||||
}
|
||||
bool ret = true;
|
||||
void *v = r_rbtree_cont_last (tree);
|
||||
RContRBNode *node = r_rbtree_cont_find_node (tree, v, simple_cmp, NULL);
|
||||
i = (ut32)(size_t)v;
|
||||
node = r_rbtree_cont_node_prev (node);
|
||||
mu_assert ("rbtree_cont_node_prev no node befor last", !!node);
|
||||
while (node) {
|
||||
const ut32 prev = (ut32)(size_t)node->data;
|
||||
ret &= (i >= prev);
|
||||
i = prev;
|
||||
node = r_rbtree_cont_node_prev (node);
|
||||
}
|
||||
mu_assert ("rbtree_cont_node_prev", ret);
|
||||
mu_end;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
mu_run_test (test_r_rbtree_cont_insert);
|
||||
mu_run_test (test_r_rbtree_cont_delete);
|
||||
mu_run_test (test_r_rbtree_cont_node_next);
|
||||
mu_run_test (test_r_rbtree_cont_node_prev);
|
||||
return tests_run != tests_passed;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user