Bug 1403444 - Expand rb_search and rb_nsearch. r=njn

At the same time, simplify the expanded code to better fit in the
template.

--HG--
extra : rebase_source : d68bce212b04b927e32d360b0d606692a336598a
This commit is contained in:
Mike Hommey 2017-09-26 16:46:43 +09:00
Родитель 28b7741df7
Коммит d4ac54ef7d
1 изменённых файлов: 24 добавлений и 48 удалений

Просмотреть файл

@ -149,49 +149,6 @@ public:
} \ } \
} while (0) } while (0)
#define rb_search(a_type, a_field, a_cmp, a_tree, a_key, r_node) \
do { \
int rbp_se_cmp; \
(r_node) = (a_tree)->rbt_root; \
while ((r_node) != &(a_tree)->rbt_nil && \
(rbp_se_cmp = (a_cmp)((a_key), (r_node))) != 0) { \
if (rbp_se_cmp < 0) { \
(r_node) = a_field(r_node).Left(); \
} else { \
(r_node) = a_field(r_node).Right(); \
} \
} \
if ((r_node) == &(a_tree)->rbt_nil) { \
(r_node) = nullptr; \
} \
} while (0)
/*
* Find a match if it exists. Otherwise, find the next greater node, if one
* exists.
*/
#define rb_nsearch(a_type, a_field, a_cmp, a_tree, a_key, r_node) \
do { \
a_type* rbp_ns_t = (a_tree)->rbt_root; \
(r_node) = nullptr; \
while (rbp_ns_t != &(a_tree)->rbt_nil) { \
int rbp_ns_cmp = (a_cmp)((a_key), rbp_ns_t); \
if (rbp_ns_cmp < 0) { \
(r_node) = rbp_ns_t; \
rbp_ns_t = a_field(rbp_ns_t).Left(); \
} else if (rbp_ns_cmp > 0) { \
rbp_ns_t = a_field(rbp_ns_t).Right(); \
} else { \
(r_node) = rbp_ns_t; \
break; \
} \
} \
} while (0)
/*
* Find a match if it exists. Otherwise, find the previous lesser node, if one
* exists.
*/
#define rbp_rotate_left(a_type, a_field, a_node, r_node) \ #define rbp_rotate_left(a_type, a_field, a_node, r_node) \
do { \ do { \
(r_node) = a_field(a_node).Right(); \ (r_node) = a_field(a_node).Right(); \
@ -626,17 +583,36 @@ struct RedBlackTree
T* Search(T* aKey) T* Search(T* aKey)
{ {
T* ret; T* ret = rbt_root;
rb_search(T, Trait::GetTreeNode, Trait::Compare, this, aKey, ret); int rbp_se_cmp;
return ret; while (ret != &rbt_nil && (rbp_se_cmp = Trait::Compare(aKey, ret)) != 0) {
if (rbp_se_cmp < 0) {
ret = Trait::GetTreeNode(ret).Left();
} else {
ret = Trait::GetTreeNode(ret).Right();
}
}
return (ret == &rbt_nil) ? nullptr : ret;
} }
/* Find a match if it exists. Otherwise, find the next greater node, if one /* Find a match if it exists. Otherwise, find the next greater node, if one
* exists */ * exists */
T* SearchOrNext(T* aKey) T* SearchOrNext(T* aKey)
{ {
T* ret; T* ret = nullptr;
rb_nsearch(T, Trait::GetTreeNode, Trait::Compare, this, aKey, ret); T* rbp_ns_t = rbt_root;
while (rbp_ns_t != &rbt_nil) {
int rbp_ns_cmp = Trait::Compare(aKey, rbp_ns_t);
if (rbp_ns_cmp < 0) {
ret = rbp_ns_t;
rbp_ns_t = Trait::GetTreeNode(rbp_ns_t).Left();
} else if (rbp_ns_cmp > 0) {
rbp_ns_t = Trait::GetTreeNode(rbp_ns_t).Right();
} else {
ret = rbp_ns_t;
break;
}
}
return ret; return ret;
} }