Add the RB_PROTOTYPE_STATIC and RB_GENERATE_STATIC macros.
Approved by: markm (mentor)
This commit is contained in:
parent
2addd81287
commit
d72cd77975
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=154548
@ -110,6 +110,7 @@ MLINKS+= tree.3 RB_EMPTY.3 \
|
||||
tree.3 RB_FIND.3 \
|
||||
tree.3 RB_FOREACH.3 \
|
||||
tree.3 RB_GENERATE.3 \
|
||||
tree.3 RB_GENERATE_STATIC.3 \
|
||||
tree.3 RB_HEAD.3 \
|
||||
tree.3 RB_INIT.3 \
|
||||
tree.3 RB_INITIALIZER.3 \
|
||||
@ -121,6 +122,7 @@ MLINKS+= tree.3 RB_EMPTY.3 \
|
||||
tree.3 RB_NFIND.3 \
|
||||
tree.3 RB_PARENT.3 \
|
||||
tree.3 RB_PROTOTYPE.3 \
|
||||
tree.3 RB_PROTOTYPE_STATIC.3 \
|
||||
tree.3 RB_REMOVE.3 \
|
||||
tree.3 RB_RIGHT.3 \
|
||||
tree.3 RB_ROOT.3 \
|
||||
|
@ -30,7 +30,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 24, 2002
|
||||
.Dd January 17, 2006
|
||||
.Dt TREE 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -52,7 +52,9 @@
|
||||
.Nm SPLAY_INSERT ,
|
||||
.Nm SPLAY_REMOVE ,
|
||||
.Nm RB_PROTOTYPE ,
|
||||
.Nm RB_PROTOTYPE_STATIC ,
|
||||
.Nm RB_GENERATE ,
|
||||
.Nm RB_GENERATE_STATIC ,
|
||||
.Nm RB_ENTRY ,
|
||||
.Nm RB_HEAD ,
|
||||
.Nm RB_INITIALIZER ,
|
||||
@ -102,7 +104,9 @@
|
||||
.Ft "struct TYPE *"
|
||||
.Fn SPLAY_REMOVE NAME "SPLAY_HEAD *head" "struct TYPE *elm"
|
||||
.Fn RB_PROTOTYPE NAME TYPE FIELD CMP
|
||||
.Fn RB_PROTOTYPE_STATIC NAME TYPE FIELD CMP
|
||||
.Fn RB_GENERATE NAME TYPE FIELD CMP
|
||||
.Fn RB_GENERATE_STATIC NAME TYPE FIELD CMP
|
||||
.Fn RB_ENTRY TYPE
|
||||
.Fn RB_HEAD HEADNAME TYPE
|
||||
.Fn RB_INITIALIZER "RB_HEAD *head"
|
||||
@ -156,14 +160,16 @@ The argument
|
||||
.Fa NAME
|
||||
has to be a unique name prefix for every tree that is defined.
|
||||
.Pp
|
||||
The function prototypes are declared with either
|
||||
The function prototypes are declared with
|
||||
.Fn SPLAY_PROTOTYPE ,
|
||||
.Fn RB_PROTOTYPE ,
|
||||
or
|
||||
.Fn RB_PROTOTYPE .
|
||||
The function bodies are generated with either
|
||||
.Fn RB_PROTOTYPE_STATIC .
|
||||
The function bodies are generated with
|
||||
.Fn SPLAY_GENERATE ,
|
||||
.Fn RB_GENERATE ,
|
||||
or
|
||||
.Fn RB_GENERATE .
|
||||
.Fn RB_GENERATE_STATIC .
|
||||
See the examples below for further explanation of how these macros are used.
|
||||
.Sh SPLAY TREES
|
||||
A splay tree is a self-organizing data structure.
|
||||
@ -344,6 +350,8 @@ macro declares a structure that allows elements to be connected in the tree.
|
||||
In order to use the functions that manipulate the tree structure,
|
||||
their prototypes need to be declared with the
|
||||
.Fn RB_PROTOTYPE
|
||||
or
|
||||
.Fn RB_PROTOTYPE_STATIC
|
||||
macro,
|
||||
where
|
||||
.Fa NAME
|
||||
@ -359,10 +367,14 @@ argument is the name of the element defined by
|
||||
.Pp
|
||||
The function bodies are generated with the
|
||||
.Fn RB_GENERATE
|
||||
or
|
||||
.Fn RB_GENERATE_STATIC
|
||||
macro.
|
||||
It takes the same arguments as the
|
||||
These macros take the same arguments as the
|
||||
.Fn RB_PROTOTYPE
|
||||
macro, but should be used only once.
|
||||
and
|
||||
.Fn RB_PROTOTYPE_STATIC
|
||||
macros, but should be used only once.
|
||||
.Pp
|
||||
Finally,
|
||||
the
|
||||
|
@ -30,6 +30,8 @@
|
||||
#ifndef _SYS_TREE_H_
|
||||
#define _SYS_TREE_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
/*
|
||||
* This file defines data structures for different types of trees:
|
||||
* splay trees and red-black trees.
|
||||
@ -376,22 +378,30 @@ struct { \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
/* Generates prototypes and inline functions */
|
||||
#define RB_PROTOTYPE(name, type, field, cmp) \
|
||||
void name##_RB_INSERT_COLOR(struct name *, struct type *); \
|
||||
void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
|
||||
struct type *name##_RB_REMOVE(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_NFIND(struct name *, struct type *); \
|
||||
struct type *name##_RB_NEXT(struct type *); \
|
||||
struct type *name##_RB_MINMAX(struct name *, int); \
|
||||
#define RB_PROTOTYPE(name, type, field, cmp) \
|
||||
RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
|
||||
#define RB_PROTOTYPE_STATIC(name, type, field, cmp) \
|
||||
RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __unused static)
|
||||
#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \
|
||||
attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \
|
||||
attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
|
||||
attr struct type *name##_RB_REMOVE(struct name *, struct type *); \
|
||||
attr struct type *name##_RB_INSERT(struct name *, struct type *); \
|
||||
attr struct type *name##_RB_FIND(struct name *, struct type *); \
|
||||
attr struct type *name##_RB_NFIND(struct name *, struct type *); \
|
||||
attr struct type *name##_RB_NEXT(struct type *); \
|
||||
attr struct type *name##_RB_MINMAX(struct name *, int); \
|
||||
\
|
||||
|
||||
/* Main rb operation.
|
||||
* Moves node close to the key of elm to top
|
||||
*/
|
||||
#define RB_GENERATE(name, type, field, cmp) \
|
||||
void \
|
||||
#define RB_GENERATE(name, type, field, cmp) \
|
||||
RB_GENERATE_INTERNAL(name, type, field, cmp,)
|
||||
#define RB_GENERATE_STATIC(name, type, field, cmp) \
|
||||
RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static)
|
||||
#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \
|
||||
attr void \
|
||||
name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *parent, *gparent, *tmp; \
|
||||
@ -435,7 +445,7 @@ name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \
|
||||
RB_COLOR(head->rbh_root, field) = RB_BLACK; \
|
||||
} \
|
||||
\
|
||||
void \
|
||||
attr void \
|
||||
name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
|
||||
{ \
|
||||
struct type *tmp; \
|
||||
@ -513,7 +523,7 @@ name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm)
|
||||
RB_COLOR(elm, field) = RB_BLACK; \
|
||||
} \
|
||||
\
|
||||
struct type * \
|
||||
attr struct type * \
|
||||
name##_RB_REMOVE(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *child, *parent, *old = elm; \
|
||||
@ -581,7 +591,7 @@ color: \
|
||||
} \
|
||||
\
|
||||
/* Inserts a node into the RB tree */ \
|
||||
struct type * \
|
||||
attr struct type * \
|
||||
name##_RB_INSERT(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *tmp; \
|
||||
@ -612,7 +622,7 @@ name##_RB_INSERT(struct name *head, struct type *elm) \
|
||||
} \
|
||||
\
|
||||
/* Finds the node with the same key as elm */ \
|
||||
struct type * \
|
||||
attr struct type * \
|
||||
name##_RB_FIND(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *tmp = RB_ROOT(head); \
|
||||
@ -630,7 +640,7 @@ name##_RB_FIND(struct name *head, struct type *elm) \
|
||||
} \
|
||||
\
|
||||
/* Finds the first node greater than or equal to the search key */ \
|
||||
struct type * \
|
||||
attr struct type * \
|
||||
name##_RB_NFIND(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *ret = RB_ROOT(head); \
|
||||
@ -659,7 +669,7 @@ name##_RB_NFIND(struct name *head, struct type *elm) \
|
||||
} \
|
||||
\
|
||||
/* ARGSUSED */ \
|
||||
struct type * \
|
||||
attr struct type * \
|
||||
name##_RB_NEXT(struct type *elm) \
|
||||
{ \
|
||||
if (RB_RIGHT(elm, field)) { \
|
||||
@ -680,7 +690,7 @@ name##_RB_NEXT(struct type *elm) \
|
||||
return (elm); \
|
||||
} \
|
||||
\
|
||||
struct type * \
|
||||
attr struct type * \
|
||||
name##_RB_MINMAX(struct name *head, int val) \
|
||||
{ \
|
||||
struct type *tmp = RB_ROOT(head); \
|
||||
|
Loading…
Reference in New Issue
Block a user