rbtree: Add equal nodes to linked list
Signed-off-by: Robert Baldyga <robert.baldyga@intel.com>
This commit is contained in:
parent
50c4de0495
commit
0ae4f4b5b2
@ -134,8 +134,11 @@ void ocf_rb_tree_insert(struct ocf_rb_tree *tree, struct ocf_rb_node *node)
|
|||||||
struct ocf_rb_node *iter, *new_iter;
|
struct ocf_rb_node *iter, *new_iter;
|
||||||
int cmp;
|
int cmp;
|
||||||
|
|
||||||
|
INIT_LIST_HEAD(&node->list);
|
||||||
|
|
||||||
node->left = NULL;
|
node->left = NULL;
|
||||||
node->right = NULL;
|
node->right = NULL;
|
||||||
|
node->parent = NULL;
|
||||||
|
|
||||||
if (!tree->root) {
|
if (!tree->root) {
|
||||||
node->red = false;
|
node->red = false;
|
||||||
@ -147,9 +150,16 @@ void ocf_rb_tree_insert(struct ocf_rb_tree *tree, struct ocf_rb_node *node)
|
|||||||
for (new_iter = tree->root; new_iter;) {
|
for (new_iter = tree->root; new_iter;) {
|
||||||
iter = new_iter;
|
iter = new_iter;
|
||||||
cmp = tree->cmp(node, iter);
|
cmp = tree->cmp(node, iter);
|
||||||
|
if (cmp == 0)
|
||||||
|
break;
|
||||||
new_iter = (cmp < 0) ? iter->left : iter->right;
|
new_iter = (cmp < 0) ? iter->left : iter->right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cmp == 0) {
|
||||||
|
list_add_tail(&node->list, &iter->list);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
node->red = true;
|
node->red = true;
|
||||||
node->parent = iter;
|
node->parent = iter;
|
||||||
if (cmp < 0)
|
if (cmp < 0)
|
||||||
@ -330,7 +340,22 @@ void ocf_rb_tree_fix_double_black(struct ocf_rb_tree *tree,
|
|||||||
|
|
||||||
void ocf_rb_tree_remove(struct ocf_rb_tree *tree, struct ocf_rb_node *node)
|
void ocf_rb_tree_remove(struct ocf_rb_tree *tree, struct ocf_rb_node *node)
|
||||||
{
|
{
|
||||||
struct ocf_rb_node *sibling, *rep;
|
struct ocf_rb_node *sibling, *rep, *next;
|
||||||
|
|
||||||
|
if (!list_empty(&node->list)) {
|
||||||
|
/* Node list is not empty */
|
||||||
|
if (!node->parent && node != tree->root) {
|
||||||
|
/* Node is in the middle of the list -> just remove */
|
||||||
|
list_del(&node->list);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Node is at head of the list -> need to make new head */
|
||||||
|
next = list_first_entry(&node->list, struct ocf_rb_node, list);
|
||||||
|
ocf_rb_tree_swap(tree, node, next);
|
||||||
|
list_del(&node->list);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
sibling = ocf_rb_tree_sibling(node);
|
sibling = ocf_rb_tree_sibling(node);
|
||||||
@ -375,6 +400,9 @@ bool ocf_rb_tree_can_update(struct ocf_rb_tree *tree,
|
|||||||
struct ocf_rb_node *iter = tree->root;
|
struct ocf_rb_node *iter = tree->root;
|
||||||
int cmp = 0;
|
int cmp = 0;
|
||||||
|
|
||||||
|
if (!list_empty(&node->list))
|
||||||
|
return false;
|
||||||
|
|
||||||
while (iter) {
|
while (iter) {
|
||||||
if (iter == node)
|
if (iter == node)
|
||||||
break;
|
break;
|
||||||
|
@ -13,6 +13,7 @@ struct ocf_rb_node {
|
|||||||
struct ocf_rb_node *left;
|
struct ocf_rb_node *left;
|
||||||
struct ocf_rb_node *right;
|
struct ocf_rb_node *right;
|
||||||
struct ocf_rb_node *parent;
|
struct ocf_rb_node *parent;
|
||||||
|
struct list_head list;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int (*ocf_rb_tree_node_cmp_cb)(struct ocf_rb_node *n1,
|
typedef int (*ocf_rb_tree_node_cmp_cb)(struct ocf_rb_node *n1,
|
||||||
|
Loading…
Reference in New Issue
Block a user