All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kent Overstreet <koverstreet@google.com>
To: linux-kernel@vger.kernel.org, linux-bcache@vger.kernel.org
Cc: Kent Overstreet <koverstreet@google.com>,
	tj@kernel.org, axboe@kernel.dk, paul.gortmaker@windriver.com
Subject: [PATCH 1/3] rbtree: Add rb_insert(), rb_search(), etc.
Date: Fri, 25 May 2012 13:57:39 -0700	[thread overview]
Message-ID: <1337979461-19654-2-git-send-email-koverstreet@google.com> (raw)
In-Reply-To: <1337979461-19654-1-git-send-email-koverstreet@google.com>

Change-Id: I072d94a42b75454aa62be849c724980d27523b08

Signed-off-by: Kent Overstreet <koverstreet@google.com>
---
 include/linux/rbtree.h |  110 ++++++++++++++++++++++++++++++++++++++++++++++++
 lib/rbtree.c           |   28 ++++++++++++
 2 files changed, 138 insertions(+)

diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h
index 033b507..4447919 100644
--- a/include/linux/rbtree.h
+++ b/include/linux/rbtree.h
@@ -174,4 +174,114 @@ static inline void rb_link_node(struct rb_node * node, struct rb_node * parent,
 	*rb_link = node;
 }
 
+typedef int (rb_cmp_t) (struct rb_node *l, struct rb_node *r);
+
+static inline int _rb_insert(struct rb_root *root,
+			     struct rb_node *new,
+			     rb_cmp_t cmp)
+{
+	struct rb_node **n = &root->rb_node, *parent = NULL;
+	int res;
+
+	while (*n) {
+		parent = *n;
+		res = cmp(new, *n);
+		if (!res)
+			return -1;
+		n = res < 0
+			? &(*n)->rb_left
+			: &(*n)->rb_right;
+	}
+
+	rb_link_node(new, parent, n);
+	rb_insert_color(new, root);
+	return 0;
+}
+
+static inline void _rb_insert_allow_dup(struct rb_root *root,
+				       struct rb_node *new,
+				       rb_cmp_t cmp)
+{
+	struct rb_node **n = &root->rb_node, *parent = NULL;
+
+	while (*n) {
+		parent = *n;
+		n = cmp(new, *n) < 0
+			? &(*n)->rb_left
+			: &(*n)->rb_right;
+	}
+
+	rb_link_node(new, parent, n);
+	rb_insert_color(new, root);
+}
+
+static inline struct rb_node *_rb_search(struct rb_root *root,
+					 struct rb_node *search,
+					 rb_cmp_t cmp)
+{
+	struct rb_node *n = root->rb_node;
+
+	while (n) {
+		int res = cmp(search, n);
+		if (!res)
+			return n;
+
+		n = res < 0
+			? n->rb_left
+			: n->rb_right;
+	}
+
+	return NULL;
+}
+
+static inline struct rb_node *_rb_greater(struct rb_root *root,
+					  struct rb_node *search,
+					  rb_cmp_t cmp)
+{
+	struct rb_node *n = root->rb_node;
+	struct rb_node *ret = NULL;
+
+	while (n) {
+		int res = cmp(search, n);
+
+		if (res < 0) {
+			ret = n;
+			n = n->rb_left;
+		} else {
+			n = n->rb_right;
+		}
+	}
+
+	return ret;
+}
+
+int rb_insert(struct rb_root *root, struct rb_node *new, rb_cmp_t cmp);
+void rb_insert_allow_dup(struct rb_root *root,
+			 struct rb_node *new,
+			 rb_cmp_t cmp);
+struct rb_node *rb_search(struct rb_root *root,
+			  struct rb_node *search,
+			  rb_cmp_t cmp);
+struct rb_node *rb_greater(struct rb_root *root,
+			   struct rb_node *search,
+			   rb_cmp_t cmp);
+
+#define container_of_or_null(ptr, type, member)				\
+({									\
+	typeof(ptr) _ptr = ptr;						\
+	_ptr ? container_of(_ptr, type, member) : NULL;			\
+})
+
+#define RB_FIRST(root, type, member)					\
+	container_of_or_null(rb_first(root), type, member)
+
+#define RB_LAST(root, type, member)					\
+	container_of_or_null(rb_last(root), type, member)
+
+#define RB_NEXT(ptr, member)						\
+	container_of_or_null(rb_next(&(ptr)->member), typeof(*ptr), member)
+
+#define RB_PREV(ptr, member)						\
+	container_of_or_null(rb_prev(&(ptr)->member), typeof(*ptr), member)
+
 #endif	/* _LINUX_RBTREE_H */
