History

augmented rbtree: rework the RB_DECLARE_CALLBACKS macro definition

Change the definition of the RBCOMPUTE function. The propagate callback repeatedly calls RBCOMPUTE as it moves from leaf to root. it wants to stop recomputing once the augmented subtree information doesn't change. This was previously checked using the == operator, but that only works when the augmented subtree information is a scalar field. This commit modifies the RBCOMPUTE function so that it now sets the augmented subtree information instead of returning it, and returns a boolean value indicating if the propagate callback should stop. The motivation for this change is that I want to introduce augmented rbtree uses where the augmented data for the subtree is a struct instead of a scalar.

Michel Lespinasse committed 7 years ago

Commit 6d2052d1 parent 315cc062 files · +24 −24Browse files

Showing the changes to include/linux (1 of 2 files). Show all

Unified · Split

include/linux/rbtree_augmented.h+12−12
@@ -67,22 +67,19 @@ rb_insert_augmented_cached(struct rb_node *node, · 66 unmodified lines
67 * RBNAME: name of the rb_augment_callbacks structure67 * RBNAME: name of the rb_augment_callbacks structure
68 * RBSTRUCT: struct type of the tree nodes68 * RBSTRUCT: struct type of the tree nodes
69 * RBFIELD: name of struct rb_node field within RBSTRUCT69 * RBFIELD: name of struct rb_node field within RBSTRUCT
70 * RBTYPE: type of the RBAUGMENTED field70 * RBAUGMENTED: name of field within RBSTRUCT holding data for subtree
71 * RBAUGMENTED: name of RBTYPE field within RBSTRUCT holding data for subtree
72 * RBCOMPUTE: name of function that recomputes the RBAUGMENTED data71 * RBCOMPUTE: name of function that recomputes the RBAUGMENTED data
73 */72 */
74 73
75#define RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \74#define RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \
76 RBTYPE, RBAUGMENTED, RBCOMPUTE) \75 RBSTRUCT, RBFIELD, RBAUGMENTED, RBCOMPUTE) \
77static inline void \76static inline void \
78RBNAME ## _propagate(struct rb_node *rb, struct rb_node *stop) \77RBNAME ## _propagate(struct rb_node *rb, struct rb_node *stop) \
79{ \78{ \
80 while (rb != stop) { \79 while (rb != stop) { \
81 RBSTRUCT *node = rb_entry(rb, RBSTRUCT, RBFIELD); \80 RBSTRUCT *node = rb_entry(rb, RBSTRUCT, RBFIELD); \
82 RBTYPE augmented = RBCOMPUTE(node); \81 if (RBCOMPUTE(node, true)) \
83 if (node->RBAUGMENTED == augmented) \
84 break; \82 break; \
85 node->RBAUGMENTED = augmented; \
86 rb = rb_parent(&node->RBFIELD); \83 rb = rb_parent(&node->RBFIELD); \
87 } \84 } \
88} \85} \
@@ -99,7 +96,7 @@ RBNAME ## _rotate(struct rb_node *rb_old, struct rb_node *rb_new) \ · 10 unmodified lines
99 RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD); \96 RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD); \
100 RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \97 RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \
101 new->RBAUGMENTED = old->RBAUGMENTED; \98 new->RBAUGMENTED = old->RBAUGMENTED; \
102 old->RBAUGMENTED = RBCOMPUTE(old); \99 RBCOMPUTE(old, false); \
103} \100} \
104RBSTATIC const struct rb_augment_callbacks RBNAME = { \101RBSTATIC const struct rb_augment_callbacks RBNAME = { \
105 .propagate = RBNAME ## _propagate, \102 .propagate = RBNAME ## _propagate, \
@@ -122,7 +119,7 @@ RBSTATIC const struct rb_augment_callbacks RBNAME = { \ · 16 unmodified lines
122 119
123#define RB_DECLARE_CALLBACKS_MAX(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \120#define RB_DECLARE_CALLBACKS_MAX(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \
124 RBTYPE, RBAUGMENTED, RBCOMPUTE) \121 RBTYPE, RBAUGMENTED, RBCOMPUTE) \
125static inline RBTYPE RBNAME ## _compute_max(RBSTRUCT *node) \122static inline bool RBNAME ## _compute_max(RBSTRUCT *node, bool exit) \
126{ \123{ \
127 RBSTRUCT *child; \124 RBSTRUCT *child; \
128 RBTYPE max = RBCOMPUTE(node); \125 RBTYPE max = RBCOMPUTE(node); \
@@ -136,10 +133,13 @@ static inline RBTYPE RBNAME ## _compute_max(RBSTRUCT *node) \ · 7 unmodified lines
136 if (child->RBAUGMENTED > max) \133 if (child->RBAUGMENTED > max) \
137 max = child->RBAUGMENTED; \134 max = child->RBAUGMENTED; \
138 } \135 } \
139 return max; \136 if (exit && node->RBAUGMENTED == max) \
137 return true; \
138 node->RBAUGMENTED = max; \
139 return false; \
140} \140} \
141RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \141RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \
142 RBTYPE, RBAUGMENTED, RBNAME ## _compute_max)142 RBSTRUCT, RBFIELD, RBAUGMENTED, RBNAME ## _compute_max)
143 143
144 144
145#define RB_RED 0145#define RB_RED 0

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t