diff --git a/src/ocf_seq_cutoff.c b/src/ocf_seq_cutoff.c index 55c4999..c34bb6d 100644 --- a/src/ocf_seq_cutoff.c +++ b/src/ocf_seq_cutoff.c @@ -52,7 +52,7 @@ void ocf_core_seq_cutoff_init(ocf_core_t core) ocf_core_log(core, log_info, "Seqential cutoff init\n"); env_rwlock_init(&core->seq_cutoff.lock); - ocf_rb_tree_init(&core->seq_cutoff.tree, ocf_seq_cutoff_stream_cmp); + ocf_rb_tree_init(&core->seq_cutoff.tree, ocf_seq_cutoff_stream_cmp, NULL); INIT_LIST_HEAD(&core->seq_cutoff.lru); for (i = 0; i < OCF_SEQ_CUTOFF_MAX_STREAMS; i++) { diff --git a/src/utils/utils_rbtree.c b/src/utils/utils_rbtree.c index 727811a..e4ce67f 100644 --- a/src/utils/utils_rbtree.c +++ b/src/utils/utils_rbtree.c @@ -5,10 +5,15 @@ #include "utils_rbtree.h" -void ocf_rb_tree_init(struct ocf_rb_tree *tree, ocf_rb_tree_node_cmp_cb cmp) +static struct ocf_rb_node *ocf_rb_tree_list_find_first( + struct ocf_rb_node_list *node_list); + +void ocf_rb_tree_init(struct ocf_rb_tree *tree, ocf_rb_tree_node_cmp_cb cmp, + ocf_rb_tree_list_find_cb find) { tree->root = NULL; tree->cmp = cmp; + tree->find = find ?: ocf_rb_tree_list_find_first; } static void ocf_rb_tree_update_parent(struct ocf_rb_tree *tree, @@ -435,10 +440,22 @@ bool ocf_rb_tree_can_update(struct ocf_rb_tree *tree, return true; } +static struct ocf_rb_node *ocf_rb_tree_list_find_first( + struct ocf_rb_node_list *node_list) +{ + struct ocf_rb_node *node; + + ocf_rb_list_for_each_node(node_list, node) + return node; + + return NULL; +} + struct ocf_rb_node *ocf_rb_tree_find(struct ocf_rb_tree *tree, struct ocf_rb_node *node) { struct ocf_rb_node *iter = tree->root; + struct ocf_rb_node_list node_list; int cmp = 0; while (iter) { @@ -449,5 +466,11 @@ struct ocf_rb_node *ocf_rb_tree_find(struct ocf_rb_tree *tree, iter = (cmp < 0) ? iter->left : iter->right; } + if (!iter || list_empty(&iter->list)) + return iter; + + list_add_tail(&node_list.list, &iter->list); + iter = tree->find(&node_list); + list_del(&node_list.list); return iter; } diff --git a/src/utils/utils_rbtree.h b/src/utils/utils_rbtree.h index 04a99d0..61fcb34 100644 --- a/src/utils/utils_rbtree.h +++ b/src/utils/utils_rbtree.h @@ -16,15 +16,27 @@ struct ocf_rb_node { struct list_head list; }; +struct ocf_rb_node_list { + struct list_head list; +}; + +#define ocf_rb_list_for_each_node(node_list, node) \ + list_for_each_entry(node, &node_list->list, list) + typedef int (*ocf_rb_tree_node_cmp_cb)(struct ocf_rb_node *n1, struct ocf_rb_node *n2); +typedef struct ocf_rb_node *(*ocf_rb_tree_list_find_cb)( + struct ocf_rb_node_list *node_list); + struct ocf_rb_tree { struct ocf_rb_node *root; ocf_rb_tree_node_cmp_cb cmp; + ocf_rb_tree_list_find_cb find; }; -void ocf_rb_tree_init(struct ocf_rb_tree *tree, ocf_rb_tree_node_cmp_cb cmp); +void ocf_rb_tree_init(struct ocf_rb_tree *tree, ocf_rb_tree_node_cmp_cb cmp, + ocf_rb_tree_list_find_cb find); void ocf_rb_tree_insert(struct ocf_rb_tree *tree, struct ocf_rb_node *node); diff --git a/tests/unit/tests/utils/utils_rbtree.c/utils_rbtree.c b/tests/unit/tests/utils/utils_rbtree.c/utils_rbtree.c index dae23fe..8abeebe 100644 --- a/tests/unit/tests/utils/utils_rbtree.c/utils_rbtree.c +++ b/tests/unit/tests/utils/utils_rbtree.c/utils_rbtree.c @@ -77,7 +77,7 @@ void prepare(struct ocf_rb_tree *tree) { int i; - ocf_rb_tree_init(tree, test_cmp); + ocf_rb_tree_init(tree, test_cmp, NULL); for (i = 0; i < nodes_number; i++) ocf_rb_tree_insert(tree, &nodes[i].tree);