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. Link: http://lkml.kernel.org/r/20190703040156.56953-4-walken@google.com Signed-off-by: Michel Lespinasse <walken@google.com> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: David Howells <dhowells@redhat.com> Cc: Davidlohr Bueso <dbueso@suse.de> Cc: Uladzislau Rezki <urezki@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
315cc066b8
commit
6d2052d188
2 changed files with 24 additions and 24 deletions
|
@ -67,22 +67,19 @@ rb_insert_augmented_cached(struct rb_node *node,
|
||||||
* RBNAME: name of the rb_augment_callbacks structure
|
* RBNAME: name of the rb_augment_callbacks structure
|
||||||
* RBSTRUCT: struct type of the tree nodes
|
* RBSTRUCT: struct type of the tree nodes
|
||||||
* RBFIELD: name of struct rb_node field within RBSTRUCT
|
* RBFIELD: name of struct rb_node field within RBSTRUCT
|
||||||
* RBTYPE: type of the RBAUGMENTED field
|
* RBAUGMENTED: name of field within RBSTRUCT holding data for subtree
|
||||||
* RBAUGMENTED: name of RBTYPE field within RBSTRUCT holding data for subtree
|
|
||||||
* RBCOMPUTE: name of function that recomputes the RBAUGMENTED data
|
* RBCOMPUTE: name of function that recomputes the RBAUGMENTED data
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \
|
#define RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \
|
||||||
RBTYPE, RBAUGMENTED, RBCOMPUTE) \
|
RBSTRUCT, RBFIELD, RBAUGMENTED, RBCOMPUTE) \
|
||||||
static inline void \
|
static inline void \
|
||||||
RBNAME ## _propagate(struct rb_node *rb, struct rb_node *stop) \
|
RBNAME ## _propagate(struct rb_node *rb, struct rb_node *stop) \
|
||||||
{ \
|
{ \
|
||||||
while (rb != stop) { \
|
while (rb != stop) { \
|
||||||
RBSTRUCT *node = rb_entry(rb, RBSTRUCT, RBFIELD); \
|
RBSTRUCT *node = rb_entry(rb, RBSTRUCT, RBFIELD); \
|
||||||
RBTYPE augmented = RBCOMPUTE(node); \
|
if (RBCOMPUTE(node, true)) \
|
||||||
if (node->RBAUGMENTED == augmented) \
|
|
||||||
break; \
|
break; \
|
||||||
node->RBAUGMENTED = augmented; \
|
|
||||||
rb = rb_parent(&node->RBFIELD); \
|
rb = rb_parent(&node->RBFIELD); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
|
@ -99,7 +96,7 @@ RBNAME ## _rotate(struct rb_node *rb_old, struct rb_node *rb_new) \
|
||||||
RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD); \
|
RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD); \
|
||||||
RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \
|
RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \
|
||||||
new->RBAUGMENTED = old->RBAUGMENTED; \
|
new->RBAUGMENTED = old->RBAUGMENTED; \
|
||||||
old->RBAUGMENTED = RBCOMPUTE(old); \
|
RBCOMPUTE(old, false); \
|
||||||
} \
|
} \
|
||||||
RBSTATIC const struct rb_augment_callbacks RBNAME = { \
|
RBSTATIC const struct rb_augment_callbacks RBNAME = { \
|
||||||
.propagate = RBNAME ## _propagate, \
|
.propagate = RBNAME ## _propagate, \
|
||||||
|
@ -122,7 +119,7 @@ RBSTATIC const struct rb_augment_callbacks RBNAME = { \
|
||||||
|
|
||||||
#define RB_DECLARE_CALLBACKS_MAX(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \
|
#define RB_DECLARE_CALLBACKS_MAX(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \
|
||||||
RBTYPE, RBAUGMENTED, RBCOMPUTE) \
|
RBTYPE, RBAUGMENTED, RBCOMPUTE) \
|
||||||
static inline RBTYPE RBNAME ## _compute_max(RBSTRUCT *node) \
|
static inline bool RBNAME ## _compute_max(RBSTRUCT *node, bool exit) \
|
||||||
{ \
|
{ \
|
||||||
RBSTRUCT *child; \
|
RBSTRUCT *child; \
|
||||||
RBTYPE max = RBCOMPUTE(node); \
|
RBTYPE max = RBCOMPUTE(node); \
|
||||||
|
@ -136,10 +133,13 @@ static inline RBTYPE RBNAME ## _compute_max(RBSTRUCT *node) \
|
||||||
if (child->RBAUGMENTED > max) \
|
if (child->RBAUGMENTED > max) \
|
||||||
max = child->RBAUGMENTED; \
|
max = child->RBAUGMENTED; \
|
||||||
} \
|
} \
|
||||||
return max; \
|
if (exit && node->RBAUGMENTED == max) \
|
||||||
|
return true; \
|
||||||
|
node->RBAUGMENTED = max; \
|
||||||
|
return false; \
|
||||||
} \
|
} \
|
||||||
RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \
|
RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \
|
||||||
RBTYPE, RBAUGMENTED, RBNAME ## _compute_max)
|
RBSTRUCT, RBFIELD, RBAUGMENTED, RBNAME ## _compute_max)
|
||||||
|
|
||||||
|
|
||||||
#define RB_RED 0
|
#define RB_RED 0
|
||||||
|
|
|
@ -69,22 +69,19 @@ rb_insert_augmented_cached(struct rb_node *node,
|
||||||
* RBNAME: name of the rb_augment_callbacks structure
|
* RBNAME: name of the rb_augment_callbacks structure
|
||||||
* RBSTRUCT: struct type of the tree nodes
|
* RBSTRUCT: struct type of the tree nodes
|
||||||
* RBFIELD: name of struct rb_node field within RBSTRUCT
|
* RBFIELD: name of struct rb_node field within RBSTRUCT
|
||||||
* RBTYPE: type of the RBAUGMENTED field
|
* RBAUGMENTED: name of field within RBSTRUCT holding data for subtree
|
||||||
* RBAUGMENTED: name of RBTYPE field within RBSTRUCT holding data for subtree
|
|
||||||
* RBCOMPUTE: name of function that recomputes the RBAUGMENTED data
|
* RBCOMPUTE: name of function that recomputes the RBAUGMENTED data
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \
|
#define RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \
|
||||||
RBTYPE, RBAUGMENTED, RBCOMPUTE) \
|
RBSTRUCT, RBFIELD, RBAUGMENTED, RBCOMPUTE) \
|
||||||
static inline void \
|
static inline void \
|
||||||
RBNAME ## _propagate(struct rb_node *rb, struct rb_node *stop) \
|
RBNAME ## _propagate(struct rb_node *rb, struct rb_node *stop) \
|
||||||
{ \
|
{ \
|
||||||
while (rb != stop) { \
|
while (rb != stop) { \
|
||||||
RBSTRUCT *node = rb_entry(rb, RBSTRUCT, RBFIELD); \
|
RBSTRUCT *node = rb_entry(rb, RBSTRUCT, RBFIELD); \
|
||||||
RBTYPE augmented = RBCOMPUTE(node); \
|
if (RBCOMPUTE(node, true)) \
|
||||||
if (node->RBAUGMENTED == augmented) \
|
|
||||||
break; \
|
break; \
|
||||||
node->RBAUGMENTED = augmented; \
|
|
||||||
rb = rb_parent(&node->RBFIELD); \
|
rb = rb_parent(&node->RBFIELD); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
|
@ -101,7 +98,7 @@ RBNAME ## _rotate(struct rb_node *rb_old, struct rb_node *rb_new) \
|
||||||
RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD); \
|
RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD); \
|
||||||
RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \
|
RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \
|
||||||
new->RBAUGMENTED = old->RBAUGMENTED; \
|
new->RBAUGMENTED = old->RBAUGMENTED; \
|
||||||
old->RBAUGMENTED = RBCOMPUTE(old); \
|
RBCOMPUTE(old, false); \
|
||||||
} \
|
} \
|
||||||
RBSTATIC const struct rb_augment_callbacks RBNAME = { \
|
RBSTATIC const struct rb_augment_callbacks RBNAME = { \
|
||||||
.propagate = RBNAME ## _propagate, \
|
.propagate = RBNAME ## _propagate, \
|
||||||
|
@ -124,7 +121,7 @@ RBSTATIC const struct rb_augment_callbacks RBNAME = { \
|
||||||
|
|
||||||
#define RB_DECLARE_CALLBACKS_MAX(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \
|
#define RB_DECLARE_CALLBACKS_MAX(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \
|
||||||
RBTYPE, RBAUGMENTED, RBCOMPUTE) \
|
RBTYPE, RBAUGMENTED, RBCOMPUTE) \
|
||||||
static inline RBTYPE RBNAME ## _compute_max(RBSTRUCT *node) \
|
static inline bool RBNAME ## _compute_max(RBSTRUCT *node, bool exit) \
|
||||||
{ \
|
{ \
|
||||||
RBSTRUCT *child; \
|
RBSTRUCT *child; \
|
||||||
RBTYPE max = RBCOMPUTE(node); \
|
RBTYPE max = RBCOMPUTE(node); \
|
||||||
|
@ -138,10 +135,13 @@ static inline RBTYPE RBNAME ## _compute_max(RBSTRUCT *node) \
|
||||||
if (child->RBAUGMENTED > max) \
|
if (child->RBAUGMENTED > max) \
|
||||||
max = child->RBAUGMENTED; \
|
max = child->RBAUGMENTED; \
|
||||||
} \
|
} \
|
||||||
return max; \
|
if (exit && node->RBAUGMENTED == max) \
|
||||||
|
return true; \
|
||||||
|
node->RBAUGMENTED = max; \
|
||||||
|
return false; \
|
||||||
} \
|
} \
|
||||||
RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \
|
RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \
|
||||||
RBTYPE, RBAUGMENTED, RBNAME ## _compute_max)
|
RBSTRUCT, RBFIELD, RBAUGMENTED, RBNAME ## _compute_max)
|
||||||
|
|
||||||
|
|
||||||
#define RB_RED 0
|
#define RB_RED 0
|
||||||
|
|
Loading…
Reference in a new issue