Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
varnish-cache
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
varnishcache
varnish-cache
Commits
e1ac5933
Commit
e1ac5933
authored
Mar 23, 2021
by
Poul-Henning Kamp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update vtree.h from FreeBSD
parent
cd3e4c61
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
376 additions
and
274 deletions
+376
-274
flint.lnt
flint.lnt
+4
-1
vtree.h
include/vtree.h
+338
-273
import_vtree_from_freebsd.sh
tools/import_vtree_from_freebsd.sh
+34
-0
No files found.
flint.lnt
View file @
e1ac5933
...
...
@@ -202,7 +202,10 @@
///////////////////////////////////////////////////////////////////////
// <vtree.h>
-emacro(801, VRBT_*) // goto considered bad
// -emacro(801, VRBT_*) // goto considered bad
-emacro(527, VRBT_*) // unreachable code
-emacro(740, VRBT_*) // unusual pointer cast
-emacro(438, VRBT_*) // last value assigned not used
-esym(534, *_VRBT_REMOVE) // ignore retval
-esym(534, *_VRBT_INSERT) // ignore retval
...
...
include/vtree.h
View file @
e1ac5933
/* $NetBSD: tree.h,v 1.8 2004/03/28 19:38:30 provos Exp $ */
/* $OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $ */
/* $FreeBSD
: release/9.0.0/sys/sys/tree.h 189204 2009-03-01 04:57:23Z bms
$ */
/* $FreeBSD$ */
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
...
...
@@ -32,9 +32,10 @@
#ifndef _VTREE_H_
#define _VTREE_H_
/*
* This file defines data structures for different types of trees:
* splay trees and r
ed-black
trees.
* splay trees and r
ank-balanced
trees.
*
* A splay tree is a self-organizing data structure. Every operation
* on the tree causes a splay to happen. The splay moves the requested
...
...
@@ -48,15 +49,24 @@
* and n inserts on an initially empty tree as O((m + n)lg n). The
* amortized cost for a sequence of m accesses to a splay tree is O(lg n);
*
* A red-black tree is a binary search tree with the node color as an
* extra attribute. It fulfills a set of conditions:
* - every search path from the root to a leaf consists of the
* same number of black nodes,
* - each red node (except for the root) has a black parent,
* - each leaf node is black.
* A rank-balanced tree is a binary search tree with an integer
* rank-difference as an attribute of each pointer from parent to child.
* The sum of the rank-differences on any path from a node down to null is
* the same, and defines the rank of that node. The rank of the null node
* is -1.
*
* Different additional conditions define different sorts of balanced
* trees, including "red-black" and "AVL" trees. The set of conditions
* applied here are the "weak-AVL" conditions of Haeupler, Sen and Tarjan:
* - every rank-difference is 1 or 2.
* - the rank of any leaf is 1.
*
* Every operation on a red-black tree is bounded as O(lg n).
* The maximum height of a red-black tree is 2lg (n+1).
* For historical reasons, rank differences that are even are associated
* with the color red (Rank-Even-Difference), and the child that a red edge
* points to is called a red child.
*
* Every operation on a rank-balanced tree is bounded as O(lg n).
* The maximum height of a rank-balanced tree is 2lg (n+1).
*/
#define VSPLAY_HEAD(name, type) \
...
...
@@ -84,13 +94,13 @@ struct { \
/* VSPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold VSPLAY_{RIGHT,LEFT} */
#define VSPLAY_ROTATE_RIGHT(head, tmp, field) do { \
VSPLAY_LEFT((head)->sph_root, field) = VSPLAY_RIGHT(tmp, field);\
VSPLAY_LEFT((head)->sph_root, field) = VSPLAY_RIGHT(tmp, field);
\
VSPLAY_RIGHT(tmp, field) = (head)->sph_root; \
(head)->sph_root = tmp; \
} while (
/*CONSTCOND*/
0)
#define VSPLAY_ROTATE_LEFT(head, tmp, field) do { \
VSPLAY_RIGHT((head)->sph_root, field) = VSPLAY_LEFT(tmp, field);\
VSPLAY_RIGHT((head)->sph_root, field) = VSPLAY_LEFT(tmp, field);
\
VSPLAY_LEFT(tmp, field) = (head)->sph_root; \
(head)->sph_root = tmp; \
} while (
/*CONSTCOND*/
0)
...
...
@@ -108,10 +118,10 @@ struct { \
} while (
/*CONSTCOND*/
0)
#define VSPLAY_ASSEMBLE(head, node, left, right, field) do { \
VSPLAY_RIGHT(left, field) = VSPLAY_LEFT((head)->sph_root, field);\
VSPLAY_RIGHT(left, field) = VSPLAY_LEFT((head)->sph_root, field);
\
VSPLAY_LEFT(right, field) = VSPLAY_RIGHT((head)->sph_root, field);\
VSPLAY_LEFT((head)->sph_root, field) = VSPLAY_RIGHT(node, field);\
VSPLAY_RIGHT((head)->sph_root, field) = VSPLAY_LEFT(node, field);\
VSPLAY_LEFT((head)->sph_root, field) = VSPLAY_RIGHT(node, field);
\
VSPLAY_RIGHT((head)->sph_root, field) = VSPLAY_LEFT(node, field);
\
} while (
/*CONSTCOND*/
0)
/* Generates prototypes and inline functions */
...
...
@@ -123,7 +133,7 @@ struct type *name##_VSPLAY_INSERT(struct name *, struct type *); \
struct type *name##_VSPLAY_REMOVE(struct name *, struct type *); \
\
/* Finds the node with the same key as elm */
\
static
__inline struct type *
\
static
v_unused_ __inline struct type *
\
name##_VSPLAY_FIND(struct name *head, struct type *elm) \
{ \
if (VSPLAY_EMPTY(head)) \
...
...
@@ -134,7 +144,7 @@ name##_VSPLAY_FIND(struct name *head, struct type *elm) \
return (NULL); \
} \
\
static
__inline struct type *
\
static
v_unused_ __inline struct type *
\
name##_VSPLAY_NEXT(struct name *head, struct type *elm) \
{ \
name##_VSPLAY(head, elm); \
...
...
@@ -148,7 +158,7 @@ name##_VSPLAY_NEXT(struct name *head, struct type *elm) \
return (elm); \
} \
\
static
__inline struct type *
\
static
v_unused_ __inline struct type *
\
name##_VSPLAY_MIN_MAX(struct name *head, int val) \
{ \
name##_VSPLAY_MINMAX(head, val); \
...
...
@@ -168,7 +178,7 @@ name##_VSPLAY_INSERT(struct name *head, struct type *elm) \
int __comp; \
name##_VSPLAY(head, elm); \
__comp = (cmp)(elm, (head)->sph_root); \
if
(__comp < 0) { \
if(__comp < 0) { \
VSPLAY_LEFT(elm, field) = VSPLAY_LEFT((head)->sph_root, field);\
VSPLAY_RIGHT(elm, field) = (head)->sph_root; \
VSPLAY_LEFT((head)->sph_root, field) = NULL; \
...
...
@@ -219,7 +229,7 @@ name##_VSPLAY(struct name *head, struct type *elm) \
if (__tmp == NULL) \
break; \
if ((cmp)(elm, __tmp) < 0){ \
VSPLAY_ROTATE_RIGHT(head, __tmp, field);\
VSPLAY_ROTATE_RIGHT(head, __tmp, field);
\
if (VSPLAY_LEFT((head)->sph_root, field) == NULL)\
break; \
} \
...
...
@@ -255,7 +265,7 @@ void name##_VSPLAY_MINMAX(struct name *head, int __comp) \
if (__tmp == NULL) \
break; \
if (__comp < 0){ \
VSPLAY_ROTATE_RIGHT(head, __tmp, field);\
VSPLAY_ROTATE_RIGHT(head, __tmp, field);
\
if (VSPLAY_LEFT((head)->sph_root, field) == NULL)\
break; \
} \
...
...
@@ -292,7 +302,7 @@ void name##_VSPLAY_MINMAX(struct name *head, int __comp) \
(x) != NULL; \
(x) = VSPLAY_NEXT(name, head, x))
/* Macros that define a r
ed-black
tree */
/* Macros that define a r
ank-balanced
tree */
#define VRBT_HEAD(name, type) \
struct name { \
struct type *rbh_root;
/* root of the tree */
\
...
...
@@ -305,76 +315,91 @@ struct name { \
(root)->rbh_root = NULL; \
} while (
/*CONSTCOND*/
0)
#define VRBT_BLACK 0
#define VRBT_RED 1
#define VRBT_ENTRY(type) \
struct { \
struct type *rbe_left;
/* left element */
\
struct type *rbe_right;
/* right element */
\
struct type *rbe_parent;
/* parent element */
\
int rbe_color;
/* node color */
\
}
#define VRBT_LEFT(elm, field) (elm)->field.rbe_left
#define VRBT_RIGHT(elm, field) (elm)->field.rbe_right
#define VRBT_PARENT(elm, field) (elm)->field.rbe_parent
#define VRBT_COLOR(elm, field) (elm)->field.rbe_color
/*
* With the expectation that any object of struct type has an
* address that is a multiple of 4, and that therefore the
* 2 least significant bits of a pointer to struct type are
* always zero, this implementation sets those bits to indicate
* that the left or right child of the tree node is "red".
*/
#define VRBT_UP(elm, field) (elm)->field.rbe_parent
#define VRBT_BITS(elm, field) (*(__uintptr_t *)&VRBT_UP(elm, field))
#define VRBT_RED_L ((__uintptr_t)1)
#define VRBT_RED_R ((__uintptr_t)2)
#define VRBT_RED_MASK ((__uintptr_t)3)
#define VRBT_FLIP_LEFT(elm, field) (VRBT_BITS(elm, field) ^= VRBT_RED_L)
#define VRBT_FLIP_RIGHT(elm, field) (VRBT_BITS(elm, field) ^= VRBT_RED_R)
#define VRBT_RED_LEFT(elm, field) ((VRBT_BITS(elm, field) & VRBT_RED_L) != 0)
#define VRBT_RED_RIGHT(elm, field) ((VRBT_BITS(elm, field) & VRBT_RED_R) != 0)
#define VRBT_PARENT(elm, field) ((__typeof(VRBT_UP(elm, field))) \
(VRBT_BITS(elm, field) & ~VRBT_RED_MASK))
#define VRBT_ROOT(head) (head)->rbh_root
#define VRBT_EMPTY(head) (VRBT_ROOT(head) == NULL)
#define VRBT_SET_PARENT(dst, src, field) do { \
VRBT_BITS(dst, field) &= VRBT_RED_MASK; \
VRBT_BITS(dst, field) |= (__uintptr_t)src; \
} while (
/*CONSTCOND*/
0)
#define VRBT_SET(elm, parent, field) do { \
VRBT_
PARENT(elm, field) = parent;
\
VRBT_
UP(elm, field) = parent;
\
VRBT_LEFT(elm, field) = VRBT_RIGHT(elm, field) = NULL; \
VRBT_COLOR(elm, field) = VRBT_RED; \
} while (
/*CONSTCOND*/
0)
#define VRBT_
SET_BLACKRED(black, red, field) do {
\
VRBT_COLOR(black, field) = VRBT_BLACK;
\
VRBT_COLOR(red, field) = VRBT_RED;
\
} while (
/*CONSTCOND*/
0
)
#define VRBT_
COLOR(elm, field) (VRBT_PARENT(elm, field) == NULL ? 0 :
\
VRBT_LEFT(VRBT_PARENT(elm, field), field) == elm ?
\
VRBT_RED_LEFT(VRBT_PARENT(elm, field), field) :
\
VRBT_RED_RIGHT(VRBT_PARENT(elm, field), field)
)
/*
* Something to be invoked in a loop at the root of every modified subtree,
* from the bottom up to the root, to update augmented node data.
*/
#ifndef VRBT_AUGMENT
#define VRBT_AUGMENT(x)
do {} while (0)
#define VRBT_AUGMENT(x)
break
#endif
#define VRBT_SWAP_CHILD(head, out, in, field) do { \
if (VRBT_PARENT(out, field) == NULL) \
VRBT_ROOT(head) = (in); \
else if ((out) == VRBT_LEFT(VRBT_PARENT(out, field), field)) \
VRBT_LEFT(VRBT_PARENT(out, field), field) = (in); \
else \
VRBT_RIGHT(VRBT_PARENT(out, field), field) = (in); \
} while (
/*CONSTCOND*/
0)
#define VRBT_ROTATE_LEFT(head, elm, tmp, field) do { \
(tmp) = VRBT_RIGHT(elm, field); \
if ((VRBT_RIGHT(elm, field) = VRBT_LEFT(tmp, field)) != NULL) { \
VRBT_
PARENT(VRBT_LEFT(tmp, field), field) = (elm
); \
VRBT_
SET_PARENT(VRBT_RIGHT(elm, field), elm, field
); \
} \
VRBT_AUGMENT(elm); \
if ((VRBT_PARENT(tmp, field) = VRBT_PARENT(elm, field)) != NULL) {\
if ((elm) == VRBT_LEFT(VRBT_PARENT(elm, field), field)) \
VRBT_LEFT(VRBT_PARENT(elm, field), field) = (tmp);\
else \
VRBT_RIGHT(VRBT_PARENT(elm, field), field) = (tmp);\
} else \
(head)->rbh_root = (tmp); \
VRBT_SET_PARENT(tmp, VRBT_PARENT(elm, field), field); \
VRBT_SWAP_CHILD(head, elm, tmp, field); \
VRBT_LEFT(tmp, field) = (elm); \
VRBT_PARENT(elm, field) = (tmp); \
VRBT_AUGMENT(tmp); \
if ((VRBT_PARENT(tmp, field))) \
VRBT_AUGMENT(VRBT_PARENT(tmp, field)); \
VRBT_SET_PARENT(elm, tmp, field); \
VRBT_AUGMENT(elm); \
} while (
/*CONSTCOND*/
0)
#define VRBT_ROTATE_RIGHT(head, elm, tmp, field) do { \
(tmp) = VRBT_LEFT(elm, field); \
if ((VRBT_LEFT(elm, field) = VRBT_RIGHT(tmp, field)) != NULL) { \
VRBT_
PARENT(VRBT_RIGHT(tmp, field), field) = (elm);
\
VRBT_
SET_PARENT(VRBT_LEFT(elm, field), elm, field);
\
} \
VRBT_AUGMENT(elm); \
if ((VRBT_PARENT(tmp, field) = VRBT_PARENT(elm, field)) != NULL) {\
if ((elm) == VRBT_LEFT(VRBT_PARENT(elm, field), field)) \
VRBT_LEFT(VRBT_PARENT(elm, field), field) = (tmp);\
else \
VRBT_RIGHT(VRBT_PARENT(elm, field), field) = (tmp);\
} else \
(head)->rbh_root = (tmp); \
VRBT_SET_PARENT(tmp, VRBT_PARENT(elm, field), field); \
VRBT_SWAP_CHILD(head, elm, tmp, field); \
VRBT_RIGHT(tmp, field) = (elm); \
VRBT_PARENT(elm, field) = (tmp); \
VRBT_AUGMENT(tmp); \
if ((VRBT_PARENT(tmp, field))) \
VRBT_AUGMENT(VRBT_PARENT(tmp, field)); \
VRBT_SET_PARENT(elm, tmp, field); \
VRBT_AUGMENT(elm); \
} while (
/*CONSTCOND*/
0)
/* Generates prototypes and inline functions */
...
...
@@ -383,17 +408,37 @@ struct { \
#define VRBT_PROTOTYPE_STATIC(name, type, field, cmp) \
VRBT_PROTOTYPE_INTERNAL(name, type, field, cmp, v_unused_ static)
#define VRBT_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \
/*lint -esym(528, name##_VRBT_*) */
\
attr void name##_VRBT_INSERT_COLOR(struct name *, struct type *); \
attr void name##_VRBT_REMOVE_COLOR(struct name *, struct type *, struct type *);\
attr struct type *name##_VRBT_REMOVE(struct name *, struct type *); \
attr struct type *name##_VRBT_INSERT(struct name *, struct type *); \
attr struct type *name##_VRBT_FIND(const struct name *, const struct type *); \
attr struct type *name##_VRBT_NFIND(const struct name *, const struct type *); \
attr struct type *name##_VRBT_NEXT(struct type *); \
attr struct type *name##_VRBT_PREV(struct type *); \
attr struct type *name##_VRBT_MINMAX(const struct name *, int); \
\
VRBT_PROTOTYPE_INSERT_COLOR(name, type, attr); \
VRBT_PROTOTYPE_REMOVE_COLOR(name, type, attr); \
VRBT_PROTOTYPE_INSERT(name, type, attr); \
VRBT_PROTOTYPE_REMOVE(name, type, attr); \
VRBT_PROTOTYPE_FIND(name, type, attr); \
VRBT_PROTOTYPE_NFIND(name, type, attr); \
VRBT_PROTOTYPE_NEXT(name, type, attr); \
VRBT_PROTOTYPE_PREV(name, type, attr); \
VRBT_PROTOTYPE_MINMAX(name, type, attr); \
VRBT_PROTOTYPE_REINSERT(name, type, attr);
#define VRBT_PROTOTYPE_INSERT_COLOR(name, type, attr) \
attr void name##_VRBT_INSERT_COLOR(struct name *, struct type *)
#define VRBT_PROTOTYPE_REMOVE_COLOR(name, type, attr) \
attr void name##_VRBT_REMOVE_COLOR(struct name *, \
struct type *, struct type *)
#define VRBT_PROTOTYPE_REMOVE(name, type, attr) \
attr struct type *name##_VRBT_REMOVE(struct name *, struct type *)
#define VRBT_PROTOTYPE_INSERT(name, type, attr) \
attr struct type *name##_VRBT_INSERT(struct name *, struct type *)
#define VRBT_PROTOTYPE_FIND(name, type, attr) \
attr struct type *name##_VRBT_FIND(const struct name *, const struct type *)
#define VRBT_PROTOTYPE_NFIND(name, type, attr) \
attr struct type *name##_VRBT_NFIND(const struct name *, const struct type *)
#define VRBT_PROTOTYPE_NEXT(name, type, attr) \
attr struct type *name##_VRBT_NEXT(struct type *)
#define VRBT_PROTOTYPE_PREV(name, type, attr) \
attr struct type *name##_VRBT_PREV(struct type *)
#define VRBT_PROTOTYPE_MINMAX(name, type, attr) \
attr struct type *name##_VRBT_MINMAX(const struct name *, int)
#define VRBT_PROTOTYPE_REINSERT(name, type, attr) \
attr struct type *name##_VRBT_REINSERT(struct name *, struct type *)
/* Main rb operation.
* Moves node close to the key of elm to top
...
...
@@ -403,197 +448,193 @@ attr struct type *name##_VRBT_MINMAX(const struct name *, int); \
#define VRBT_GENERATE_STATIC(name, type, field, cmp) \
VRBT_GENERATE_INTERNAL(name, type, field, cmp, v_unused_ static)
#define VRBT_GENERATE_INTERNAL(name, type, field, cmp, attr) \
VRBT_GENERATE_INSERT_COLOR(name, type, field, attr) \
VRBT_GENERATE_REMOVE_COLOR(name, type, field, attr) \
VRBT_GENERATE_INSERT(name, type, field, cmp, attr) \
VRBT_GENERATE_REMOVE(name, type, field, attr) \
VRBT_GENERATE_FIND(name, type, field, cmp, attr) \
VRBT_GENERATE_NFIND(name, type, field, cmp, attr) \
VRBT_GENERATE_NEXT(name, type, field, attr) \
VRBT_GENERATE_PREV(name, type, field, attr) \
VRBT_GENERATE_MINMAX(name, type, field, attr) \
VRBT_GENERATE_REINSERT(name, type, field, cmp, attr)
#define VRBT_GENERATE_INSERT_COLOR(name, type, field, attr) \
attr void \
name##_VRBT_INSERT_COLOR(struct name *head, struct type *elm) \
{ \
struct type *
parent, *gparent, *tmp;
\
while ((parent = VRBT_PARENT(elm, field)) != NULL
&&
\
VRBT_COLOR(parent, field) == VRBT_RED
) { \
gparent = VRBT_PARENT(parent, field);
\
if (parent == VRBT_LEFT(gparent, field)) {
\
tmp = VRBT_RIGHT(gparent, field);
\
if (tmp && VRBT_COLOR(tmp, field) == VRBT_RED) {
\
VRBT_COLOR(tmp, field) = VRBT_BLACK;
\
VRBT_SET_BLACKRED(parent, gparent, field);
\
elm =
g
parent; \
struct type *
child, *parent;
\
while ((parent = VRBT_PARENT(elm, field)) != NULL
) {
\
if (VRBT_LEFT(parent, field) == elm
) { \
if (VRBT_RED_LEFT(parent, field)) {
\
VRBT_FLIP_LEFT(parent, field);
\
return;
\
}
\
VRBT_FLIP_RIGHT(parent, field);
\
if (VRBT_RED_RIGHT(parent, field)) {
\
elm = parent; \
continue; \
} \
if (VRBT_RIGHT(parent, field) == elm) { \
VRBT_ROTATE_LEFT(head, parent, tmp, field);\
tmp = parent; \
parent = elm; \
elm = tmp; \
if (!VRBT_RED_RIGHT(elm, field)) { \
VRBT_FLIP_LEFT(elm, field); \
VRBT_ROTATE_LEFT(head, elm, child, field);\
if (VRBT_RED_LEFT(child, field)) \
VRBT_FLIP_RIGHT(elm, field); \
else if (VRBT_RED_RIGHT(child, field)) \
VRBT_FLIP_LEFT(parent, field); \
AN(parent); \
elm = child; \
} \
VRBT_SET_BLACKRED(parent, gparent, field); \
VRBT_ROTATE_RIGHT(head, gparent, tmp, field); \
VRBT_ROTATE_RIGHT(head, parent, elm, field); \
} else { \
tmp = VRBT_LEFT(gparent, field); \
if (tmp && VRBT_COLOR(tmp, field) == VRBT_RED) {\
VRBT_COLOR(tmp, field) = VRBT_BLACK; \
VRBT_SET_BLACKRED(parent, gparent, field);\
elm = gparent; \
if (VRBT_RED_RIGHT(parent, field)) { \
VRBT_FLIP_RIGHT(parent, field); \
return; \
} \
VRBT_FLIP_LEFT(parent, field); \
if (VRBT_RED_LEFT(parent, field)) { \
elm = parent; \
continue; \
} \
if (VRBT_LEFT(parent, field) == elm) { \
VRBT_ROTATE_RIGHT(head, parent, tmp, field);\
tmp = parent; \
parent = elm; \
elm = tmp; \
if (!VRBT_RED_LEFT(elm, field)) { \
VRBT_FLIP_RIGHT(elm, field); \
VRBT_ROTATE_RIGHT(head, elm, child, field);\
if (VRBT_RED_RIGHT(child, field)) \
VRBT_FLIP_LEFT(elm, field); \
else if (VRBT_RED_LEFT(child, field)) \
VRBT_FLIP_RIGHT(parent, field); \
elm = child; \
} \
VRBT_SET_BLACKRED(parent, gparent, field); \
VRBT_ROTATE_LEFT(head, gparent, tmp, field); \
VRBT_ROTATE_LEFT(head, parent, elm, field); \
} \
VRBT_BITS(elm, field) &= ~VRBT_RED_MASK; \
break; \
} \
VRBT_COLOR(head->rbh_root, field) = VRBT_BLACK; \
} \
\
}
#define VRBT_GENERATE_REMOVE_COLOR(name, type, field, attr)
\
attr void \
name##_VRBT_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
name##_VRBT_REMOVE_COLOR(struct name *head, \
struct type *parent, struct type *elm) \
{ \
struct type *tmp; \
while ((elm == NULL || VRBT_COLOR(elm, field) == VRBT_BLACK) && \
elm != VRBT_ROOT(head)) { \
AN(parent); \
if (VRBT_LEFT(parent, field) == elm) { \
tmp = VRBT_RIGHT(parent, field); \
if (VRBT_COLOR(tmp, field) == VRBT_RED) { \
VRBT_SET_BLACKRED(tmp, parent, field); \
VRBT_ROTATE_LEFT(head, parent, tmp, field);\
tmp = VRBT_RIGHT(parent, field); \
} \
if ((VRBT_LEFT(tmp, field) == NULL || \
VRBT_COLOR(VRBT_LEFT(tmp, field), field) == VRBT_BLACK) &&\
(VRBT_RIGHT(tmp, field) == NULL || \
VRBT_COLOR(VRBT_RIGHT(tmp, field), field) == VRBT_BLACK)) {\
VRBT_COLOR(tmp, field) = VRBT_RED; \
struct type *sib; \
if (VRBT_LEFT(parent, field) == elm && \
VRBT_RIGHT(parent, field) == elm) { \
VRBT_BITS(parent, field) &= ~VRBT_RED_MASK; \
elm = parent; \
parent = VRBT_PARENT(elm, field); \
} else { \
if (VRBT_RIGHT(tmp, field) == NULL || \
VRBT_COLOR(VRBT_RIGHT(tmp, field), field) == VRBT_BLACK) {\
struct type *oleft; \
if ((oleft = VRBT_LEFT(tmp, field)) \
!= NULL) \
VRBT_COLOR(oleft, field) = VRBT_BLACK;\
VRBT_COLOR(tmp, field) = VRBT_RED;\
VRBT_ROTATE_RIGHT(head, tmp, oleft, field);\
tmp = VRBT_RIGHT(parent, field);\
} \
VRBT_COLOR(tmp, field) = VRBT_COLOR(parent, field);\
VRBT_COLOR(parent, field) = VRBT_BLACK; \
if (VRBT_RIGHT(tmp, field)) \
VRBT_COLOR(VRBT_RIGHT(tmp, field), field) = VRBT_BLACK;\
VRBT_ROTATE_LEFT(head, parent, tmp, field);\
elm = VRBT_ROOT(head); \
break; \
if (parent == NULL) \
return; \
} \
} else { \
tmp = VRBT_LEFT(parent, field); \
if (VRBT_COLOR(tmp, field) == VRBT_RED) { \
VRBT_SET_BLACKRED(tmp, parent, field); \
VRBT_ROTATE_RIGHT(head, parent, tmp, field);\
tmp = VRBT_LEFT(parent, field); \
} \
if ((VRBT_LEFT(tmp, field) == NULL || \
VRBT_COLOR(VRBT_LEFT(tmp, field), field) == VRBT_BLACK) &&\
(VRBT_RIGHT(tmp, field) == NULL || \
VRBT_COLOR(VRBT_RIGHT(tmp, field), field) == VRBT_BLACK)) {\
VRBT_COLOR(tmp, field) = VRBT_RED; \
do { \
if (VRBT_LEFT(parent, field) == elm) { \
if (!VRBT_RED_LEFT(parent, field)) { \
VRBT_FLIP_LEFT(parent, field); \
return; \
} \
if (VRBT_RED_RIGHT(parent, field)) { \
VRBT_FLIP_RIGHT(parent, field); \
elm = parent; \
parent = VRBT_PARENT(elm, field); \
continue; \
} \
sib = VRBT_RIGHT(parent, field); \
if ((~VRBT_BITS(sib, field) & VRBT_RED_MASK) == 0) {\
VRBT_BITS(sib, field) &= ~VRBT_RED_MASK; \
elm = parent; \
continue; \
} \
VRBT_FLIP_RIGHT(sib, field); \
if (VRBT_RED_LEFT(sib, field)) \
VRBT_FLIP_LEFT(parent, field); \
else if (!VRBT_RED_RIGHT(sib, field)) { \
VRBT_FLIP_LEFT(parent, field); \
VRBT_ROTATE_RIGHT(head, sib, elm, field); \
if (VRBT_RED_RIGHT(elm, field)) \
VRBT_FLIP_LEFT(sib, field); \
if (VRBT_RED_LEFT(elm, field)) \
VRBT_FLIP_RIGHT(parent, field); \
VRBT_BITS(elm, field) |= VRBT_RED_MASK; \
sib = elm; \
} \
VRBT_ROTATE_LEFT(head, parent, sib, field); \
} else { \
if (VRBT_LEFT(tmp, field) == NULL || \
VRBT_COLOR(VRBT_LEFT(tmp, field), field) == VRBT_BLACK) {\
struct type *oright; \
if ((oright = VRBT_RIGHT(tmp, field)) \
!= NULL) \
VRBT_COLOR(oright, field) = VRBT_BLACK;\
VRBT_COLOR(tmp, field) = VRBT_RED;\
VRBT_ROTATE_LEFT(head, tmp, oright, field);\
tmp = VRBT_LEFT(parent, field); \
} \
VRBT_COLOR(tmp, field) = VRBT_COLOR(parent, field);\
VRBT_COLOR(parent, field) = VRBT_BLACK; \
if (VRBT_LEFT(tmp, field)) \
VRBT_COLOR(VRBT_LEFT(tmp, field), field) = VRBT_BLACK;\
VRBT_ROTATE_RIGHT(head, parent, tmp, field);\
elm = VRBT_ROOT(head); \
break; \
if (!VRBT_RED_RIGHT(parent, field)) { \
VRBT_FLIP_RIGHT(parent, field); \
return; \
} \
if (VRBT_RED_LEFT(parent, field)) { \
VRBT_FLIP_LEFT(parent, field); \
elm = parent; \
continue; \
} \
sib = VRBT_LEFT(parent, field); \
if ((~VRBT_BITS(sib, field) & VRBT_RED_MASK) == 0) {\
VRBT_BITS(sib, field) &= ~VRBT_RED_MASK; \
elm = parent; \
continue; \
} \
if (elm) \
VRBT_COLOR(elm, field) = VRBT_BLACK; \
} \
\
VRBT_FLIP_LEFT(sib, field); \
if (VRBT_RED_RIGHT(sib, field)) \
VRBT_FLIP_RIGHT(parent, field); \
else if (!VRBT_RED_LEFT(sib, field)) { \
VRBT_FLIP_RIGHT(parent, field); \
VRBT_ROTATE_LEFT(head, sib, elm, field); \
if (VRBT_RED_LEFT(elm, field)) \
VRBT_FLIP_RIGHT(sib, field); \
if (VRBT_RED_RIGHT(elm, field)) \
VRBT_FLIP_LEFT(parent, field); \
VRBT_BITS(elm, field) |= VRBT_RED_MASK; \
sib = elm; \
} \
VRBT_ROTATE_RIGHT(head, parent, sib, field); \
} \
break; \
} while ((parent = VRBT_PARENT(elm, field)) != NULL); \
}
#define VRBT_GENERATE_REMOVE(name, type, field, attr) \
attr struct type * \
name##_VRBT_REMOVE(struct name *head, struct type *elm) \
{ \
struct type *child, *parent, *old = elm; \
int color; \
struct type *child, *old, *parent, *right; \
\
old = elm; \
parent = VRBT_PARENT(elm, field); \
right = VRBT_RIGHT(elm, field); \
if (VRBT_LEFT(elm, field) == NULL) \
child = VRBT_RIGHT(elm, field);
\
else if (
VRBT_RIGHT(elm, field) == NULL)
\
child = VRBT_LEFT(elm, field);
\
elm = child = right;
\
else if (
right == NULL)
\
elm = child = VRBT_LEFT(elm, field);
\
else { \
struct type *left; \
elm = VRBT_RIGHT(elm, field); \
while ((left = VRBT_LEFT(elm, field)) != NULL) \
elm = left; \
if ((child = VRBT_LEFT(right, field)) == NULL) { \
child = VRBT_RIGHT(right, field); \
VRBT_RIGHT(old, field) = child; \
parent = elm = right; \
} else { \
do \
elm = child; \
while ((child = VRBT_LEFT(elm, field)) != NULL); \
child = VRBT_RIGHT(elm, field); \
parent = VRBT_PARENT(elm, field); \
color = VRBT_COLOR(elm, field); \
if (child) \
VRBT_PARENT(child, field) = parent; \
if (parent) { \
if (VRBT_LEFT(parent, field) == elm) \
VRBT_LEFT(parent, field) = child; \
else \
VRBT_RIGHT(parent, field) = child; \
VRBT_AUGMENT(parent); \
} else \
VRBT_ROOT(head) = child; \
if (VRBT_PARENT(elm, field) == old) \
parent = elm; \
(elm)->field = (old)->field; \
if (VRBT_PARENT(old, field)) { \
if (VRBT_LEFT(VRBT_PARENT(old, field), field) == old)\
VRBT_LEFT(VRBT_PARENT(old, field), field) = elm;\
else \
VRBT_RIGHT(VRBT_PARENT(old, field), field) = elm;\
VRBT_AUGMENT(VRBT_PARENT(old, field)); \
} else \
VRBT_ROOT(head) = elm; \
VRBT_PARENT(VRBT_LEFT(old, field), field) = elm; \
if (VRBT_RIGHT(old, field)) \
VRBT_PARENT(VRBT_RIGHT(old, field), field) = elm;\
if (parent) { \
left = parent; \
do { \
VRBT_AUGMENT(left); \
} while ((left = VRBT_PARENT(left, field)) != NULL);\
VRBT_SET_PARENT(VRBT_RIGHT(old, field), elm, field);\
} \
goto color; \
VRBT_SET_PARENT(VRBT_LEFT(old, field), elm, field); \
elm->field = old->field; \
} \
parent = VRBT_PARENT(elm, field); \
color = VRBT_COLOR(elm, field); \
if (child) \
VRBT_PARENT(child, field) = parent; \
if (parent) { \
if (VRBT_LEFT(parent, field) == elm) \
VRBT_LEFT(parent, field) = child; \
else \
VRBT_RIGHT(parent, field) = child; \
VRBT_AUGMENT(parent); \
} else \
VRBT_ROOT(head) = child; \
color: \
if (color == VRBT_BLACK) { \
VRBT_SWAP_CHILD(head, old, elm, field); \
if (child != NULL) \
VRBT_SET_PARENT(child, parent, field); \
if (parent != NULL) \
name##_VRBT_REMOVE_COLOR(head, parent, child); \
while (parent != NULL) { \
VRBT_AUGMENT(parent); \
parent = VRBT_PARENT(parent, field); \
} \
return (old); \
} \
\
}
#define VRBT_GENERATE_INSERT(name, type, field, cmp, attr) \
/* Inserts a node into the RB tree */
\
attr struct type * \
name##_VRBT_INSERT(struct name *head, struct type *elm) \
...
...
@@ -613,18 +654,21 @@ name##_VRBT_INSERT(struct name *head, struct type *elm) \
return (tmp); \
} \
VRBT_SET(elm, parent, field); \
if (parent != NULL) { \
if (comp < 0) \
if (parent == NULL) \
VRBT_ROOT(head) = elm; \
else if (comp < 0) \
VRBT_LEFT(parent, field) = elm; \
else \
VRBT_RIGHT(parent, field) = elm; \
VRBT_AUGMENT(parent); \
} else \
VRBT_ROOT(head) = elm; \
name##_VRBT_INSERT_COLOR(head, elm); \
while (elm != NULL) { \
VRBT_AUGMENT(elm); \
elm = VRBT_PARENT(elm, field); \
} \
return (NULL); \
} \
\
}
#define VRBT_GENERATE_FIND(name, type, field, cmp, attr) \
/* Finds the node with the same key as elm */
\
attr struct type * \
name##_VRBT_FIND(const struct name *head, const struct type *elm) \
...
...
@@ -641,8 +685,9 @@ name##_VRBT_FIND(const struct name *head, const struct type *elm) \
return (tmp); \
} \
return (NULL); \
} \
\
}
#define VRBT_GENERATE_NFIND(name, type, field, cmp, attr) \
/* Finds the first node greater than or equal to the search key */
\
attr struct type * \
name##_VRBT_NFIND(const struct name *head, const struct type *elm) \
...
...
@@ -662,8 +707,9 @@ name##_VRBT_NFIND(const struct name *head, const struct type *elm) \
return (tmp); \
} \
return (res); \
} \
\
}
#define VRBT_GENERATE_NEXT(name, type, field, attr) \
/* ARGSUSED */
\
attr struct type * \
name##_VRBT_NEXT(struct type *elm) \
...
...
@@ -684,8 +730,9 @@ name##_VRBT_NEXT(struct type *elm) \
} \
} \
return (elm); \
} \
\
}
#define VRBT_GENERATE_PREV(name, type, field, attr) \
/* ARGSUSED */
\
attr struct type * \
name##_VRBT_PREV(struct type *elm) \
...
...
@@ -696,7 +743,7 @@ name##_VRBT_PREV(struct type *elm) \
elm = VRBT_RIGHT(elm, field); \
} else { \
if (VRBT_PARENT(elm, field) && \
(elm == VRBT_RIGHT(VRBT_PARENT(elm, field), field)))\
(elm == VRBT_RIGHT(VRBT_PARENT(elm, field), field)))
\
elm = VRBT_PARENT(elm, field); \
else { \
while (VRBT_PARENT(elm, field) && \
...
...
@@ -706,8 +753,9 @@ name##_VRBT_PREV(struct type *elm) \
} \
} \
return (elm); \
} \
\
}
#define VRBT_GENERATE_MINMAX(name, type, field, attr) \
attr struct type * \
name##_VRBT_MINMAX(const struct name *head, int val) \
{ \
...
...
@@ -723,6 +771,22 @@ name##_VRBT_MINMAX(const struct name *head, int val) \
return (parent); \
}
#define VRBT_GENERATE_REINSERT(name, type, field, cmp, attr) \
attr struct type * \
name##_VRBT_REINSERT(struct name *head, struct type *elm) \
{ \
struct type *cmpelm; \
if (((cmpelm = VRBT_PREV(name, head, elm)) != NULL && \
cmp(cmpelm, elm) >= 0) || \
((cmpelm = VRBT_NEXT(name, head, elm)) != NULL && \
cmp(elm, cmpelm) >= 0)) { \
/* XXXLAS: Remove/insert is heavy handed. */
\
VRBT_REMOVE(name, head, elm); \
return (VRBT_INSERT(name, head, elm)); \
} \
return (NULL); \
} \
#define VRBT_NEGINF -1
#define VRBT_INF 1
...
...
@@ -734,6 +798,7 @@ name##_VRBT_MINMAX(const struct name *head, int val) \
#define VRBT_PREV(name, x, y) name##_VRBT_PREV(y)
#define VRBT_MIN(name, x) name##_VRBT_MINMAX(x, VRBT_NEGINF)
#define VRBT_MAX(name, x) name##_VRBT_MINMAX(x, VRBT_INF)
#define VRBT_REINSERT(name, x, y) name##_VRBT_REINSERT(x, y)
#define VRBT_FOREACH(x, name, head) \
for ((x) = VRBT_MIN(name, head); \
...
...
tools/import_vtree_from_freebsd.sh
0 → 100644
View file @
e1ac5933
#
#
if
[
!
-f
vtree.h
]
;
then
echo
"Run from include subdir"
exit
1
fi
if
[
!
-f
/usr/src/sys/sys/tree.h
]
;
then
echo
"You need a FreeBSD source tree in /usr/src"
exit
1
fi
git diff vtree.h | git apply
-R
>
/dev/null 2>&1
||
true
GR
=
f6e54eb360a78856dcde930a00d9b2b3627309ab
(
cd
/usr/src/
&&
git show
$GR
:sys/sys/tree.h
)
|
sed
-E
'
485a\
AN(parent); \\
s/_SYS_TREE_H_/_VTREE_H_/
s/SPLAY/VSPLAY/g
s/RB_/VRBT_/g
/(VRBT_FIND|VRBT_NFIND|VRBT_MINMAX)/{
s/struct name [*]/const struct name */
s/, struct type [*]/, const struct type */
}
/sys\/cdefs/d
s/__unused/v_unused_/
s/^ / /g
'
>
_t
diff
-uw
_t vtree.h
mv
_t vtree.h
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment