For the case when RB_REMOVE requires a nontrivial search to find the

node to replace the one being removed, restructure to first remove the
replacement node and correct the parent pointers around it, and then
let the all-cases code at the end deal with the parent of the deleted
node, making it point to the replacement node. This removes one or two
conditional branches.

Reviewed by:	markj
Tested by:	pho
Differential Revision:	https://reviews.freebsd.org/D24845
This commit is contained in:
Doug Moore 2020-05-21 05:34:02 +00:00
parent a100c050eb
commit c807b9ec06

View File

@ -562,48 +562,44 @@ name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm)
attr struct type * \
name##_RB_REMOVE(struct name *head, struct type *elm) \
{ \
struct type *child, *parent, *old = elm; \
struct type *child, *parent, *parent_old, *old = elm; \
int color; \
if (RB_LEFT(elm, field) == NULL) \
child = RB_RIGHT(elm, field); \
else if (RB_RIGHT(elm, field) == NULL) \
child = RB_LEFT(elm, field); \
else { \
parent_old = parent = RB_PARENT(elm, field); \
color = RB_COLOR(elm, field); \
if (RB_LEFT(elm, field) == NULL) { \
elm = child = RB_RIGHT(elm, field); \
if (elm != NULL) \
RB_PARENT(elm, field) = parent; \
} else if (RB_RIGHT(elm, field) == NULL) { \
elm = child = RB_LEFT(elm, field); \
RB_PARENT(elm, field) = parent; \
} else { \
elm = RB_RIGHT(old, field); \
if ((child = RB_LEFT(elm, field)) == NULL) { \
child = RB_RIGHT(elm, field); \
RB_RIGHT(old, field) = child; \
RB_PARENT(elm, field) = elm; \
parent = elm; \
} else { \
do \
elm = child; \
while ((child = RB_LEFT(elm, field)) != NULL); \
child = RB_RIGHT(elm, field); \
parent = RB_PARENT(elm, field); \
RB_LEFT(parent, field) = child; \
if (child != NULL) \
RB_PARENT(child, field) = parent; \
RB_PARENT(RB_RIGHT(old, field), field) = elm; \
} \
RB_PARENT(RB_LEFT(old, field), field) = elm; \
parent = RB_PARENT(old, field); \
if (parent != NULL) { \
if (RB_LEFT(parent, field) == old) \
RB_LEFT(parent, field) = elm; \
else \
RB_RIGHT(parent, field) = elm; \
} else \
RB_ROOT(head) = elm; \
color = RB_COLOR(elm, field); \
elm->field = old->field; \
} \
parent = RB_PARENT(elm, field); \
color = RB_COLOR(elm, field); \
if (child != NULL) \
RB_PARENT(child, field) = parent; \
if (parent != NULL) { \
if (RB_LEFT(parent, field) == elm) \
RB_LEFT(parent, field) = child; \
else \
RB_RIGHT(parent, field) = child; \
} else \
RB_ROOT(head) = child; \
if (elm != old) \
(elm)->field = (old)->field; \
if (parent_old == NULL) \
RB_ROOT(head) = elm; \
else if (RB_LEFT(parent_old, field) == old) \
RB_LEFT(parent_old, field) = elm; \
else \
RB_RIGHT(parent_old, field) = elm; \
if (color == RB_BLACK) \
name##_RB_REMOVE_COLOR(head, parent, child); \
while (parent != NULL) { \