]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
The other direction of searching and traversing
authorJan Maria Matejka <mq@ucw.cz>
Mon, 3 Dec 2018 13:24:09 +0000 (14:24 +0100)
committerJan Maria Matejka <mq@ucw.cz>
Mon, 3 Dec 2018 13:24:09 +0000 (14:24 +0100)
lib/redblack.h

index 9dcfdc2176b637cb7c87c91ee087906bc2378db0..f02355430afc7a7aa83759c0c28d325b312a0097 100644 (file)
       out = *pointer; \
     out; \
     })
+#define REDBLACK_FIND_DOWN(type, name, key, compare, root, what) ({ \
+    type **pointer, *prev = NULL, *out; \
+    REDBLACK_FIND_POINTER(name, key, compare, root, what, pointer) \
+      prev = *pointer; \
+    if (!*pointer && prev) \
+      if (pointer == &(REDBLACK_LEFT_CHILD(name, prev))) \
+       out = REDBLACK_PREV(type, name, prev); \
+      else \
+       out = prev; \
+    else \
+      out = *pointer; \
+    out; \
+    })
 
 #define REDBLACK_FIRST(type, name, root) ({ \
     type *first = root; \
     where; \
 })
 
+#define REDBLACK_PREV(type, name, node) ({ \
+    type *where = node; \
+    if (REDBLACK_LEFT_CHILD(name, where)) { \
+      where = REDBLACK_LEFT_CHILD(name, where); \
+      while (REDBLACK_RIGHT_CHILD(name, where)) \
+       where = REDBLACK_RIGHT_CHILD(name, where); \
+    } else \
+      while (1) { \
+       type *p = REDBLACK_PARENT(type, name, where); \
+       int ps = p ? REDBLACK_PARENT_SIDE(name, p, where) : 0; \
+       where = p; \
+       if (ps == REDBLACK_LEFT) \
+         continue; \
+       break; \
+      } \
+    where; \
+})
+
 
 /* Low level tree manipulation */