[sheepdog-users] [PATCH stable-0.7] rbtree: add rb_destroy helper

Hitoshi Mitake mitake.hitoshi at lab.ntt.co.jp
Mon Feb 3 08:50:05 CET 2014


From: Liu Yuan <namei.unix at gmail.com>

Signed-off-by: Liu Yuan <namei.unix at gmail.com>
Reviewed-by: Hitoshi Mitake <mitake.hitoshi at lab.ntt.co.jp>
Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>

Conflicts:
	dog/vdi.c
	include/rbtree.h
	sheep/group.c

Conflicts were resolved by Hitoshi Mitake.
Signed-off-by: Hitoshi Mitake <mitake.hitoshi at lab.ntt.co.jp>
---
 include/rbtree.h |  113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 113 insertions(+)

diff --git a/include/rbtree.h b/include/rbtree.h
index 642d151..aa16be3 100644
--- a/include/rbtree.h
+++ b/include/rbtree.h
@@ -80,4 +80,117 @@ static inline void rb_link_node(struct rb_node *node, struct rb_node *parent,
 	*rb_link = node;
 }
 
+/*
+ * Search for a value in the rbtree.  This returns NULL when the key is not
+ * found in the rbtree.
+ */
+#define rb_search(root, key, member, compar)				\
+({									\
+	struct rb_node *__n = (root)->rb_node;				\
+	typeof(key) __ret = NULL, __data;				\
+									\
+	while (__n) {							\
+		__data = rb_entry(__n, typeof(*key), member);		\
+		int __cmp = compar(key, __data);			\
+									\
+		if (__cmp < 0)						\
+			__n = __n->rb_left;				\
+		else if (__cmp > 0)					\
+			__n = __n->rb_right;				\
+		else {							\
+			__ret = __data;					\
+			break;						\
+		}							\
+	}								\
+	__ret;								\
+})
+
+/*
+ * Insert a new node into the rbtree.  This returns NULL on success, or the
+ * existing node on error.
+ */
+#define rb_insert(root, new, member, compar)				\
+({									\
+	struct rb_node **__n = &(root)->rb_node, *__parent = NULL;	\
+	typeof(new) __old = NULL, __data;				\
+									\
+	while (*__n) {							\
+		__data = rb_entry(*__n, typeof(*new), member);		\
+		int __cmp = compar(new, __data);			\
+									\
+		__parent = *__n;					\
+		if (__cmp < 0)						\
+			__n = &((*__n)->rb_left);			\
+		else if (__cmp > 0)					\
+			__n = &((*__n)->rb_right);			\
+		else {							\
+			__old = __data;					\
+			break;						\
+		}							\
+	}								\
+									\
+	if (__old == NULL) {						\
+		/* Add new node and rebalance tree. */			\
+		rb_link_node(&((new)->member), __parent, __n);		\
+		rb_insert_color(&((new)->member), root);		\
+	}								\
+									\
+	__old;							\
+})
+
+/*
+ * Search for a value in the rbtree.  When the key is not found in the rbtree,
+ * this returns the next greater node. Note, if key > greatest node, we'll
+ * return first node.
+ *
+ * For an empty tree, we return NULL.
+ */
+#define rb_nsearch(root, key, member, compar)                           \
+({                                                                      \
+        struct rb_node *__n = (root)->rb_node;                          \
+        typeof(key) __ret = NULL, __data;                               \
+                                                                        \
+        while (__n) {                                                   \
+                __data = rb_entry(__n, typeof(*key), member);           \
+                int __cmp = compar(key, __data);                        \
+                                                                        \
+                if (__cmp < 0) {                                        \
+                        __ret = __data;                                 \
+                        __n = __n->rb_left;                             \
+                } else if (__cmp > 0)                                   \
+                        __n = __n->rb_right;                            \
+                else {                                                  \
+                        __ret = __data;                                 \
+                        break;                                          \
+                }                                                       \
+        }                                                               \
+        if (!__ret && !RB_EMPTY_ROOT(root))                             \
+                __ret = rb_entry(rb_first(root), typeof(*key), member); \
+        __ret;                                                          \
+})
+
+/* Iterate over a rbtree safe against removal of rbnode */
+#define rb_for_each(pos, root)					\
+	pos = rb_first(root);					\
+	for (struct rb_node *__n = rb_next(pos);		\
+	     pos && ({ __n = rb_next(pos); 1; });		\
+	     pos = __n)
+
+/* Iterate over a rbtree of given type safe against removal of rbnode */
+#define rb_for_each_entry(pos, root, member)				\
+	for (struct rb_node *__pos = rb_first(root), *__n;		\
+	     __pos && ({ __n = rb_next(__pos); 1; }) &&			\
+		     ({ pos =  rb_entry(__pos, typeof(*pos), member); 1; }); \
+	     __pos = __n)
+
+/* Destroy the tree and free the memory */
+#define rb_destroy(root, type, member)                                  \
+{                                                                       \
+        type *__dummy;                                                  \
+        rb_for_each_entry(__dummy, root, member) {                      \
+                rb_erase(&__dummy->member, root);                       \
+                free(__dummy);                                          \
+        }                                                               \
+}
+
 #endif /* __RBTREE_H_ */
-- 
1.7.10.4




More information about the sheepdog-users mailing list