Florin Coras | 672d5fc | 2019-04-15 17:28:51 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2019 Cisco and/or its affiliates. |
| 3 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | * you may not use this file except in compliance with the License. |
| 5 | * You may obtain a copy of the License at: |
| 6 | * |
| 7 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | * |
| 9 | * Unless required by applicable law or agreed to in writing, software |
| 10 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | * See the License for the specific language governing permissions and |
| 13 | * limitations under the License. |
| 14 | */ |
| 15 | |
| 16 | #ifndef SRC_VPPINFRA_RBTREE_H_ |
| 17 | #define SRC_VPPINFRA_RBTREE_H_ |
| 18 | |
| 19 | #include <vppinfra/types.h> |
| 20 | #include <vppinfra/pool.h> |
| 21 | |
| 22 | #define RBTREE_TNIL_INDEX 0 |
| 23 | |
| 24 | typedef u32 rb_node_index_t; |
| 25 | |
| 26 | typedef enum rb_tree_color_ |
| 27 | { |
| 28 | RBTREE_RED, |
| 29 | RBTREE_BLACK |
| 30 | } rb_node_color_t; |
| 31 | |
| 32 | typedef struct rb_node_ |
| 33 | { |
| 34 | u8 color; /**< node color */ |
| 35 | rb_node_index_t parent; /**< parent index */ |
| 36 | rb_node_index_t left; /**< left child index */ |
| 37 | rb_node_index_t right; /**< right child index */ |
| 38 | u32 key; /**< node key */ |
Florin Coras | 4375fa3 | 2019-04-19 15:56:00 -0700 | [diff] [blame] | 39 | uword opaque; /**< value stored by node */ |
Florin Coras | 672d5fc | 2019-04-15 17:28:51 -0700 | [diff] [blame] | 40 | } rb_node_t; |
| 41 | |
| 42 | typedef struct rb_tree_ |
| 43 | { |
| 44 | rb_node_t *nodes; /**< pool of nodes */ |
| 45 | rb_node_index_t root; /**< root index */ |
| 46 | } rb_tree_t; |
| 47 | |
Florin Coras | badf38a | 2019-06-17 11:11:15 -0700 | [diff] [blame] | 48 | typedef int (*rb_tree_lt_fn) (u32 a, u32 b); |
| 49 | |
Florin Coras | 672d5fc | 2019-04-15 17:28:51 -0700 | [diff] [blame] | 50 | void rb_tree_init (rb_tree_t * rt); |
| 51 | rb_node_index_t rb_tree_add (rb_tree_t * rt, u32 key); |
Florin Coras | 4375fa3 | 2019-04-19 15:56:00 -0700 | [diff] [blame] | 52 | rb_node_index_t rb_tree_add2 (rb_tree_t * rt, u32 key, uword opaque); |
Florin Coras | badf38a | 2019-06-17 11:11:15 -0700 | [diff] [blame] | 53 | rb_node_index_t rb_tree_add_custom (rb_tree_t * rt, u32 key, uword opaque, |
| 54 | rb_tree_lt_fn ltfn); |
Florin Coras | 672d5fc | 2019-04-15 17:28:51 -0700 | [diff] [blame] | 55 | void rb_tree_del (rb_tree_t * rt, u32 key); |
Florin Coras | badf38a | 2019-06-17 11:11:15 -0700 | [diff] [blame] | 56 | void rb_tree_del_custom (rb_tree_t * rt, u32 key, rb_tree_lt_fn ltfn); |
Florin Coras | 672d5fc | 2019-04-15 17:28:51 -0700 | [diff] [blame] | 57 | void rb_tree_free_nodes (rb_tree_t * rt); |
| 58 | u32 rb_tree_n_nodes (rb_tree_t * rt); |
| 59 | rb_node_t *rb_tree_min_subtree (rb_tree_t * rt, rb_node_t * x); |
| 60 | rb_node_t *rb_tree_max_subtree (rb_tree_t * rt, rb_node_t * x); |
| 61 | rb_node_t *rb_tree_search_subtree (rb_tree_t * rt, rb_node_t * x, u32 key); |
Florin Coras | badf38a | 2019-06-17 11:11:15 -0700 | [diff] [blame] | 62 | rb_node_t *rb_tree_search_subtree_custom (rb_tree_t * rt, rb_node_t * x, |
| 63 | u32 key, rb_tree_lt_fn ltfn); |
Florin Coras | f7cda7a | 2019-04-19 18:50:34 -0700 | [diff] [blame] | 64 | rb_node_t *rb_tree_successor (rb_tree_t * rt, rb_node_t * x); |
| 65 | rb_node_t *rb_tree_predecessor (rb_tree_t * rt, rb_node_t * x); |
Florin Coras | 672d5fc | 2019-04-15 17:28:51 -0700 | [diff] [blame] | 66 | |
| 67 | static inline rb_node_index_t |
| 68 | rb_node_index (rb_tree_t * rt, rb_node_t * n) |
| 69 | { |
| 70 | return n - rt->nodes; |
| 71 | } |
| 72 | |
| 73 | static inline u8 |
| 74 | rb_node_is_tnil (rb_tree_t * rt, rb_node_t * n) |
| 75 | { |
| 76 | return rb_node_index (rt, n) == RBTREE_TNIL_INDEX; |
| 77 | } |
| 78 | |
| 79 | static inline rb_node_t * |
| 80 | rb_node (rb_tree_t * rt, rb_node_index_t ri) |
| 81 | { |
| 82 | return pool_elt_at_index (rt->nodes, ri); |
| 83 | } |
| 84 | |
Florin Coras | 4375fa3 | 2019-04-19 15:56:00 -0700 | [diff] [blame] | 85 | static inline rb_node_t * |
| 86 | rb_node_right (rb_tree_t * rt, rb_node_t * n) |
| 87 | { |
| 88 | return pool_elt_at_index (rt->nodes, n->right); |
| 89 | } |
| 90 | |
| 91 | static inline rb_node_t * |
| 92 | rb_node_left (rb_tree_t * rt, rb_node_t * n) |
| 93 | { |
| 94 | return pool_elt_at_index (rt->nodes, n->left); |
| 95 | } |
| 96 | |
| 97 | static inline rb_node_t * |
| 98 | rb_node_parent (rb_tree_t * rt, rb_node_t * n) |
| 99 | { |
| 100 | return pool_elt_at_index (rt->nodes, n->parent); |
| 101 | } |
| 102 | |
Florin Coras | 672d5fc | 2019-04-15 17:28:51 -0700 | [diff] [blame] | 103 | #endif /* SRC_VPPINFRA_RBTREE_H_ */ |
| 104 | |
| 105 | /* |
| 106 | * fd.io coding-style-patch-verification: ON |
| 107 | * |
| 108 | * Local Variables: |
| 109 | * eval: (c-set-style "gnu") |
| 110 | * End: |
| 111 | */ |