[3/4] sys/tree.h: Add parent rotations

Message ID 20211005141625.31585-4-sebastian.huber@embedded-brains.de
State Superseded
Headers show
Series
  • Optimize red-black tree insert/extract
Related show

Commit Message

Sebastian Huber Oct. 5, 2021, 2:16 p.m.
Add specialized rotations RB_PARENT_ROTATE_LEFT() and RB_PARENT_ROTATE_RIGHT()
which may be used if the parent node exists and the direction of the child is
known.  The specialized rotations are derived from RB_ROTATE_LEFT() and
RB_ROTATE_RIGHT() where the RB_SWAP_CHILD() was replaced by a simple
assignment.
---
 newlib/libc/include/sys/tree.h | 36 ++++++++++++++++++++++++++++++----
 1 file changed, 32 insertions(+), 4 deletions(-)

-- 
2.26.2

Comments

C Howland Oct. 5, 2021, 2:56 p.m. | #1
>

>

>

> ------------------------------

> *From:* Newlib <newlib-bounces+craig.howland=caci.com@sourceware.org> on

> behalf of Sebastian Huber <sebastian.huber@embedded-brains.de>

> *Sent:* Tuesday, October 5, 2021 10:16 AM

> *To:* newlib@sourceware.org <newlib@sourceware.org>

> *Cc:* devel@rtems.org <devel@rtems.org>

> *Subject:* [PATCH 3/4] sys/tree.h: Add parent rotations

>

>

>

> Add specialized rotations RB_PARENT_ROTATE_LEFT() and

> RB_PARENT_ROTATE_RIGHT()

> which may be used if the parent node exists and the direction of the child

> is

> known.  The specialized rotations are derived from RB_ROTATE_LEFT() and

> RB_ROTATE_RIGHT() where the RB_SWAP_CHILD() was replaced by a simple

> assignment.

>


It would seem appropriate for both this patch and #4 to include your
descriptions from the emails about the specialized nature of these new
macros in the source.  (Otherwise, how can the conditions on their use be
known?)
Craig

---
>  newlib/libc/include/sys/tree.h | 36 ++++++++++++++++++++++++++++++----

>  1 file changed, 32 insertions(+), 4 deletions(-)

>

> diff --git a/newlib/libc/include/sys/tree.h

> b/newlib/libc/include/sys/tree.h

> index 180809e9b..5fc052817 100644

> --- a/newlib/libc/include/sys/tree.h

> +++ b/newlib/libc/include/sys/tree.h

> @@ -381,6 +381,30 @@ struct

> {                                                           \

>         RB_AUGMENT(elm);                                                \

>  } while (/*CONSTCOND*/ 0)

>

> +#define RB_PARENT_ROTATE_LEFT(parent, left, tmp, field) do {           \

> ...

> 2.26.2

>

>

Patch

diff --git a/newlib/libc/include/sys/tree.h b/newlib/libc/include/sys/tree.h
index 180809e9b..5fc052817 100644
--- a/newlib/libc/include/sys/tree.h
+++ b/newlib/libc/include/sys/tree.h
@@ -381,6 +381,30 @@  struct {								\
 	RB_AUGMENT(elm);						\
 } while (/*CONSTCOND*/ 0)
 
+#define RB_PARENT_ROTATE_LEFT(parent, left, tmp, field) do {		\
+	(tmp) = RB_RIGHT(left, field);					\
+	if ((RB_RIGHT(left, field) = RB_LEFT(tmp, field)) != NULL) {	\
+		RB_SET_PARENT(RB_RIGHT(left, field), left, field);	\
+	}								\
+	RB_SET_PARENT(tmp, parent, field);				\
+	RB_LEFT(parent, field) = (tmp);					\
+	RB_LEFT(tmp, field) = (left);					\
+	RB_SET_PARENT(left, tmp, field);				\
+	RB_AUGMENT(left);						\
+} while (/*CONSTCOND*/ 0)
+
+#define RB_PARENT_ROTATE_RIGHT(parent, elm, tmp, field) do {		\
+	(tmp) = RB_LEFT(elm, field);					\
+	if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) {	\
+		RB_SET_PARENT(RB_LEFT(elm, field), elm, field);		\
+	}								\
+	RB_SET_PARENT(tmp, parent, field);				\
+	RB_RIGHT(parent, field) = (tmp);				\
+	RB_RIGHT(tmp, field) = (elm);					\
+	RB_SET_PARENT(elm, tmp, field);					\
+	RB_AUGMENT(elm);						\
+} while (/*CONSTCOND*/ 0)
+
 /* Generates prototypes and inline functions */
 #define	RB_PROTOTYPE(name, type, field, cmp)				\
 	RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
@@ -454,7 +478,8 @@  name##_RB_INSERT_COLOR(struct name *head, struct type *elm)		\
 				continue;				\
 			}						\
 			if (RB_RIGHT(parent, field) == elm) {		\
-				RB_ROTATE_LEFT(head, parent, tmp, field);\
+				RB_PARENT_ROTATE_LEFT(gparent, parent,	\
+				    tmp, field);			\
 				tmp = parent;				\
 				parent = elm;				\
 				elm = tmp;				\
@@ -470,7 +495,8 @@  name##_RB_INSERT_COLOR(struct name *head, struct type *elm)		\
 				continue;				\
 			}						\
 			if (RB_LEFT(parent, field) == elm) {		\
-				RB_ROTATE_RIGHT(head, parent, tmp, field);\
+				RB_PARENT_ROTATE_RIGHT(gparent, parent,	\
+				    tmp, field);			\
 				tmp = parent;				\
 				parent = elm;				\
 				elm = tmp;				\
@@ -500,7 +526,8 @@  name##_RB_REMOVE_COLOR(struct name *head, struct type *parent)		\
 				RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK; \
 			else if (RB_ISRED(RB_LEFT(tmp, field), field)) { \
 				struct type *oleft;			\
-				RB_ROTATE_RIGHT(head, tmp, oleft, field); \
+				RB_PARENT_ROTATE_RIGHT(parent, tmp,	\
+				    oleft, field);			\
 				RB_COLOR(oleft, field) = RB_BLACK;	\
 				tmp = oleft;				\
 			} else {					\
@@ -525,7 +552,8 @@  name##_RB_REMOVE_COLOR(struct name *head, struct type *parent)		\
 				RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK; \
 			else if (RB_ISRED(RB_RIGHT(tmp, field), field)) { \
 				struct type *oright;			\
-				RB_ROTATE_LEFT(head, tmp, oright, field); \
+				RB_PARENT_ROTATE_LEFT(parent, tmp,	\
+				    oright, field);			\
 				RB_COLOR(oright, field) = RB_BLACK;	\
 				tmp = oright;				\
 			} else {					\