Copy and simplify the Linux kernel's interval_tree_generic.h, instantiating for uint64_t. Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
		
			
				
	
	
		
			100 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			100 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* 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 */
 |