* AVL trees vs. Red-Black trees
@ 1999-11-27 12:59 Kevin O'Connor
1999-11-28 2:57 ` Andrea Arcangeli
0 siblings, 1 reply; 8+ messages in thread
From: Kevin O'Connor @ 1999-11-27 12:59 UTC (permalink / raw)
To: linux-mm
Hi,
I've been spending the last few days "kicking around" different ideas for
implementing reusable data structures in C. That is, generic hash tables,
linked lists, trees, etc.
I was planning on hacking up a kernel with a generic tree implementation.
(Right now there are two AVL trees in the kernel - one in the MM code and a
copy in the net/bridge code.)
I was a little surprised to see that the MM code uses an AVL tree - my old
textbooks are of the opinion that Red-Black trees are superior.
Implementing the code to create a stack for performing "bottom-up"
insertions/deletions seems like a pain to me. I would think the "top-down"
approach of a Red-Black tree would be more efficient and probably simpler
to implement.
So my question is, was there a particular reason AVL trees were chosen, or
would any balanced tree implementation suffice?
-Kevin
--
------------------------------------------------------------------------
| Kevin O'Connor "BTW, IMHO we need a FAQ for |
| koconnor@cse.buffalo.edu 'IMHO', 'FAQ', 'BTW', etc. !" |
------------------------------------------------------------------------
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://humbolt.geo.uu.nl/Linux-MM/
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: AVL trees vs. Red-Black trees
1999-11-27 12:59 AVL trees vs. Red-Black trees Kevin O'Connor
@ 1999-11-28 2:57 ` Andrea Arcangeli
1999-11-28 5:29 ` Oliver Xymoron
0 siblings, 1 reply; 8+ messages in thread
From: Andrea Arcangeli @ 1999-11-28 2:57 UTC (permalink / raw)
To: Kevin O'Connor; +Cc: linux-mm, linux-kernel
On Sat, 27 Nov 1999, Kevin O'Connor wrote:
>I was a little surprised to see that the MM code uses an AVL tree - my old
>textbooks are of the opinion that Red-Black trees are superior.
You basically do a query for each page fault and an insert for each mmap
and a remove for each munmap thus AVL gives better performances.
>Implementing the code to create a stack for performing "bottom-up"
>insertions/deletions seems like a pain to me. I would think the "top-down"
>approach of a Red-Black tree would be more efficient and probably simpler
>to implement.
I just implemented RB trees in the kernel with a reusable implementation
exactly like include/linux/list.h for the lists.
If somebody find this interesting I can provide a patch to add the
include/linux/rbtree.h and lib/rbtree.c that will provde rbtree support.
Andrea
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://humbolt.geo.uu.nl/Linux-MM/
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: AVL trees vs. Red-Black trees
1999-11-28 2:57 ` Andrea Arcangeli
@ 1999-11-28 5:29 ` Oliver Xymoron
1999-11-29 15:54 ` [patch] rbtrees [was Re: AVL trees vs. Red-Black trees] Andrea Arcangeli
0 siblings, 1 reply; 8+ messages in thread
From: Oliver Xymoron @ 1999-11-28 5:29 UTC (permalink / raw)
To: Andrea Arcangeli; +Cc: Kevin O'Connor, linux-mm, linux-kernel
On Sun, 28 Nov 1999, Andrea Arcangeli wrote:
> On Sat, 27 Nov 1999, Kevin O'Connor wrote:
>
> >I was a little surprised to see that the MM code uses an AVL tree - my old
> >textbooks are of the opinion that Red-Black trees are superior.
>
> You basically do a query for each page fault and an insert for each mmap
> and a remove for each munmap thus AVL gives better performances.
>
> >Implementing the code to create a stack for performing "bottom-up"
> >insertions/deletions seems like a pain to me. I would think the "top-down"
> >approach of a Red-Black tree would be more efficient and probably simpler
> >to implement.
>
> I just implemented RB trees in the kernel with a reusable implementation
> exactly like include/linux/list.h for the lists.
>
> If somebody find this interesting I can provide a patch to add the
> include/linux/rbtree.h and lib/rbtree.c that will provde rbtree support.
I'd like to take a look at this, I've been looking at putting some more
uniform tree structures in the kernel (post 2.4).
--
"Love the dolphins," she advised him. "Write by W.A.S.T.E.."
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://humbolt.geo.uu.nl/Linux-MM/
^ permalink raw reply [flat|nested] 8+ messages in thread
* [patch] rbtrees [was Re: AVL trees vs. Red-Black trees]
1999-11-28 5:29 ` Oliver Xymoron
@ 1999-11-29 15:54 ` Andrea Arcangeli
1999-11-29 19:18 ` Manfred Spraul
0 siblings, 1 reply; 8+ messages in thread
From: Andrea Arcangeli @ 1999-11-29 15:54 UTC (permalink / raw)
To: Oliver Xymoron
Cc: Kevin O'Connor, linux-mm, linux-kernel, Marc Lehmann, Linus Torvalds
On Sat, 27 Nov 1999, Oliver Xymoron wrote:
>I'd like to take a look at this, I've been looking at putting some more
>uniform tree structures in the kernel (post 2.4).
This patch will add btree support to linux. I extracted it from my old
patches. I think it could be added also in the stock kernel so if somebody
needs rbtrees, he won't have to reinvent the wheel each time ;). The patch
is against 2.3.30pre3.
diff -urN 2.3.30pre3/include/linux/rbtree.h 2.3.30pre3-rbtree/include/linux/rbtree.h
--- 2.3.30pre3/include/linux/rbtree.h Thu Jan 1 01:00:00 1970
+++ 2.3.30pre3-rbtree/include/linux/rbtree.h Mon Nov 29 16:33:26 1999
@@ -0,0 +1,128 @@
+/*
+ Red Black Trees
+ (C) 1999 Andrea Arcangeli <andrea@suse.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ linux/include/linux/rbtree.h
+
+ To use rbtrees you'll have to implement your own insert and search cores.
+ This will avoid us to use callbacks and to drop drammatically performances.
+ I know it's not the cleaner way, but in C (not in C++) to get
+ performances and genericity...
+
+ Some example of insert and search follows here. The search is a plain
+ normal search over an ordered tree. The insert instead must be implemented
+ int two steps: as first thing the code must insert the element in
+ order as a red leaf in the tree, then the support library function
+ rb_insert_color() must be called. Such function will do the
+ not trivial work to rebalance the rbtree if necessary.
+
+-----------------------------------------------------------------------
+static inline struct page * rb_search_page_cache(struct inode * inode,
+ unsigned long offset)
+{
+ rb_node_t * n = inode->i_rb_page_cache.rb_node;
+ struct page * page;
+
+ while (n)
+ {
+ page = rb_entry(n, struct page, rb_page_cache);
+
+ if (offset < page->offset)
+ n = n->rb_left;
+ else if (offset > page->offset)
+ n = n->rb_right;
+ else
+ return page;
+ }
+ return NULL;
+}
+
+static inline struct page * __rb_insert_page_cache(struct inode * inode,
+ unsigned long offset,
+ rb_node_t * node)
+{
+ rb_node_t ** p = &inode->i_rb_page_cache.rb_node;
+ rb_node_t * parent = NULL;
+ struct page * page;
+
+ while (*p)
+ {
+ parent = *p;
+ page = rb_entry(parent, struct page, rb_page_cache);
+
+ if (offset < page->offset)
+ p = &(*p)->rb_left;
+ else if (offset > page->offset)
+ p = &(*p)->rb_right;
+ else
+ return page;
+ }
+
+ node->rb_parent = parent;
+ node->rb_color = RB_RED;
+ node->rb_left = node->rb_right = NULL;
+
+ *p = node;
+
+ return NULL;
+}
+
+static inline struct page * rb_insert_page_cache(struct inode * inode,
+ unsigned long offset,
+ rb_node_t * node)
+{
+ struct page * ret;
+ if ((ret = __rb_insert_page_cache(inode, offset, node)))
+ goto out;
+ rb_insert_color(node, &inode->i_rb_page_cache);
+ out:
+ return ret;
+}
+-----------------------------------------------------------------------
+*/
+
+#ifndef _LINUX_RBTREE_H
+#define _LINUX_RBTREE_H
+
+#include <linux/kernel.h>
+#include <linux/stddef.h>
+
+typedef struct rb_node_s
+{
+ struct rb_node_s * rb_parent;
+ int rb_color;
+#define RB_RED 0
+#define RB_BLACK 1
+ struct rb_node_s * rb_right;
+ struct rb_node_s * rb_left;
+}
+rb_node_t;
+
+typedef struct rb_root_s
+{
+ struct rb_node_s * rb_node;
+}
+rb_root_t;
+
+#define RB_ROOT (rb_root_t) { NULL, }
+#define rb_entry(ptr, type, member) \
+ ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
+
+extern void rb_insert_color(rb_node_t *, rb_root_t *);
+extern void rb_erase(rb_node_t *, rb_root_t *);
+
+#endif /* _LINUX_RBTREE_H */
diff -urN 2.3.30pre3/lib/Makefile 2.3.30pre3-rbtree/lib/Makefile
--- 2.3.30pre3/lib/Makefile Mon Jan 18 02:27:00 1999
+++ 2.3.30pre3-rbtree/lib/Makefile Mon Nov 29 16:22:36 1999
@@ -7,6 +7,6 @@
#
L_TARGET := lib.a
-L_OBJS := errno.o ctype.o string.o vsprintf.o
+L_OBJS := errno.o ctype.o string.o vsprintf.o rbtree.o
include $(TOPDIR)/Rules.make
diff -urN 2.3.30pre3/lib/rbtree.c 2.3.30pre3-rbtree/lib/rbtree.c
--- 2.3.30pre3/lib/rbtree.c Thu Jan 1 01:00:00 1970
+++ 2.3.30pre3-rbtree/lib/rbtree.c Mon Nov 29 16:31:37 1999
@@ -0,0 +1,293 @@
+/*
+ Red Black Trees
+ (C) 1999 Andrea Arcangeli <andrea@suse.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ linux/lib/rbtree.c
+*/
+
+#include <linux/rbtree.h>
+
+static void __rb_rotate_left(rb_node_t * node, rb_root_t * root)
+{
+ rb_node_t * right = node->rb_right;
+
+ if ((node->rb_right = right->rb_left))
+ right->rb_left->rb_parent = node;
+ right->rb_left = node;
+
+ if ((right->rb_parent = node->rb_parent))
+ {
+ if (node == node->rb_parent->rb_left)
+ node->rb_parent->rb_left = right;
+ else
+ node->rb_parent->rb_right = right;
+ }
+ else
+ root->rb_node = right;
+ node->rb_parent = right;
+}
+
+static void __rb_rotate_right(rb_node_t * node, rb_root_t * root)
+{
+ rb_node_t * left = node->rb_left;
+
+ if ((node->rb_left = left->rb_right))
+ left->rb_right->rb_parent = node;
+ left->rb_right = node;
+
+ if ((left->rb_parent = node->rb_parent))
+ {
+ if (node == node->rb_parent->rb_right)
+ node->rb_parent->rb_right = left;
+ else
+ node->rb_parent->rb_left = left;
+ }
+ else
+ root->rb_node = left;
+ node->rb_parent = left;
+}
+
+void rb_insert_color(rb_node_t * node, rb_root_t * root)
+{
+ rb_node_t * parent, * gparent;
+
+ while ((parent = node->rb_parent) && parent->rb_color == RB_RED)
+ {
+ gparent = parent->rb_parent;
+
+ if (parent == gparent->rb_left)
+ {
+ {
+ register rb_node_t * uncle = gparent->rb_right;
+ if (uncle && uncle->rb_color == RB_RED)
+ {
+ uncle->rb_color = RB_BLACK;
+ parent->rb_color = RB_BLACK;
+ gparent->rb_color = RB_RED;
+ node = gparent;
+ continue;
+ }
+ }
+
+ if (parent->rb_right == node)
+ {
+ register rb_node_t * tmp;
+ __rb_rotate_left(parent, root);
+ tmp = parent;
+ parent = node;
+ node = tmp;
+ }
+
+ parent->rb_color = RB_BLACK;
+ gparent->rb_color = RB_RED;
+ __rb_rotate_right(gparent, root);
+ } else {
+ {
+ register rb_node_t * uncle = gparent->rb_left;
+ if (uncle && uncle->rb_color == RB_RED)
+ {
+ uncle->rb_color = RB_BLACK;
+ parent->rb_color = RB_BLACK;
+ gparent->rb_color = RB_RED;
+ node = gparent;
+ continue;
+ }
+ }
+
+ if (parent->rb_left == node)
+ {
+ register rb_node_t * tmp;
+ __rb_rotate_right(parent, root);
+ tmp = parent;
+ parent = node;
+ node = tmp;
+ }
+
+ parent->rb_color = RB_BLACK;
+ gparent->rb_color = RB_RED;
+ __rb_rotate_left(gparent, root);
+ }
+ }
+
+ root->rb_node->rb_color = RB_BLACK;
+}
+
+static void __rb_erase_color(rb_node_t * node, rb_node_t * parent,
+ rb_root_t * root)
+{
+ rb_node_t * other;
+
+ while ((!node || node->rb_color == RB_BLACK) && node != root->rb_node)
+ {
+ if (parent->rb_left == node)
+ {
+ other = parent->rb_right;
+ if (other->rb_color == RB_RED)
+ {
+ other->rb_color = RB_BLACK;
+ parent->rb_color = RB_RED;
+ __rb_rotate_left(parent, root);
+ other = parent->rb_right;
+ }
+ if ((!other->rb_left ||
+ other->rb_left->rb_color == RB_BLACK)
+ && (!other->rb_right ||
+ other->rb_right->rb_color == RB_BLACK))
+ {
+ other->rb_color = RB_RED;
+ node = parent;
+ parent = node->rb_parent;
+ }
+ else
+ {
+ if (!other->rb_right ||
+ other->rb_right->rb_color == RB_BLACK)
+ {
+ register rb_node_t * o_left;
+ if ((o_left = other->rb_left))
+ o_left->rb_color = RB_BLACK;
+ other->rb_color = RB_RED;
+ __rb_rotate_right(other, root);
+ other = parent->rb_right;
+ }
+ other->rb_color = parent->rb_color;
+ parent->rb_color = RB_BLACK;
+ if (other->rb_right)
+ other->rb_right->rb_color = RB_BLACK;
+ __rb_rotate_left(parent, root);
+ node = root->rb_node;
+ break;
+ }
+ }
+ else
+ {
+ other = parent->rb_left;
+ if (other->rb_color == RB_RED)
+ {
+ other->rb_color = RB_BLACK;
+ parent->rb_color = RB_RED;
+ __rb_rotate_right(parent, root);
+ other = parent->rb_left;
+ }
+ if ((!other->rb_left ||
+ other->rb_left->rb_color == RB_BLACK)
+ && (!other->rb_right ||
+ other->rb_right->rb_color == RB_BLACK))
+ {
+ other->rb_color = RB_RED;
+ node = parent;
+ parent = node->rb_parent;
+ }
+ else
+ {
+ if (!other->rb_left ||
+ other->rb_left->rb_color == RB_BLACK)
+ {
+ register rb_node_t * o_right;
+ if ((o_right = other->rb_right))
+ o_right->rb_color = RB_BLACK;
+ other->rb_color = RB_RED;
+ __rb_rotate_left(other, root);
+ other = parent->rb_left;
+ }
+ other->rb_color = parent->rb_color;
+ parent->rb_color = RB_BLACK;
+ if (other->rb_left)
+ other->rb_left->rb_color = RB_BLACK;
+ __rb_rotate_right(parent, root);
+ node = root->rb_node;
+ break;
+ }
+ }
+ }
+ if (node)
+ node->rb_color = RB_BLACK;
+}
+
+void rb_erase(rb_node_t * node, rb_root_t * root)
+{
+ rb_node_t * child, * parent;
+ int color;
+
+ if (!node->rb_left)
+ child = node->rb_right;
+ else if (!node->rb_right)
+ child = node->rb_left;
+ else
+ {
+ rb_node_t * old = node, * left;
+
+ node = node->rb_right;
+ while ((left = node->rb_left))
+ node = left;
+ child = node->rb_right;
+ parent = node->rb_parent;
+ color = node->rb_color;
+
+ if (child)
+ child->rb_parent = parent;
+ if (parent)
+ {
+ if (parent->rb_left == node)
+ parent->rb_left = child;
+ else
+ parent->rb_right = child;
+ }
+ else
+ root->rb_node = child;
+
+ if (node->rb_parent == old)
+ parent = node;
+ node->rb_parent = old->rb_parent;
+ node->rb_color = old->rb_color;
+ node->rb_right = old->rb_right;
+ node->rb_left = old->rb_left;
+
+ if (old->rb_parent)
+ {
+ if (old->rb_parent->rb_left == old)
+ old->rb_parent->rb_left = node;
+ else
+ old->rb_parent->rb_right = node;
+ } else
+ root->rb_node = node;
+
+ old->rb_left->rb_parent = node;
+ if (old->rb_right)
+ old->rb_right->rb_parent = node;
+ goto color;
+ }
+
+ parent = node->rb_parent;
+ color = node->rb_color;
+
+ if (child)
+ child->rb_parent = parent;
+ if (parent)
+ {
+ if (parent->rb_left == node)
+ parent->rb_left = child;
+ else
+ parent->rb_right = child;
+ }
+ else
+ root->rb_node = child;
+
+ color:
+ if (color == RB_BLACK)
+ __rb_erase_color(child, parent, root);
+}
Downloadable also from:
ftp://ftp.*.kernel.org/pub/linux/kernel/people/andrea/patches/v2.3/2.3.30pre3/rbtree-1.bz2
Andrea
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://humbolt.geo.uu.nl/Linux-MM/
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [patch] rbtrees [was Re: AVL trees vs. Red-Black trees]
1999-11-29 19:18 ` Manfred Spraul
@ 1999-11-29 19:17 ` Andrea Arcangeli
1999-11-30 5:27 ` Kevin O'Connor
1 sibling, 0 replies; 8+ messages in thread
From: Andrea Arcangeli @ 1999-11-29 19:17 UTC (permalink / raw)
To: Manfred Spraul
Cc: Oliver Xymoron, Kevin O'Connor, linux-mm, linux-kernel,
Marc Lehmann, Linus Torvalds
On Mon, 29 Nov 1999, Manfred Spraul wrote:
>What about something similar to the "end_request()" implementation?
Personally I don't cosider that very nicer. Also look at what I am doing
in the insert, my insert also does a query, you may also do differnet
things.
But if you think it worth, I can implement that of course.
Andrea
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://humbolt.geo.uu.nl/Linux-MM/
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [patch] rbtrees [was Re: AVL trees vs. Red-Black trees]
1999-11-29 15:54 ` [patch] rbtrees [was Re: AVL trees vs. Red-Black trees] Andrea Arcangeli
@ 1999-11-29 19:18 ` Manfred Spraul
1999-11-29 19:17 ` Andrea Arcangeli
1999-11-30 5:27 ` Kevin O'Connor
0 siblings, 2 replies; 8+ messages in thread
From: Manfred Spraul @ 1999-11-29 19:18 UTC (permalink / raw)
To: Andrea Arcangeli
Cc: Oliver Xymoron, Kevin O'Connor, linux-mm, linux-kernel,
Marc Lehmann, Linus Torvalds
Andrea Arcangeli wrote:
> + To use rbtrees you'll have to implement your own insert and search cores.
> + This will avoid us to use callbacks and to drop drammatically performances.
> + I know it's not the cleaner way, but in C (not in C++) to get
> + performances and genericity...
> +
> + Some example of insert and search follows here. The search is a plain
> + normal search over an ordered tree. The insert instead must be implemented
> + int two steps: as first thing the code must insert the element in
> + order as a red leaf in the tree, then the support library function
> + rb_insert_color() must be called. Such function will do the
> + not trivial work to rebalance the rbtree if necessary.
What about something similar to the "end_request()" implementation?
ie you #define a name and the (inline) compare function, then you
#include <rbtree.h>. <rbtree.h> creates all functions that you need.
--
Manfred
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://humbolt.geo.uu.nl/Linux-MM/
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [patch] rbtrees [was Re: AVL trees vs. Red-Black trees]
1999-11-29 19:18 ` Manfred Spraul
1999-11-29 19:17 ` Andrea Arcangeli
@ 1999-11-30 5:27 ` Kevin O'Connor
1999-11-30 14:14 ` Andrea Arcangeli
1 sibling, 1 reply; 8+ messages in thread
From: Kevin O'Connor @ 1999-11-30 5:27 UTC (permalink / raw)
To: Manfred Spraul
Cc: Andrea Arcangeli, Oliver Xymoron, Kevin O'Connor, linux-mm,
linux-kernel, Marc Lehmann, Linus Torvalds
On Mon, Nov 29, 1999 at 08:18:17PM +0100, Manfred Spraul wrote:
> What about something similar to the "end_request()" implementation?
>
> ie you #define a name and the (inline) compare function, then you
> #include <rbtree.h>. <rbtree.h> creates all functions that you need.
I don't much like this method - IMO, it obfuscates the #include directive.
That said, however, I implemented a generic AVL tree implementation using a
similar idea. Basically, I define a couple of MACROs: AVL_FIND and
AVL_FINDWITHSTACK (needed by AVL trees to do a bottom-up insert/delete).
These macros take a compare function as a parameter. If the compare
function is declared as inline, or if it is a macro, it will be compiled
inline and without the overhead of a call instruction.
I'm including a sample usage, plus an excerpt from my avltree.h header file
- just to give a sample of how I would implement generic trees.
I can provide more code upon request. I've got inserts working, but
removes are becoming a myriad of special cases..
Note: I tried to be "clever", and store the tree height in the low-order
bytes of a pointer. It works, but it's pretty ugly.
-Kevin
============= Sample application usage ===============
struct hrmm {
int num;
avl_node_t treenode;
};
static inline int
mycmp(avl_node_t *x, avl_node_t *y)
{
int a,b;
a = avl_entry(x, struct hrmm, treenode)->num;
b = avl_entry(y, struct hrmm, treenode)->num;
return (a < b ? -1 : a > b ? 1 : 0);
}
int
my_insert(avl_node_t **tree, struct hrmm *node)
{
return AVL_INSERT(tree,&node->treenode,mycmp);
}
int
my_remove(avl_node_t **tree, struct hrmm *node)
{
return AVL_REMOVE(tree,&node->treenode,mycmp);
}
struct hrmm *
my_find(avl_node_t *tree, struct hrmm *node)
{
return avl_entry(AVL_FIND(tree,&node->treenode,mycmp)
, struct hrmm, treenode);
}
============= Macros from header file ===============
#define AVL_FIND(__Tree,__Node,__Compare) ({ \
avl_node_t *__tree = (__Tree); \
\
while (__tree) { \
int __compval = __Compare((__Node),__tree); \
\
if (__compval < 0) { \
__tree = getChild(__tree, TREE_LEFT); \
} else if (__compval > 0) { \
__tree = getChild(__tree, TREE_RIGHT); \
} else { \
break; \
} \
} \
__tree;})
#define AVL_FINDWITHSTACK(__TreeP,__Node,__Stack,__Count,__Compare) ({ \
avl_node_t **__tree = (__TreeP), *__tmp; \
avl_dptr_t *__stack = (__Stack); \
int *__count = (__Count), __found=0; \
\
__tmp = *__tree; \
*__count = 0; \
__stack[0] = (avl_dptr_t) __tree; \
while (__tmp) { \
int __compval = __Compare((__Node), __tmp); \
\
if (__compval < 0) { \
(*__count)++; \
setPtr(&__stack[*__count], __tmp, TREE_LEFT); \
__tmp = getChild(__tmp, TREE_LEFT); \
} else if (__compval > 0) { \
(*__count)++; \
setPtr(&__stack[*__count], __tmp, TREE_RIGHT); \
__tmp = getChild(__tmp, TREE_RIGHT); \
} else { \
__found = 1; \
break; \
} \
} \
__found;})
#define AVL_REMOVE(__TreeP,__Node,__Compare) ({ \
avl_dptr_t __stk[AVL_MAXHEIGHT]; \
int __cnt, __ret; \
\
if (! AVL_FINDWITHSTACK((__TreeP),(__Node) \
,__stk,&__cnt,__Compare)) { \
__ret = 0; \
} else { \
avl_remove(__stk, __cnt); \
__ret = 1; \
} \
__ret;})
#define AVL_INSERT(__TreeP,__Node,__Compare) ({ \
avl_dptr_t __stk[AVL_MAXHEIGHT]; \
int __cnt, __ret; \
\
if (AVL_FINDWITHSTACK((__TreeP),(__Node) \
,__stk,&__cnt,__Compare)) { \
__ret = 0; \
} else { \
avl_insert((__Node), __stk, __cnt); \
__ret = 1; \
} \
__ret;})
--
------------------------------------------------------------------------
| Kevin O'Connor "BTW, IMHO we need a FAQ for |
| koconnor@cse.buffalo.edu 'IMHO', 'FAQ', 'BTW', etc. !" |
------------------------------------------------------------------------
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://humbolt.geo.uu.nl/Linux-MM/
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [patch] rbtrees [was Re: AVL trees vs. Red-Black trees]
1999-11-30 5:27 ` Kevin O'Connor
@ 1999-11-30 14:14 ` Andrea Arcangeli
0 siblings, 0 replies; 8+ messages in thread
From: Andrea Arcangeli @ 1999-11-30 14:14 UTC (permalink / raw)
To: Kevin O'Connor
Cc: Manfred Spraul, Oliver Xymoron, linux-mm, linux-kernel,
Marc Lehmann, Linus Torvalds
On Tue, 30 Nov 1999, Kevin O'Connor wrote:
>[..] I've got inserts working, but
>removes are becoming a myriad of special cases..
removes are trivial with rbtrees as you never need to compare nodes. All
the rebalancing is done in function of the node color (that is a private
information of each node). The same is true also for the
insert-rebalancing, but to do an insert you must first browse the tree to
do a normal ordered O(log(n)) insert before calling the rebalance (thus a
compare semantic on elements is necessary for the insert operation to
work).
Andrea
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://humbolt.geo.uu.nl/Linux-MM/
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~1999-11-30 14:14 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-11-27 12:59 AVL trees vs. Red-Black trees Kevin O'Connor
1999-11-28 2:57 ` Andrea Arcangeli
1999-11-28 5:29 ` Oliver Xymoron
1999-11-29 15:54 ` [patch] rbtrees [was Re: AVL trees vs. Red-Black trees] Andrea Arcangeli
1999-11-29 19:18 ` Manfred Spraul
1999-11-29 19:17 ` Andrea Arcangeli
1999-11-30 5:27 ` Kevin O'Connor
1999-11-30 14:14 ` Andrea Arcangeli
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox