162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci  Red Black Trees
462306a36Sopenharmony_ci  (C) 1999  Andrea Arcangeli <andrea@suse.de>
562306a36Sopenharmony_ci  (C) 2002  David Woodhouse <dwmw2@infradead.org>
662306a36Sopenharmony_ci  (C) 2012  Michel Lespinasse <walken@google.com>
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci  linux/include/linux/rbtree_augmented.h
1062306a36Sopenharmony_ci*/
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#ifndef _LINUX_RBTREE_AUGMENTED_H
1362306a36Sopenharmony_ci#define _LINUX_RBTREE_AUGMENTED_H
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include <linux/compiler.h>
1662306a36Sopenharmony_ci#include <linux/rbtree.h>
1762306a36Sopenharmony_ci#include <linux/rcupdate.h>
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci/*
2062306a36Sopenharmony_ci * Please note - only struct rb_augment_callbacks and the prototypes for
2162306a36Sopenharmony_ci * rb_insert_augmented() and rb_erase_augmented() are intended to be public.
2262306a36Sopenharmony_ci * The rest are implementation details you are not expected to depend on.
2362306a36Sopenharmony_ci *
2462306a36Sopenharmony_ci * See Documentation/core-api/rbtree.rst for documentation and samples.
2562306a36Sopenharmony_ci */
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_cistruct rb_augment_callbacks {
2862306a36Sopenharmony_ci	void (*propagate)(struct rb_node *node, struct rb_node *stop);
2962306a36Sopenharmony_ci	void (*copy)(struct rb_node *old, struct rb_node *new);
3062306a36Sopenharmony_ci	void (*rotate)(struct rb_node *old, struct rb_node *new);
3162306a36Sopenharmony_ci};
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ciextern void __rb_insert_augmented(struct rb_node *node, struct rb_root *root,
3462306a36Sopenharmony_ci	void (*augment_rotate)(struct rb_node *old, struct rb_node *new));
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci/*
3762306a36Sopenharmony_ci * Fixup the rbtree and update the augmented information when rebalancing.
3862306a36Sopenharmony_ci *
3962306a36Sopenharmony_ci * On insertion, the user must update the augmented information on the path
4062306a36Sopenharmony_ci * leading to the inserted node, then call rb_link_node() as usual and
4162306a36Sopenharmony_ci * rb_insert_augmented() instead of the usual rb_insert_color() call.
4262306a36Sopenharmony_ci * If rb_insert_augmented() rebalances the rbtree, it will callback into
4362306a36Sopenharmony_ci * a user provided function to update the augmented information on the
4462306a36Sopenharmony_ci * affected subtrees.
4562306a36Sopenharmony_ci */
4662306a36Sopenharmony_cistatic inline void
4762306a36Sopenharmony_cirb_insert_augmented(struct rb_node *node, struct rb_root *root,
4862306a36Sopenharmony_ci		    const struct rb_augment_callbacks *augment)
4962306a36Sopenharmony_ci{
5062306a36Sopenharmony_ci	__rb_insert_augmented(node, root, augment->rotate);
5162306a36Sopenharmony_ci}
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_cistatic inline void
5462306a36Sopenharmony_cirb_insert_augmented_cached(struct rb_node *node,
5562306a36Sopenharmony_ci			   struct rb_root_cached *root, bool newleft,
5662306a36Sopenharmony_ci			   const struct rb_augment_callbacks *augment)
5762306a36Sopenharmony_ci{
5862306a36Sopenharmony_ci	if (newleft)
5962306a36Sopenharmony_ci		root->rb_leftmost = node;
6062306a36Sopenharmony_ci	rb_insert_augmented(node, &root->rb_root, augment);
6162306a36Sopenharmony_ci}
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_cistatic __always_inline struct rb_node *
6462306a36Sopenharmony_cirb_add_augmented_cached(struct rb_node *node, struct rb_root_cached *tree,
6562306a36Sopenharmony_ci			bool (*less)(struct rb_node *, const struct rb_node *),
6662306a36Sopenharmony_ci			const struct rb_augment_callbacks *augment)
6762306a36Sopenharmony_ci{
6862306a36Sopenharmony_ci	struct rb_node **link = &tree->rb_root.rb_node;
6962306a36Sopenharmony_ci	struct rb_node *parent = NULL;
7062306a36Sopenharmony_ci	bool leftmost = true;
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci	while (*link) {
7362306a36Sopenharmony_ci		parent = *link;
7462306a36Sopenharmony_ci		if (less(node, parent)) {
7562306a36Sopenharmony_ci			link = &parent->rb_left;
7662306a36Sopenharmony_ci		} else {
7762306a36Sopenharmony_ci			link = &parent->rb_right;
7862306a36Sopenharmony_ci			leftmost = false;
7962306a36Sopenharmony_ci		}
8062306a36Sopenharmony_ci	}
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci	rb_link_node(node, parent, link);
8362306a36Sopenharmony_ci	augment->propagate(parent, NULL); /* suboptimal */
8462306a36Sopenharmony_ci	rb_insert_augmented_cached(node, tree, leftmost, augment);
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci	return leftmost ? node : NULL;
8762306a36Sopenharmony_ci}
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci/*
9062306a36Sopenharmony_ci * Template for declaring augmented rbtree callbacks (generic case)
9162306a36Sopenharmony_ci *
9262306a36Sopenharmony_ci * RBSTATIC:    'static' or empty
9362306a36Sopenharmony_ci * RBNAME:      name of the rb_augment_callbacks structure
9462306a36Sopenharmony_ci * RBSTRUCT:    struct type of the tree nodes
9562306a36Sopenharmony_ci * RBFIELD:     name of struct rb_node field within RBSTRUCT
9662306a36Sopenharmony_ci * RBAUGMENTED: name of field within RBSTRUCT holding data for subtree
9762306a36Sopenharmony_ci * RBCOMPUTE:   name of function that recomputes the RBAUGMENTED data
9862306a36Sopenharmony_ci */
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci#define RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME,				\
10162306a36Sopenharmony_ci			     RBSTRUCT, RBFIELD, RBAUGMENTED, RBCOMPUTE)	\
10262306a36Sopenharmony_cistatic inline void							\
10362306a36Sopenharmony_ciRBNAME ## _propagate(struct rb_node *rb, struct rb_node *stop)		\
10462306a36Sopenharmony_ci{									\
10562306a36Sopenharmony_ci	while (rb != stop) {						\
10662306a36Sopenharmony_ci		RBSTRUCT *node = rb_entry(rb, RBSTRUCT, RBFIELD);	\
10762306a36Sopenharmony_ci		if (RBCOMPUTE(node, true))				\
10862306a36Sopenharmony_ci			break;						\
10962306a36Sopenharmony_ci		rb = rb_parent(&node->RBFIELD);				\
11062306a36Sopenharmony_ci	}								\
11162306a36Sopenharmony_ci}									\
11262306a36Sopenharmony_cistatic inline void							\
11362306a36Sopenharmony_ciRBNAME ## _copy(struct rb_node *rb_old, struct rb_node *rb_new)		\
11462306a36Sopenharmony_ci{									\
11562306a36Sopenharmony_ci	RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD);		\
11662306a36Sopenharmony_ci	RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD);		\
11762306a36Sopenharmony_ci	new->RBAUGMENTED = old->RBAUGMENTED;				\
11862306a36Sopenharmony_ci}									\
11962306a36Sopenharmony_cistatic void								\
12062306a36Sopenharmony_ciRBNAME ## _rotate(struct rb_node *rb_old, struct rb_node *rb_new)	\
12162306a36Sopenharmony_ci{									\
12262306a36Sopenharmony_ci	RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD);		\
12362306a36Sopenharmony_ci	RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD);		\
12462306a36Sopenharmony_ci	new->RBAUGMENTED = old->RBAUGMENTED;				\
12562306a36Sopenharmony_ci	RBCOMPUTE(old, false);						\
12662306a36Sopenharmony_ci}									\
12762306a36Sopenharmony_ciRBSTATIC const struct rb_augment_callbacks RBNAME = {			\
12862306a36Sopenharmony_ci	.propagate = RBNAME ## _propagate,				\
12962306a36Sopenharmony_ci	.copy = RBNAME ## _copy,					\
13062306a36Sopenharmony_ci	.rotate = RBNAME ## _rotate					\
13162306a36Sopenharmony_ci};
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci/*
13462306a36Sopenharmony_ci * Template for declaring augmented rbtree callbacks,
13562306a36Sopenharmony_ci * computing RBAUGMENTED scalar as max(RBCOMPUTE(node)) for all subtree nodes.
13662306a36Sopenharmony_ci *
13762306a36Sopenharmony_ci * RBSTATIC:    'static' or empty
13862306a36Sopenharmony_ci * RBNAME:      name of the rb_augment_callbacks structure
13962306a36Sopenharmony_ci * RBSTRUCT:    struct type of the tree nodes
14062306a36Sopenharmony_ci * RBFIELD:     name of struct rb_node field within RBSTRUCT
14162306a36Sopenharmony_ci * RBTYPE:      type of the RBAUGMENTED field
14262306a36Sopenharmony_ci * RBAUGMENTED: name of RBTYPE field within RBSTRUCT holding data for subtree
14362306a36Sopenharmony_ci * RBCOMPUTE:   name of function that returns the per-node RBTYPE scalar
14462306a36Sopenharmony_ci */
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci#define RB_DECLARE_CALLBACKS_MAX(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD,	      \
14762306a36Sopenharmony_ci				 RBTYPE, RBAUGMENTED, RBCOMPUTE)	      \
14862306a36Sopenharmony_cistatic inline bool RBNAME ## _compute_max(RBSTRUCT *node, bool exit)	      \
14962306a36Sopenharmony_ci{									      \
15062306a36Sopenharmony_ci	RBSTRUCT *child;						      \
15162306a36Sopenharmony_ci	RBTYPE max = RBCOMPUTE(node);					      \
15262306a36Sopenharmony_ci	if (node->RBFIELD.rb_left) {					      \
15362306a36Sopenharmony_ci		child = rb_entry(node->RBFIELD.rb_left, RBSTRUCT, RBFIELD);   \
15462306a36Sopenharmony_ci		if (child->RBAUGMENTED > max)				      \
15562306a36Sopenharmony_ci			max = child->RBAUGMENTED;			      \
15662306a36Sopenharmony_ci	}								      \
15762306a36Sopenharmony_ci	if (node->RBFIELD.rb_right) {					      \
15862306a36Sopenharmony_ci		child = rb_entry(node->RBFIELD.rb_right, RBSTRUCT, RBFIELD);  \
15962306a36Sopenharmony_ci		if (child->RBAUGMENTED > max)				      \
16062306a36Sopenharmony_ci			max = child->RBAUGMENTED;			      \
16162306a36Sopenharmony_ci	}								      \
16262306a36Sopenharmony_ci	if (exit && node->RBAUGMENTED == max)				      \
16362306a36Sopenharmony_ci		return true;						      \
16462306a36Sopenharmony_ci	node->RBAUGMENTED = max;					      \
16562306a36Sopenharmony_ci	return false;							      \
16662306a36Sopenharmony_ci}									      \
16762306a36Sopenharmony_ciRB_DECLARE_CALLBACKS(RBSTATIC, RBNAME,					      \
16862306a36Sopenharmony_ci		     RBSTRUCT, RBFIELD, RBAUGMENTED, RBNAME ## _compute_max)
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci#define	RB_RED		0
17262306a36Sopenharmony_ci#define	RB_BLACK	1
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_ci#define __rb_parent(pc)    ((struct rb_node *)(pc & ~3))
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci#define __rb_color(pc)     ((pc) & 1)
17762306a36Sopenharmony_ci#define __rb_is_black(pc)  __rb_color(pc)
17862306a36Sopenharmony_ci#define __rb_is_red(pc)    (!__rb_color(pc))
17962306a36Sopenharmony_ci#define rb_color(rb)       __rb_color((rb)->__rb_parent_color)
18062306a36Sopenharmony_ci#define rb_is_red(rb)      __rb_is_red((rb)->__rb_parent_color)
18162306a36Sopenharmony_ci#define rb_is_black(rb)    __rb_is_black((rb)->__rb_parent_color)
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_cistatic inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
18462306a36Sopenharmony_ci{
18562306a36Sopenharmony_ci	rb->__rb_parent_color = rb_color(rb) + (unsigned long)p;
18662306a36Sopenharmony_ci}
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_cistatic inline void rb_set_parent_color(struct rb_node *rb,
18962306a36Sopenharmony_ci				       struct rb_node *p, int color)
19062306a36Sopenharmony_ci{
19162306a36Sopenharmony_ci	rb->__rb_parent_color = (unsigned long)p + color;
19262306a36Sopenharmony_ci}
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_cistatic inline void
19562306a36Sopenharmony_ci__rb_change_child(struct rb_node *old, struct rb_node *new,
19662306a36Sopenharmony_ci		  struct rb_node *parent, struct rb_root *root)
19762306a36Sopenharmony_ci{
19862306a36Sopenharmony_ci	if (parent) {
19962306a36Sopenharmony_ci		if (parent->rb_left == old)
20062306a36Sopenharmony_ci			WRITE_ONCE(parent->rb_left, new);
20162306a36Sopenharmony_ci		else
20262306a36Sopenharmony_ci			WRITE_ONCE(parent->rb_right, new);
20362306a36Sopenharmony_ci	} else
20462306a36Sopenharmony_ci		WRITE_ONCE(root->rb_node, new);
20562306a36Sopenharmony_ci}
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_cistatic inline void
20862306a36Sopenharmony_ci__rb_change_child_rcu(struct rb_node *old, struct rb_node *new,
20962306a36Sopenharmony_ci		      struct rb_node *parent, struct rb_root *root)
21062306a36Sopenharmony_ci{
21162306a36Sopenharmony_ci	if (parent) {
21262306a36Sopenharmony_ci		if (parent->rb_left == old)
21362306a36Sopenharmony_ci			rcu_assign_pointer(parent->rb_left, new);
21462306a36Sopenharmony_ci		else
21562306a36Sopenharmony_ci			rcu_assign_pointer(parent->rb_right, new);
21662306a36Sopenharmony_ci	} else
21762306a36Sopenharmony_ci		rcu_assign_pointer(root->rb_node, new);
21862306a36Sopenharmony_ci}
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ciextern void __rb_erase_color(struct rb_node *parent, struct rb_root *root,
22162306a36Sopenharmony_ci	void (*augment_rotate)(struct rb_node *old, struct rb_node *new));
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_cistatic __always_inline struct rb_node *
22462306a36Sopenharmony_ci__rb_erase_augmented(struct rb_node *node, struct rb_root *root,
22562306a36Sopenharmony_ci		     const struct rb_augment_callbacks *augment)
22662306a36Sopenharmony_ci{
22762306a36Sopenharmony_ci	struct rb_node *child = node->rb_right;
22862306a36Sopenharmony_ci	struct rb_node *tmp = node->rb_left;
22962306a36Sopenharmony_ci	struct rb_node *parent, *rebalance;
23062306a36Sopenharmony_ci	unsigned long pc;
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci	if (!tmp) {
23362306a36Sopenharmony_ci		/*
23462306a36Sopenharmony_ci		 * Case 1: node to erase has no more than 1 child (easy!)
23562306a36Sopenharmony_ci		 *
23662306a36Sopenharmony_ci		 * Note that if there is one child it must be red due to 5)
23762306a36Sopenharmony_ci		 * and node must be black due to 4). We adjust colors locally
23862306a36Sopenharmony_ci		 * so as to bypass __rb_erase_color() later on.
23962306a36Sopenharmony_ci		 */
24062306a36Sopenharmony_ci		pc = node->__rb_parent_color;
24162306a36Sopenharmony_ci		parent = __rb_parent(pc);
24262306a36Sopenharmony_ci		__rb_change_child(node, child, parent, root);
24362306a36Sopenharmony_ci		if (child) {
24462306a36Sopenharmony_ci			child->__rb_parent_color = pc;
24562306a36Sopenharmony_ci			rebalance = NULL;
24662306a36Sopenharmony_ci		} else
24762306a36Sopenharmony_ci			rebalance = __rb_is_black(pc) ? parent : NULL;
24862306a36Sopenharmony_ci		tmp = parent;
24962306a36Sopenharmony_ci	} else if (!child) {
25062306a36Sopenharmony_ci		/* Still case 1, but this time the child is node->rb_left */
25162306a36Sopenharmony_ci		tmp->__rb_parent_color = pc = node->__rb_parent_color;
25262306a36Sopenharmony_ci		parent = __rb_parent(pc);
25362306a36Sopenharmony_ci		__rb_change_child(node, tmp, parent, root);
25462306a36Sopenharmony_ci		rebalance = NULL;
25562306a36Sopenharmony_ci		tmp = parent;
25662306a36Sopenharmony_ci	} else {
25762306a36Sopenharmony_ci		struct rb_node *successor = child, *child2;
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci		tmp = child->rb_left;
26062306a36Sopenharmony_ci		if (!tmp) {
26162306a36Sopenharmony_ci			/*
26262306a36Sopenharmony_ci			 * Case 2: node's successor is its right child
26362306a36Sopenharmony_ci			 *
26462306a36Sopenharmony_ci			 *    (n)          (s)
26562306a36Sopenharmony_ci			 *    / \          / \
26662306a36Sopenharmony_ci			 *  (x) (s)  ->  (x) (c)
26762306a36Sopenharmony_ci			 *        \
26862306a36Sopenharmony_ci			 *        (c)
26962306a36Sopenharmony_ci			 */
27062306a36Sopenharmony_ci			parent = successor;
27162306a36Sopenharmony_ci			child2 = successor->rb_right;
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_ci			augment->copy(node, successor);
27462306a36Sopenharmony_ci		} else {
27562306a36Sopenharmony_ci			/*
27662306a36Sopenharmony_ci			 * Case 3: node's successor is leftmost under
27762306a36Sopenharmony_ci			 * node's right child subtree
27862306a36Sopenharmony_ci			 *
27962306a36Sopenharmony_ci			 *    (n)          (s)
28062306a36Sopenharmony_ci			 *    / \          / \
28162306a36Sopenharmony_ci			 *  (x) (y)  ->  (x) (y)
28262306a36Sopenharmony_ci			 *      /            /
28362306a36Sopenharmony_ci			 *    (p)          (p)
28462306a36Sopenharmony_ci			 *    /            /
28562306a36Sopenharmony_ci			 *  (s)          (c)
28662306a36Sopenharmony_ci			 *    \
28762306a36Sopenharmony_ci			 *    (c)
28862306a36Sopenharmony_ci			 */
28962306a36Sopenharmony_ci			do {
29062306a36Sopenharmony_ci				parent = successor;
29162306a36Sopenharmony_ci				successor = tmp;
29262306a36Sopenharmony_ci				tmp = tmp->rb_left;
29362306a36Sopenharmony_ci			} while (tmp);
29462306a36Sopenharmony_ci			child2 = successor->rb_right;
29562306a36Sopenharmony_ci			WRITE_ONCE(parent->rb_left, child2);
29662306a36Sopenharmony_ci			WRITE_ONCE(successor->rb_right, child);
29762306a36Sopenharmony_ci			rb_set_parent(child, successor);
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci			augment->copy(node, successor);
30062306a36Sopenharmony_ci			augment->propagate(parent, successor);
30162306a36Sopenharmony_ci		}
30262306a36Sopenharmony_ci
30362306a36Sopenharmony_ci		tmp = node->rb_left;
30462306a36Sopenharmony_ci		WRITE_ONCE(successor->rb_left, tmp);
30562306a36Sopenharmony_ci		rb_set_parent(tmp, successor);
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_ci		pc = node->__rb_parent_color;
30862306a36Sopenharmony_ci		tmp = __rb_parent(pc);
30962306a36Sopenharmony_ci		__rb_change_child(node, successor, tmp, root);
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_ci		if (child2) {
31262306a36Sopenharmony_ci			rb_set_parent_color(child2, parent, RB_BLACK);
31362306a36Sopenharmony_ci			rebalance = NULL;
31462306a36Sopenharmony_ci		} else {
31562306a36Sopenharmony_ci			rebalance = rb_is_black(successor) ? parent : NULL;
31662306a36Sopenharmony_ci		}
31762306a36Sopenharmony_ci		successor->__rb_parent_color = pc;
31862306a36Sopenharmony_ci		tmp = successor;
31962306a36Sopenharmony_ci	}
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci	augment->propagate(tmp, NULL);
32262306a36Sopenharmony_ci	return rebalance;
32362306a36Sopenharmony_ci}
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_cistatic __always_inline void
32662306a36Sopenharmony_cirb_erase_augmented(struct rb_node *node, struct rb_root *root,
32762306a36Sopenharmony_ci		   const struct rb_augment_callbacks *augment)
32862306a36Sopenharmony_ci{
32962306a36Sopenharmony_ci	struct rb_node *rebalance = __rb_erase_augmented(node, root, augment);
33062306a36Sopenharmony_ci	if (rebalance)
33162306a36Sopenharmony_ci		__rb_erase_color(rebalance, root, augment->rotate);
33262306a36Sopenharmony_ci}
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_cistatic __always_inline void
33562306a36Sopenharmony_cirb_erase_augmented_cached(struct rb_node *node, struct rb_root_cached *root,
33662306a36Sopenharmony_ci			  const struct rb_augment_callbacks *augment)
33762306a36Sopenharmony_ci{
33862306a36Sopenharmony_ci	if (root->rb_leftmost == node)
33962306a36Sopenharmony_ci		root->rb_leftmost = rb_next(node);
34062306a36Sopenharmony_ci	rb_erase_augmented(node, &root->rb_root, augment);
34162306a36Sopenharmony_ci}
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci#endif	/* _LINUX_RBTREE_AUGMENTED_H */
344