updated tree code

svn:r67
This commit is contained in:
Niels Provos 2003-04-29 18:29:16 +00:00
parent 670b94e479
commit bdf5a68b95

View File

@ -1,4 +1,4 @@
/* $OpenBSD: tree.h,v 1.4 2002/03/26 02:47:28 hugh Exp $ */ /* $OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $ */
/* /*
* Copyright 2002 Niels Provos <provos@citi.umich.edu> * Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved. * All rights reserved.
@ -114,48 +114,8 @@ struct { \
#define SPLAY_PROTOTYPE(name, type, field, cmp) \ #define SPLAY_PROTOTYPE(name, type, field, cmp) \
void name##_SPLAY(struct name *, struct type *); \ void name##_SPLAY(struct name *, struct type *); \
void name##_SPLAY_MINMAX(struct name *, int); \ void name##_SPLAY_MINMAX(struct name *, int); \
\ struct type *name##_SPLAY_INSERT(struct name *, struct type *); \
static __inline void \ struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \
name##_SPLAY_INSERT(struct name *head, struct type *elm) \
{ \
if (SPLAY_EMPTY(head)) { \
SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \
} else { \
int __comp; \
name##_SPLAY(head, elm); \
__comp = (cmp)(elm, (head)->sph_root); \
if(__comp < 0) { \
SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\
SPLAY_RIGHT(elm, field) = (head)->sph_root; \
SPLAY_LEFT((head)->sph_root, field) = NULL; \
} else if (__comp > 0) { \
SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\
SPLAY_LEFT(elm, field) = (head)->sph_root; \
SPLAY_RIGHT((head)->sph_root, field) = NULL; \
} else \
return; \
} \
(head)->sph_root = (elm); \
} \
\
static __inline void \
name##_SPLAY_REMOVE(struct name *head, struct type *elm) \
{ \
struct type *__tmp; \
if (SPLAY_EMPTY(head)) \
return; \
name##_SPLAY(head, elm); \
if ((cmp)(elm, (head)->sph_root) == 0) { \
if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\
} else { \
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\
name##_SPLAY(head, elm); \
SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
} \
} \
} \
\ \
/* Finds the node with the same key as elm */ \ /* Finds the node with the same key as elm */ \
static __inline struct type * \ static __inline struct type * \
@ -194,7 +154,53 @@ name##_SPLAY_MIN_MAX(struct name *head, int val) \
* Moves node close to the key of elm to top * Moves node close to the key of elm to top
*/ */
#define SPLAY_GENERATE(name, type, field, cmp) \ #define SPLAY_GENERATE(name, type, field, cmp) \
void name##_SPLAY(struct name *head, struct type *elm) \ struct type * \
name##_SPLAY_INSERT(struct name *head, struct type *elm) \
{ \
if (SPLAY_EMPTY(head)) { \
SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \
} else { \
int __comp; \
name##_SPLAY(head, elm); \
__comp = (cmp)(elm, (head)->sph_root); \
if(__comp < 0) { \
SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\
SPLAY_RIGHT(elm, field) = (head)->sph_root; \
SPLAY_LEFT((head)->sph_root, field) = NULL; \
} else if (__comp > 0) { \
SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\
SPLAY_LEFT(elm, field) = (head)->sph_root; \
SPLAY_RIGHT((head)->sph_root, field) = NULL; \
} else \
return ((head)->sph_root); \
} \
(head)->sph_root = (elm); \
return (NULL); \
} \
\
struct type * \
name##_SPLAY_REMOVE(struct name *head, struct type *elm) \
{ \
struct type *__tmp; \
if (SPLAY_EMPTY(head)) \
return (NULL); \
name##_SPLAY(head, elm); \
if ((cmp)(elm, (head)->sph_root) == 0) { \
if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\
} else { \
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\
name##_SPLAY(head, elm); \
SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
} \
return (elm); \
} \
return (NULL); \
} \
\
void \
name##_SPLAY(struct name *head, struct type *elm) \
{ \ { \
struct type __node, *__left, *__right, *__tmp; \ struct type __node, *__left, *__right, *__tmp; \
int __comp; \ int __comp; \
@ -337,12 +343,13 @@ struct { \
RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
else \ else \
RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
RB_AUGMENT(RB_PARENT(elm, field)); \
} else \ } else \
(head)->rbh_root = (tmp); \ (head)->rbh_root = (tmp); \
RB_LEFT(tmp, field) = (elm); \ RB_LEFT(tmp, field) = (elm); \
RB_PARENT(elm, field) = (tmp); \ RB_PARENT(elm, field) = (tmp); \
RB_AUGMENT(tmp); \ RB_AUGMENT(tmp); \
if ((RB_PARENT(tmp, field))) \
RB_AUGMENT(RB_PARENT(tmp, field)); \
} while (0) } while (0)
#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \ #define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \
@ -356,19 +363,20 @@ struct { \
RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
else \ else \
RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
RB_AUGMENT(RB_PARENT(elm, field)); \
} else \ } else \
(head)->rbh_root = (tmp); \ (head)->rbh_root = (tmp); \
RB_RIGHT(tmp, field) = (elm); \ RB_RIGHT(tmp, field) = (elm); \
RB_PARENT(elm, field) = (tmp); \ RB_PARENT(elm, field) = (tmp); \
RB_AUGMENT(tmp); \ RB_AUGMENT(tmp); \
if ((RB_PARENT(tmp, field))) \
RB_AUGMENT(RB_PARENT(tmp, field)); \
} while (0) } while (0)
/* Generates prototypes and inline functions */ /* Generates prototypes and inline functions */
#define RB_PROTOTYPE(name, type, field, cmp) \ #define RB_PROTOTYPE(name, type, field, cmp) \
void name##_RB_INSERT_COLOR(struct name *, struct type *); \ void name##_RB_INSERT_COLOR(struct name *, struct type *); \
void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\ void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
void name##_RB_REMOVE(struct name *, struct type *); \ struct type *name##_RB_REMOVE(struct name *, struct type *); \
struct type *name##_RB_INSERT(struct name *, struct type *); \ struct type *name##_RB_INSERT(struct name *, struct type *); \
struct type *name##_RB_FIND(struct name *, struct type *); \ struct type *name##_RB_FIND(struct name *, struct type *); \
struct type *name##_RB_NEXT(struct name *, struct type *); \ struct type *name##_RB_NEXT(struct name *, struct type *); \
@ -499,17 +507,17 @@ name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm)
RB_COLOR(elm, field) = RB_BLACK; \ RB_COLOR(elm, field) = RB_BLACK; \
} \ } \
\ \
void \ struct type * \
name##_RB_REMOVE(struct name *head, struct type *elm) \ name##_RB_REMOVE(struct name *head, struct type *elm) \
{ \ { \
struct type *child, *parent; \ struct type *child, *parent, *old = elm; \
int color; \ int color; \
if (RB_LEFT(elm, field) == NULL) \ if (RB_LEFT(elm, field) == NULL) \
child = RB_RIGHT(elm, field); \ child = RB_RIGHT(elm, field); \
else if (RB_RIGHT(elm, field) == NULL) \ else if (RB_RIGHT(elm, field) == NULL) \
child = RB_LEFT(elm, field); \ child = RB_LEFT(elm, field); \
else { \ else { \
struct type *old = elm, *left; \ struct type *left; \
elm = RB_RIGHT(elm, field); \ elm = RB_RIGHT(elm, field); \
while ((left = RB_LEFT(elm, field))) \ while ((left = RB_LEFT(elm, field))) \
elm = left; \ elm = left; \
@ -563,6 +571,7 @@ name##_RB_REMOVE(struct name *head, struct type *elm) \
color: \ color: \
if (color == RB_BLACK) \ if (color == RB_BLACK) \
name##_RB_REMOVE_COLOR(head, parent, child); \ name##_RB_REMOVE_COLOR(head, parent, child); \
return (old); \
} \ } \
\ \
/* Inserts a node into the RB tree */ \ /* Inserts a node into the RB tree */ \