diff --git a/lib/rbtree.c b/lib/rbtree.c
index d417556..53641b7 100644
--- a/lib/rbtree.c
+++ b/lib/rbtree.c
@@ -135,6 +135,34 @@ void rb_insert_color(struct rb_node *node, struct rb_root *root)
 }
 EXPORT_SYMBOL(rb_insert_color);
 
+int rb_insert(struct rb_root *root, struct rb_node *new, rb_cmp_t cmp)
+{
+	return _rb_insert(root, new, cmp);
+}
+EXPORT_SYMBOL(rb_insert);
+
+void rb_insert_allow_dup(struct rb_root *root, struct rb_node *new, rb_cmp_t cmp)
+{
+	_rb_insert_allow_dup(root, new, cmp);
+}
+EXPORT_SYMBOL(rb_insert_allow_dup);
+
+struct rb_node *rb_search(struct rb_root *root,
+			  struct rb_node *search,
+			  rb_cmp_t cmp)
+{
+	return _rb_search(root, search, cmp);
+}
+EXPORT_SYMBOL(rb_search);
+
+struct rb_node *rb_greater(struct rb_root *root,
+			   struct rb_node *search,
+			   rb_cmp_t cmp)
+{
+	return _rb_greater(root, search, cmp);
+}
+EXPORT_SYMBOL(rb_greater);
+
 static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
 			     struct rb_root *root)
 {
-- 
1.7.9.3.327.g2980b

  reply	other threads:[~2012-05-25 20:57 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-05-25 20:57 [PATCH 0/3] Generic rb tree code Kent Overstreet
2012-05-25 20:57 ` Kent Overstreet [this message]
     [not found]   ` <1337979461-19654-2-git-send-email-koverstreet-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2012-05-28 23:35     ` [PATCH 1/3] rbtree: Add rb_insert(), rb_search(), etc Tejun Heo
2012-05-28 23:35       ` Tejun Heo
2012-05-25 20:57 ` [PATCH 2/3] timerqueue: convert to generic rb tree code Kent Overstreet
2012-05-25 20:57 ` [PATCH 3/3] block: convert elevator " Kent Overstreet
     [not found]   ` <1337979461-19654-4-git-send-email-koverstreet-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2012-05-28 23:17     ` Tejun Heo
2012-05-28 23:17       ` Tejun Heo
2012-05-29  3:25       ` Kent Overstreet
     [not found]         ` <20120529032502.GA10175-RcKxWJ4Cfj3IzGYXcIpNmNLIRw13R84JkQQo+JxHRPFibQn6LdNjmg@public.gmane.org>
2012-05-29  5:24           ` Tejun Heo
2012-05-29  5:24             ` Tejun Heo
     [not found]             ` <20120529052458.GA17366-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2012-05-29  6:57               ` Kent Overstreet
2012-05-29  6:57                 ` Kent Overstreet
     [not found] ` <1337979461-19654-1-git-send-email-koverstreet-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2012-05-28 23:22   ` [PATCH 0/3] Generic " Tejun Heo
2012-05-28 23:22     ` Tejun Heo
     [not found]     ` <20120528232246.GC20954-RcKxWJ4Cfj1J2suj2OqeGauc2jM2gXBXkQQo+JxHRPFibQn6LdNjmg@public.gmane.org>
2012-05-29  3:30       ` Kent Overstreet
2012-05-29  3:30         ` Kent Overstreet
     [not found]         ` <20120529033032.GB10175-RcKxWJ4Cfj3IzGYXcIpNmNLIRw13R84JkQQo+JxHRPFibQn6LdNjmg@public.gmane.org>
2012-05-29  5:28           ` Tejun Heo
2012-05-29  5:28             ` Tejun Heo
2012-05-31 21:03   ` Jan Kara
2012-05-31 21:03     ` Jan Kara

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1337979461-19654-2-git-send-email-koverstreet@google.com \
    --to=koverstreet@google.com \
    --cc=axboe@kernel.dk \
    --cc=linux-bcache@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=paul.gortmaker@windriver.com \
    --cc=tj@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.