| /* SPDX-License-Identifier: GPL-2.0-or-later */ |
| /* |
| * Interval trees. |
| * |
| * Derived from include/linux/interval_tree.h and its dependencies. |
| */ |
| |
| #ifndef QEMU_INTERVAL_TREE_H |
| #define QEMU_INTERVAL_TREE_H |
| |
| /* |
| * For now, don't expose Linux Red-Black Trees separately, but retain the |
| * separate type definitions to keep the implementation sane, and allow |
| * the possibility of disentangling them later. |
| */ |
| typedef struct RBNode |
| { |
| /* Encodes parent with color in the lsb. */ |
| uintptr_t rb_parent_color; |
| struct RBNode *rb_right; |
| struct RBNode *rb_left; |
| } RBNode; |
| |
| typedef struct RBRoot |
| { |
| RBNode *rb_node; |
| } RBRoot; |
| |
| typedef struct RBRootLeftCached { |
| RBRoot rb_root; |
| RBNode *rb_leftmost; |
| } RBRootLeftCached; |
| |
| typedef struct IntervalTreeNode |
| { |
| RBNode rb; |
| |
| uint64_t start; /* Start of interval */ |
| uint64_t last; /* Last location _in_ interval */ |
| uint64_t subtree_last; |
| } IntervalTreeNode; |
| |
| typedef RBRootLeftCached IntervalTreeRoot; |
| |
| /** |
| * interval_tree_is_empty |
| * @root: root of the tree. |
| * |
| * Returns true if the tree contains no nodes. |
| */ |
| static inline bool interval_tree_is_empty(const IntervalTreeRoot *root) |
| { |
| return root->rb_root.rb_node == NULL; |
| } |
| |
| /** |
| * interval_tree_insert |
| * @node: node to insert, |
| * @root: root of the tree. |
| * |
| * Insert @node into @root, and rebalance. |
| */ |
| void interval_tree_insert(IntervalTreeNode *node, IntervalTreeRoot *root); |
| |
| /** |
| * interval_tree_remove |
| * @node: node to remove, |
| * @root: root of the tree. |
| * |
| * Remove @node from @root, and rebalance. |
| */ |
| void interval_tree_remove(IntervalTreeNode *node, IntervalTreeRoot *root); |
| |
| /** |
| * interval_tree_iter_first: |
| * @root: root of the tree, |
| * @start, @last: the inclusive interval [start, last]. |
| * |
| * Locate the "first" of a set of nodes within the tree at @root |
| * that overlap the interval, where "first" is sorted by start. |
| * Returns NULL if no overlap found. |
| */ |
| IntervalTreeNode *interval_tree_iter_first(IntervalTreeRoot *root, |
| uint64_t start, uint64_t last); |
| |
| /** |
| * interval_tree_iter_next: |
| * @node: previous search result |
| * @start, @last: the inclusive interval [start, last]. |
| * |
| * Locate the "next" of a set of nodes within the tree that overlap the |
| * interval; @next is the result of a previous call to |
| * interval_tree_iter_{first,next}. Returns NULL if @next was the last |
| * node in the set. |
| */ |
| IntervalTreeNode *interval_tree_iter_next(IntervalTreeNode *node, |
| uint64_t start, uint64_t last); |
| |
| #endif /* QEMU_INTERVAL_TREE_H */ |