summaryrefslogtreecommitdiffstats
path: root/sys/sys/tree.h
diff options
context:
space:
mode:
authorjasone <jasone@FreeBSD.org>2006-01-11 15:48:36 +0000
committerjasone <jasone@FreeBSD.org>2006-01-11 15:48:36 +0000
commit3c55fbecc573cb9c1d0662104ce9485950b986ae (patch)
tree07dde63ea169823889a636e0466b6359dc5e7e66 /sys/sys/tree.h
parentbb26b447587ea480273607b18f31bf7916e6a462 (diff)
downloadFreeBSD-src-3c55fbecc573cb9c1d0662104ce9485950b986ae.zip
FreeBSD-src-3c55fbecc573cb9c1d0662104ce9485950b986ae.tar.gz
Add the RB_NFIND() macro, which is useful for red-black tree searches
for which there may not be an exact match. Reviewed by: glebius, julian Approved by: markm (mentor)
Diffstat (limited to 'sys/sys/tree.h')
-rw-r--r--sys/sys/tree.h31
1 files changed, 31 insertions, 0 deletions
diff --git a/sys/sys/tree.h b/sys/sys/tree.h
index 6682ec7..47fd098 100644
--- a/sys/sys/tree.h
+++ b/sys/sys/tree.h
@@ -382,6 +382,7 @@ void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
struct type *name##_RB_REMOVE(struct name *, struct type *); \
struct type *name##_RB_INSERT(struct name *, struct type *); \
struct type *name##_RB_FIND(struct name *, struct type *); \
+struct type *name##_RB_NFIND(struct name *, struct type *); \
struct type *name##_RB_NEXT(struct type *); \
struct type *name##_RB_MINMAX(struct name *, int); \
\
@@ -628,6 +629,35 @@ name##_RB_FIND(struct name *head, struct type *elm) \
return (NULL); \
} \
\
+/* Finds the first node greater than or equal to the search key */ \
+struct type * \
+name##_RB_NFIND(struct name *head, struct type *elm) \
+{ \
+ struct type *ret = RB_ROOT(head); \
+ struct type *tmp; \
+ int comp; \
+ while (ret && (comp = cmp(elm, ret)) != 0) { \
+ if (comp < 0) { \
+ if ((tmp = RB_LEFT(ret, field)) == NULL) \
+ break; \
+ ret = tmp; \
+ } else { \
+ if ((tmp = RB_RIGHT(ret, field)) == NULL) { \
+ tmp = ret; \
+ ret = RB_PARENT(ret, field); \
+ while (ret && tmp == RB_RIGHT(ret, \
+ field)) { \
+ tmp = ret; \
+ ret = RB_PARENT(ret, field); \
+ } \
+ break; \
+ } \
+ ret = tmp; \
+ } \
+ } \
+ return (ret); \
+} \
+ \
/* ARGSUSED */ \
struct type * \
name##_RB_NEXT(struct type *elm) \
@@ -671,6 +701,7 @@ name##_RB_MINMAX(struct name *head, int val) \
#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
#define RB_FIND(name, x, y) name##_RB_FIND(x, y)
+#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y)
#define RB_NEXT(name, x, y) name##_RB_NEXT(y)
#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF)
#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF)
OpenPOWER on IntegriCloud