In concluding RB_REMOVE_COLOR, in the case when the sibling of the

root of the too-short tree is black and at least one of the children
of that sibling is red, either one or two rotations finish the
rebalancing. In the case when both of the children are red, the
current implementation uses two rotations where only one is
necessary. This change removes that extra rotation, and in that case
also removes a needless black-to-red-to-black recoloring.

Reviewed by:	markj
Differential Revision:	https://reviews.freebsd.org/D25335
This commit is contained in:
Doug Moore 2020-06-20 20:25:39 +00:00
parent c8b0a88b8d
commit bc1bed77a8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=362450

View File

@ -493,21 +493,19 @@ name##_RB_REMOVE_COLOR(struct name *head, struct type *parent) \
RB_ROTATE_LEFT(head, parent, tmp, field);\
tmp = RB_RIGHT(parent, field); \
} \
if (RB_ISRED(RB_LEFT(tmp, field), field)) { \
if (RB_ISRED(RB_RIGHT(tmp, field), field)) \
RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK; \
else if (RB_ISRED(RB_LEFT(tmp, field), field)) { \
struct type *oleft; \
oleft = RB_LEFT(tmp, field); \
RB_COLOR(oleft, field) = RB_BLACK; \
RB_COLOR(tmp, field) = RB_RED; \
RB_ROTATE_RIGHT(head, tmp, oleft, field); \
tmp = RB_RIGHT(parent, field); \
} else if (!RB_ISRED(RB_RIGHT(tmp, field), field)) { \
RB_COLOR(oleft, field) = RB_BLACK; \
tmp = oleft; \
} else { \
RB_COLOR(tmp, field) = RB_RED; \
elm = parent; \
parent = RB_PARENT(elm, field); \
continue; \
} \
if (RB_ISRED(RB_RIGHT(tmp, field), field)) \
RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK; \
RB_COLOR(tmp, field) = RB_COLOR(parent, field); \
RB_COLOR(parent, field) = RB_BLACK; \
RB_ROTATE_LEFT(head, parent, tmp, field); \
@ -520,21 +518,19 @@ name##_RB_REMOVE_COLOR(struct name *head, struct type *parent) \
RB_ROTATE_RIGHT(head, parent, tmp, field);\
tmp = RB_LEFT(parent, field); \
} \
if (RB_ISRED(RB_RIGHT(tmp, field), field)) { \
if (RB_ISRED(RB_LEFT(tmp, field), field)) \
RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK; \
else if (RB_ISRED(RB_RIGHT(tmp, field), field)) { \
struct type *oright; \
oright = RB_RIGHT(tmp, field); \
RB_COLOR(oright, field) = RB_BLACK; \
RB_COLOR(tmp, field) = RB_RED; \
RB_ROTATE_LEFT(head, tmp, oright, field); \
tmp = RB_LEFT(parent, field); \
RB_COLOR(oright, field) = RB_BLACK; \
tmp = oright; \
} else if (!RB_ISRED(RB_LEFT(tmp, field), field)) { \
RB_COLOR(tmp, field) = RB_RED; \
elm = parent; \
parent = RB_PARENT(elm, field); \
continue; \
} \
if (RB_ISRED(RB_LEFT(tmp, field), field)) \
RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK; \
RB_COLOR(tmp, field) = RB_COLOR(parent, field); \
RB_COLOR(parent, field) = RB_BLACK; \
RB_ROTATE_RIGHT(head, parent, tmp, field); \