public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Johannes Berg <johannes@sipsolutions.net>
To: "Jörn Engel" <joern@logfs.org>
Cc: linux-kernel@vger.kernel.org
Subject: Re: [RFC] B+Tree library V2
Date: Thu, 08 Jan 2009 01:57:21 +0100	[thread overview]
Message-ID: <1231376241.3545.96.camel@johannes> (raw)
In-Reply-To: <20081101155958.GA28776@logfs.org>

On Sat, 2008-11-01 at 16:59 +0100, Jörn Engel wrote:

[btree library]

Alright, back to this. I'm going to need something like the patch below
(except the update facility, which I thought I needed but then changed
my mind) which is on top of your patch. Does that look sane?

One thing that seems a little odd is requiring a btree_init(), but not
having a btree_destroy(), but rather requiring managing the mempool in
the caller (which invariably leads to two mempool pointers being
required unless callers want to look into the btree struct details)...
Do you think this is required? Could we have a btree_init/btree_destroy
instead that take care of the mempool stuff?

Another thing that I need is a visitor that deletes _some_ entries. How
can I do that? Additionally, it would be nice to be able to abort a tree
walk, when you have determined that you can't continue for whatever
reason.

johannes
---
 include/linux/btree.h |   31 +++++++++++++++++++++++++-
 lib/Kconfig           |    2 -
 lib/btree.c           |   59 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 90 insertions(+), 2 deletions(-)

--- wireless-testing.orig/lib/Kconfig	2009-01-07 22:58:29.000000000 +0100
+++ wireless-testing/lib/Kconfig	2009-01-07 22:58:32.000000000 +0100
@@ -137,7 +137,7 @@ config PLIST
 	boolean
 
 config BTREE
-	boolean
+	tristate
 
 config HAS_IOMEM
 	boolean
--- wireless-testing.orig/lib/btree.c	2009-01-07 22:58:35.000000000 +0100
+++ wireless-testing/lib/btree.c	2009-01-08 00:50:37.000000000 +0100
@@ -47,6 +47,7 @@
 #include <linux/cache.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/module.h>
 
 #define MAX(a, b) ((a) > (b) ? (a) : (b))
 #define NODESIZE MAX(L1_CACHE_BYTES, 128)
@@ -55,17 +56,20 @@ struct btree_geo btree_geo32 = {
 	.keylen = 1,
 	.no_pairs = NODESIZE / sizeof(long) / 2,
 };
+EXPORT_SYMBOL_GPL(btree_geo32);
 
 #define LONG_PER_U64 (64 / BITS_PER_LONG)
 struct btree_geo btree_geo64 = {
 	.keylen = LONG_PER_U64,
 	.no_pairs = NODESIZE / sizeof(long) / (1 + LONG_PER_U64),
 };
+EXPORT_SYMBOL_GPL(btree_geo64);
 
 struct btree_geo btree_geo128 = {
 	.keylen = 2 * LONG_PER_U64,
 	.no_pairs = NODESIZE / sizeof(long) / (1 + 2 * LONG_PER_U64),
 };
+EXPORT_SYMBOL_GPL(btree_geo128);
 
 static struct kmem_cache *btree_cachep;
 
