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:
parent
c8b0a88b8d
commit
bc1bed77a8
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=362450
@ -493,21 +493,19 @@ name##_RB_REMOVE_COLOR(struct name *head, struct type *parent) \
|
|||||||
RB_ROTATE_LEFT(head, parent, tmp, field);\
|
RB_ROTATE_LEFT(head, parent, tmp, field);\
|
||||||
tmp = RB_RIGHT(parent, 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; \
|
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); \
|
RB_ROTATE_RIGHT(head, tmp, oleft, field); \
|
||||||
tmp = RB_RIGHT(parent, field); \
|
RB_COLOR(oleft, field) = RB_BLACK; \
|
||||||
} else if (!RB_ISRED(RB_RIGHT(tmp, field), field)) { \
|
tmp = oleft; \
|
||||||
|
} else { \
|
||||||
RB_COLOR(tmp, field) = RB_RED; \
|
RB_COLOR(tmp, field) = RB_RED; \
|
||||||
elm = parent; \
|
elm = parent; \
|
||||||
parent = RB_PARENT(elm, field); \
|
parent = RB_PARENT(elm, field); \
|
||||||
continue; \
|
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(tmp, field) = RB_COLOR(parent, field); \
|
||||||
RB_COLOR(parent, field) = RB_BLACK; \
|
RB_COLOR(parent, field) = RB_BLACK; \
|
||||||
RB_ROTATE_LEFT(head, parent, tmp, field); \
|
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);\
|
RB_ROTATE_RIGHT(head, parent, tmp, field);\
|
||||||
tmp = RB_LEFT(parent, 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; \
|
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); \
|
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)) { \
|
} else if (!RB_ISRED(RB_LEFT(tmp, field), field)) { \
|
||||||
RB_COLOR(tmp, field) = RB_RED; \
|
RB_COLOR(tmp, field) = RB_RED; \
|
||||||
elm = parent; \
|
elm = parent; \
|
||||||
parent = RB_PARENT(elm, field); \
|
parent = RB_PARENT(elm, field); \
|
||||||
continue; \
|
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(tmp, field) = RB_COLOR(parent, field); \
|
||||||
RB_COLOR(parent, field) = RB_BLACK; \
|
RB_COLOR(parent, field) = RB_BLACK; \
|
||||||
RB_ROTATE_RIGHT(head, parent, tmp, field); \
|
RB_ROTATE_RIGHT(head, parent, tmp, field); \
|
||||||
|
Loading…
Reference in New Issue
Block a user