From: "Kevin O'Connor" <koconnor@cse.Buffalo.EDU>
To: Manfred Spraul <manfreds@colorfullife.com>
Cc: Andrea Arcangeli <andrea@suse.de>,
Oliver Xymoron <oxymoron@waste.org>,
Kevin O'Connor <koconnor@cse.Buffalo.EDU>,
linux-mm@kvack.org, linux-kernel@vger.rutgers.edu,
Marc Lehmann <pcg@opengroup.org>,
Linus Torvalds <torvalds@transmeta.com>
Subject: Re: [patch] rbtrees [was Re: AVL trees vs. Red-Black trees]
Date: Tue, 30 Nov 1999 00:27:55 -0500 [thread overview]
Message-ID: <19991130002755.A22847@armstrong.cse.Buffalo.EDU> (raw)
In-Reply-To: <3842D179.7FBD6A69@colorfullife.com>; from Manfred Spraul on Mon, Nov 29, 1999 at 08:18:17PM +0100
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/
next prev parent reply other threads:[~1999-11-30 5:27 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
1999-11-30 14:14 ` Andrea Arcangeli
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=19991130002755.A22847@armstrong.cse.Buffalo.EDU \
--to=koconnor@cse.buffalo.edu \
--cc=andrea@suse.de \
--cc=linux-kernel@vger.rutgers.edu \
--cc=linux-mm@kvack.org \
--cc=manfreds@colorfullife.com \
--cc=oxymoron@waste.org \
--cc=pcg@opengroup.org \
--cc=torvalds@transmeta.com \
/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