@@ -73,11 +77,13 @@ void *btree_alloc(gfp_t gfp_mask, void *
 {
 	return kmem_cache_alloc(btree_cachep, gfp_mask);
 }
+EXPORT_SYMBOL_GPL(btree_alloc);
 
 void btree_free(void *element, void *pool_data)
 {
 	kmem_cache_free(btree_cachep, element);
 }
+EXPORT_SYMBOL_GPL(btree_free);
 
 static unsigned long *btree_node_alloc(struct btree_head *head)
 {
@@ -217,6 +223,7 @@ void btree_init(struct btree_head *head,
 	head->mempool = mempool;
 	head->gfp_mask = gfp;
 }
+EXPORT_SYMBOL_GPL(btree_init);
 
 unsigned long *btree_last(struct btree_head *head, struct btree_geo *geo)
 {
@@ -231,6 +238,7 @@ unsigned long *btree_last(struct btree_h
 
 	return bkey(geo, node, 0);
 }
+EXPORT_SYMBOL_GPL(btree_last);
 
 static int keycmp(struct btree_geo *geo, unsigned long *node, int pos,
 		unsigned long *key)
@@ -266,6 +274,39 @@ void *btree_lookup(struct btree_head *he
 			return (void *)bval(geo, node, i);
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(btree_lookup);
+
+int btree_update(struct btree_head *head, struct btree_geo *geo,
+		 unsigned long *key, void *val)
+{
+	int i, height = head->height;
+	unsigned long *node = head->node;
+
+	if (height == 0)
+		return -ENOENT;
+
+	for ( ; height > 1; height--) {
+		for (i = 0; i < geo->no_pairs; i++)
+			if (keycmp(geo, node, i, key) <= 0)
+				break;
+		if (i == geo->no_pairs)
+			return -ENOENT;
+		node = (unsigned long *)bval(geo, node, i);
+		if (!node)
+			return -ENOENT;
+	}
+
+	if (!node)
+		return -ENOENT;
+
+	for (i = 0; i < geo->no_pairs; i++)
+		if (keycmp(geo, node, i, key) == 0) {
+			setval(geo, node, (unsigned long)val, i);
+			return 0;
+		}
+	return -ENOENT;
+}
+EXPORT_SYMBOL_GPL(btree_update);
 
 static int getpos(struct btree_geo *geo, unsigned long *node,
 		unsigned long *key)
@@ -417,6 +458,7 @@ int btree_insert(struct btree_head *head
 {
 	return btree_insert_level(head, geo, key, (unsigned long)val, 1);
 }
+EXPORT_SYMBOL_GPL(btree_insert);
 
 static void *btree_remove_level(struct btree_head *head, struct btree_geo *geo,
 		unsigned long *key, int level);
@@ -527,6 +569,7 @@ void *btree_remove(struct btree_head *he
 
 	return btree_remove_level(head, geo, key, 1);
 }
+EXPORT_SYMBOL_GPL(btree_remove);
 
 int btree_merge(struct btree_head *target, struct btree_head *victim,
 		struct btree_geo *geo, unsigned long *duplicate)
@@ -560,6 +603,7 @@ int btree_merge(struct btree_head *targe
 	}
 	return 0;
 }
+EXPORT_SYMBOL_GPL(btree_merge);
 
 static size_t __btree_for_each(struct btree_head *head, struct btree_geo *geo,
 		unsigned long *node, long opaque,
@@ -598,6 +642,7 @@ void visitorl(void *elem, long opaque, u
 
 	func(elem, opaque, *key, index);
 }
+EXPORT_SYMBOL_GPL(visitorl);
 
 void visitor32(void *elem, long opaque, unsigned long *__key, size_t index,
 		void *__func)
@@ -607,6 +652,7 @@ void visitor32(void *elem, long opaque, 
 
 	func(elem, opaque, *key, index);
 }
+EXPORT_SYMBOL_GPL(visitor32);
 
 void visitor64(void *elem, long opaque, unsigned long *__key, size_t index,
 		void *__func)
@@ -616,6 +662,7 @@ void visitor64(void *elem, long opaque, 
 
 	func(elem, opaque, *key, index);
 }
+EXPORT_SYMBOL_GPL(visitor64);
 
 void visitor128(void *elem, long opaque, unsigned long *__key, size_t index,
 		void *__func)
@@ -625,6 +672,7 @@ void visitor128(void *elem, long opaque,
 
 	func(elem, opaque, key[0], key[1], index);
 }
+EXPORT_SYMBOL_GPL(visitor128);
 
 size_t btree_visitor(struct btree_head *head, struct btree_geo *geo,
 		long opaque,
@@ -640,6 +688,7 @@ size_t btree_visitor(struct btree_head *
 				func2, 0, head->height, 0);
 	return count;
 }
+EXPORT_SYMBOL_GPL(btree_visitor);
 
 size_t btree_grim_visitor(struct btree_head *head, struct btree_geo *geo,
 		long opaque,
@@ -656,6 +705,7 @@ size_t btree_grim_visitor(struct btree_h
 	__btree_init(head);
 	return count;
 }
+EXPORT_SYMBOL_GPL(btree_grim_visitor);
 
 static int __init btree_module_init(void)
 {
@@ -664,5 +714,14 @@ static int __init btree_module_init(void
 	return 0;
 }
 
+static void __exit btree_module_exit(void)
+{
+	kmem_cache_destroy(btree_cachep);
+}
+
 /* If core code starts using btree, initialization should happen even earlier */
 module_init(btree_module_init);
+module_exit(btree_module_exit);
+
+MODULE_AUTHOR("Joern Engel <joern@logfs.org>");
+MODULE_LICENSE("GPL");
--- wireless-testing.orig/include/linux/btree.h	2009-01-07 23:16:54.000000000 +0100
+++ wireless-testing/include/linux/btree.h	2009-01-08 00:48:29.000000000 +0100
@@ -43,6 +43,8 @@ void *btree_lookup(struct btree_head *he
 		unsigned long *key);
 int btree_insert(struct btree_head *head, struct btree_geo *geo,
 		unsigned long *key, void *val);
+int btree_update(struct btree_head *head, struct btree_geo *geo,
+		 unsigned long *key, void *val);
 void *btree_remove(struct btree_head *head, struct btree_geo *geo,
 		unsigned long *key);
 int btree_merge(struct btree_head *target, struct btree_head *victim,
@@ -75,6 +77,12 @@ static inline int btree_insertl(struct b
 	return btree_insert(&head->h, &btree_geo32, &key, val);
 }
 
+static inline int btree_updatel(struct btree_headl *head, unsigned long key,
+		void *val)
+{
+	return btree_update(&head->h, &btree_geo32, &key, val);
+}
+
 static inline void *btree_removel(struct btree_headl *head, unsigned long key)
 {
 	return btree_remove(&head->h, &btree_geo32, &key);
@@ -124,6 +132,12 @@ static inline int btree_insert32(struct 
 	return btree_insert(&head->h, &btree_geo32, (unsigned long *)&key, val);
 }
 
+static inline int btree_update32(struct btree_head32 *head, u32 key,
+		void *val)
+{
+	return btree_update(&head->h, &btree_geo32, (unsigned long *)&key, val);
+}
+
 static inline void *btree_remove32(struct btree_head32 *head, u32 key)
 {
 	return btree_remove(&head->h, &btree_geo32, (unsigned long *)&key);
@@ -172,6 +186,12 @@ static inline int btree_insert64(struct 
 	return btree_insert(&head->h, &btree_geo64, (unsigned long *)&key, val);
 }
 
+static inline int btree_update64(struct btree_head64 *head, u64 key,
+		void *val)
+{
+	return btree_update(&head->h, &btree_geo64, (unsigned long *)&key, val);
+}
+
 static inline void *btree_remove64(struct btree_head64 *head, u64 key)
 {
 	return btree_remove(&head->h, &btree_geo64, (unsigned long *)&key);
@@ -220,7 +240,16 @@ static inline int btree_insert128(struct
 		void *val)
 {
 	u64 key[2] = {k1, k2};
-	return btree_insert(&head->h, &btree_geo128, (unsigned long *)&key, val);
+	return btree_insert(&head->h, &btree_geo128,
+			    (unsigned long *)&key, val);
+}
+
+static inline int btree_update128(struct btree_head128 *head, u64 k1, u64 k2,
+		void *val)
+{
+	u64 key[2] = {k1, k2};
+	return btree_update(&head->h, &btree_geo128,
+			    (unsigned long *)&key, val);
 }
 
 static inline void *btree_remove128(struct btree_head128 *head, u64 k1, u64 k2)



  parent reply	other threads:[~2009-01-08 12:03 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-10-26 12:46 [RFC] B+Tree library Jörn Engel
2008-10-28  1:25 ` Dave Chinner
2008-10-30 17:43 ` Pavel Machek
2008-10-30 17:58   ` Jörn Engel
2008-10-30 19:14     ` Pavel Machek
2008-10-30 20:20       ` Jörn Engel
2008-10-31  6:38     ` Christian Borntraeger
2008-10-31  7:35       ` Jörn Engel
2008-10-31  9:16         ` Geert Uytterhoeven
2008-10-31  9:20           ` Jörn Engel
2008-10-31 10:35 ` Johannes Berg
2008-10-31 11:26   ` Jörn Engel
2008-10-31 11:32     ` Johannes Berg
2008-10-31 12:54       ` Jörn Engel
2008-10-31 13:07         ` Johannes Berg
2008-10-31 13:15           ` Jörn Engel
2008-11-01 15:59         ` [RFC] B+Tree library V2 Jörn Engel
2008-11-05 19:57           ` Johannes Berg
2008-11-05 20:06             ` Jörn Engel
2008-11-05 20:12               ` Johannes Berg
2008-11-05 20:21                 ` Jörn Engel
2008-11-05 20:25                   ` Johannes Berg
2008-11-07  7:52                     ` Jörn Engel
2009-01-08  0:57           ` Johannes Berg [this message]
2009-01-08 16:24             ` Jörn Engel
2009-01-08 16:34               ` Johannes Berg
2009-01-08 19:40                 ` Jörn Engel
2009-01-08 16:50               ` Johannes Berg
2009-01-08 19:46                 ` Jörn Engel
2009-01-08 17:10               ` Johannes Berg
2009-01-08 20:02                 ` Jörn Engel
2009-01-08 20:18                   ` Johannes Berg
2009-01-08 21:09                     ` Jörn Engel
2008-10-31 13:16 ` [RFC] B+Tree library Johannes Berg
2008-10-31 13:29   ` Jörn Engel
2008-10-31 13:45   ` Bert Wesarg
2008-10-31 15:18   ` Tim Gardner
2008-10-31 15:35     ` Jörn Engel
2008-10-31 20:17 ` Sean Young
2008-10-31 23:36   ` Jörn Engel
2008-11-01 10:17     ` Sean Young

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=1231376241.3545.96.camel@johannes \
    --to=johannes@sipsolutions.net \
    --cc=joern@logfs.org \
    --cc=linux-kernel@vger.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox