Path: blob/main/core/coreutils/src/compat/tree.h
1398 views
/* $OpenBSD: tree.h,v 1.30 2020/10/10 18:03:41 otto Exp $ */1/*2* Copyright 2002 Niels Provos <[email protected]>3* All rights reserved.4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8* 1. Redistributions of source code must retain the above copyright9* notice, this list of conditions and the following disclaimer.10* 2. Redistributions in binary form must reproduce the above copyright11* notice, this list of conditions and the following disclaimer in the12* documentation and/or other materials provided with the distribution.13*14* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR15* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES16* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.17* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,18* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT19* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,20* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY21* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT22* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF23* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.24*/2526#ifndef _SYS_TREE_H_27#define _SYS_TREE_H_2829/*30* This file defines data structures for different types of trees:31* splay trees and red-black trees.32*33* A splay tree is a self-organizing data structure. Every operation34* on the tree causes a splay to happen. The splay moves the requested35* node to the root of the tree and partly rebalances it.36*37* This has the benefit that request locality causes faster lookups as38* the requested nodes move to the top of the tree. On the other hand,39* every lookup causes memory writes.40*41* The Balance Theorem bounds the total access time for m operations42* and n inserts on an initially empty tree as O((m + n)lg n). The43* amortized cost for a sequence of m accesses to a splay tree is O(lg n);44*45* A red-black tree is a binary search tree with the node color as an46* extra attribute. It fulfills a set of conditions:47* - every search path from the root to a leaf consists of the48* same number of black nodes,49* - each red node (except for the root) has a black parent,50* - each leaf node is black.51*52* Every operation on a red-black tree is bounded as O(lg n).53* The maximum height of a red-black tree is 2lg (n+1).54*/5556#define SPLAY_HEAD(name, type) \57struct name { \58struct type *sph_root; /* root of the tree */ \59}6061#define SPLAY_INITIALIZER(root) \62{ NULL }6364#define SPLAY_INIT(root) do { \65(root)->sph_root = NULL; \66} while (0)6768#define SPLAY_ENTRY(type) \69struct { \70struct type *spe_left; /* left element */ \71struct type *spe_right; /* right element */ \72}7374#define SPLAY_LEFT(elm, field) (elm)->field.spe_left75#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right76#define SPLAY_ROOT(head) (head)->sph_root77#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL)7879/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */80#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \81SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \82SPLAY_RIGHT(tmp, field) = (head)->sph_root; \83(head)->sph_root = tmp; \84} while (0)8586#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \87SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \88SPLAY_LEFT(tmp, field) = (head)->sph_root; \89(head)->sph_root = tmp; \90} while (0)9192#define SPLAY_LINKLEFT(head, tmp, field) do { \93SPLAY_LEFT(tmp, field) = (head)->sph_root; \94tmp = (head)->sph_root; \95(head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \96} while (0)9798#define SPLAY_LINKRIGHT(head, tmp, field) do { \99SPLAY_RIGHT(tmp, field) = (head)->sph_root; \100tmp = (head)->sph_root; \101(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \102} while (0)103104#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \105SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \106SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\107SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \108SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \109} while (0)110111/* Generates prototypes and inline functions */112113#define SPLAY_PROTOTYPE(name, type, field, cmp) \114void name##_SPLAY(struct name *, struct type *); \115void name##_SPLAY_MINMAX(struct name *, int); \116struct type *name##_SPLAY_INSERT(struct name *, struct type *); \117struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \118\119/* Finds the node with the same key as elm */ \120static __unused __inline struct type * \121name##_SPLAY_FIND(struct name *head, struct type *elm) \122{ \123if (SPLAY_EMPTY(head)) \124return(NULL); \125name##_SPLAY(head, elm); \126if ((cmp)(elm, (head)->sph_root) == 0) \127return (head->sph_root); \128return (NULL); \129} \130\131static __unused __inline struct type * \132name##_SPLAY_NEXT(struct name *head, struct type *elm) \133{ \134name##_SPLAY(head, elm); \135if (SPLAY_RIGHT(elm, field) != NULL) { \136elm = SPLAY_RIGHT(elm, field); \137while (SPLAY_LEFT(elm, field) != NULL) { \138elm = SPLAY_LEFT(elm, field); \139} \140} else \141elm = NULL; \142return (elm); \143} \144\145static __unused __inline struct type * \146name##_SPLAY_MIN_MAX(struct name *head, int val) \147{ \148name##_SPLAY_MINMAX(head, val); \149return (SPLAY_ROOT(head)); \150}151152/* Main splay operation.153* Moves node close to the key of elm to top154*/155#define SPLAY_GENERATE(name, type, field, cmp) \156struct type * \157name##_SPLAY_INSERT(struct name *head, struct type *elm) \158{ \159if (SPLAY_EMPTY(head)) { \160SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \161} else { \162int __comp; \163name##_SPLAY(head, elm); \164__comp = (cmp)(elm, (head)->sph_root); \165if(__comp < 0) { \166SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\167SPLAY_RIGHT(elm, field) = (head)->sph_root; \168SPLAY_LEFT((head)->sph_root, field) = NULL; \169} else if (__comp > 0) { \170SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\171SPLAY_LEFT(elm, field) = (head)->sph_root; \172SPLAY_RIGHT((head)->sph_root, field) = NULL; \173} else \174return ((head)->sph_root); \175} \176(head)->sph_root = (elm); \177return (NULL); \178} \179\180struct type * \181name##_SPLAY_REMOVE(struct name *head, struct type *elm) \182{ \183struct type *__tmp; \184if (SPLAY_EMPTY(head)) \185return (NULL); \186name##_SPLAY(head, elm); \187if ((cmp)(elm, (head)->sph_root) == 0) { \188if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \189(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\190} else { \191__tmp = SPLAY_RIGHT((head)->sph_root, field); \192(head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\193name##_SPLAY(head, elm); \194SPLAY_RIGHT((head)->sph_root, field) = __tmp; \195} \196return (elm); \197} \198return (NULL); \199} \200\201void \202name##_SPLAY(struct name *head, struct type *elm) \203{ \204struct type __node, *__left, *__right, *__tmp; \205int __comp; \206\207SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\208__left = __right = &__node; \209\210while ((__comp = (cmp)(elm, (head)->sph_root))) { \211if (__comp < 0) { \212__tmp = SPLAY_LEFT((head)->sph_root, field); \213if (__tmp == NULL) \214break; \215if ((cmp)(elm, __tmp) < 0){ \216SPLAY_ROTATE_RIGHT(head, __tmp, field); \217if (SPLAY_LEFT((head)->sph_root, field) == NULL)\218break; \219} \220SPLAY_LINKLEFT(head, __right, field); \221} else if (__comp > 0) { \222__tmp = SPLAY_RIGHT((head)->sph_root, field); \223if (__tmp == NULL) \224break; \225if ((cmp)(elm, __tmp) > 0){ \226SPLAY_ROTATE_LEFT(head, __tmp, field); \227if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\228break; \229} \230SPLAY_LINKRIGHT(head, __left, field); \231} \232} \233SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \234} \235\236/* Splay with either the minimum or the maximum element \237* Used to find minimum or maximum element in tree. \238*/ \239void name##_SPLAY_MINMAX(struct name *head, int __comp) \240{ \241struct type __node, *__left, *__right, *__tmp; \242\243SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\244__left = __right = &__node; \245\246while (1) { \247if (__comp < 0) { \248__tmp = SPLAY_LEFT((head)->sph_root, field); \249if (__tmp == NULL) \250break; \251if (__comp < 0){ \252SPLAY_ROTATE_RIGHT(head, __tmp, field); \253if (SPLAY_LEFT((head)->sph_root, field) == NULL)\254break; \255} \256SPLAY_LINKLEFT(head, __right, field); \257} else if (__comp > 0) { \258__tmp = SPLAY_RIGHT((head)->sph_root, field); \259if (__tmp == NULL) \260break; \261if (__comp > 0) { \262SPLAY_ROTATE_LEFT(head, __tmp, field); \263if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\264break; \265} \266SPLAY_LINKRIGHT(head, __left, field); \267} \268} \269SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \270}271272#define SPLAY_NEGINF -1273#define SPLAY_INF 1274275#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y)276#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y)277#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y)278#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y)279#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \280: name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))281#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \282: name##_SPLAY_MIN_MAX(x, SPLAY_INF))283284#define SPLAY_FOREACH(x, name, head) \285for ((x) = SPLAY_MIN(name, head); \286(x) != NULL; \287(x) = SPLAY_NEXT(name, head, x))288289/* Macros that define a red-black tree */290#define RB_HEAD(name, type) \291struct name { \292struct type *rbh_root; /* root of the tree */ \293}294295#define RB_INITIALIZER(root) \296{ NULL }297298#define RB_INIT(root) do { \299(root)->rbh_root = NULL; \300} while (0)301302#define RB_BLACK 0303#define RB_RED 1304#define RB_ENTRY(type) \305struct { \306struct type *rbe_left; /* left element */ \307struct type *rbe_right; /* right element */ \308struct type *rbe_parent; /* parent element */ \309int rbe_color; /* node color */ \310}311312#define RB_LEFT(elm, field) (elm)->field.rbe_left313#define RB_RIGHT(elm, field) (elm)->field.rbe_right314#define RB_PARENT(elm, field) (elm)->field.rbe_parent315#define RB_COLOR(elm, field) (elm)->field.rbe_color316#define RB_ROOT(head) (head)->rbh_root317#define RB_EMPTY(head) (RB_ROOT(head) == NULL)318319#define RB_SET(elm, parent, field) do { \320RB_PARENT(elm, field) = parent; \321RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \322RB_COLOR(elm, field) = RB_RED; \323} while (0)324325#define RB_SET_BLACKRED(black, red, field) do { \326RB_COLOR(black, field) = RB_BLACK; \327RB_COLOR(red, field) = RB_RED; \328} while (0)329330#ifndef RB_AUGMENT331#define RB_AUGMENT(x) do {} while (0)332#endif333334#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \335(tmp) = RB_RIGHT(elm, field); \336if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) { \337RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \338} \339RB_AUGMENT(elm); \340if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \341if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \342RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \343else \344RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \345} else \346(head)->rbh_root = (tmp); \347RB_LEFT(tmp, field) = (elm); \348RB_PARENT(elm, field) = (tmp); \349RB_AUGMENT(tmp); \350if ((RB_PARENT(tmp, field))) \351RB_AUGMENT(RB_PARENT(tmp, field)); \352} while (0)353354#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \355(tmp) = RB_LEFT(elm, field); \356if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) { \357RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \358} \359RB_AUGMENT(elm); \360if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \361if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \362RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \363else \364RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \365} else \366(head)->rbh_root = (tmp); \367RB_RIGHT(tmp, field) = (elm); \368RB_PARENT(elm, field) = (tmp); \369RB_AUGMENT(tmp); \370if ((RB_PARENT(tmp, field))) \371RB_AUGMENT(RB_PARENT(tmp, field)); \372} while (0)373374/* Generates prototypes and inline functions */375#define RB_PROTOTYPE(name, type, field, cmp) \376RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)377#define RB_PROTOTYPE_STATIC(name, type, field, cmp) \378RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static)379#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \380attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \381attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\382attr struct type *name##_RB_REMOVE(struct name *, struct type *); \383attr struct type *name##_RB_INSERT(struct name *, struct type *); \384attr struct type *name##_RB_FIND(struct name *, struct type *); \385attr struct type *name##_RB_NFIND(struct name *, struct type *); \386attr struct type *name##_RB_NEXT(struct type *); \387attr struct type *name##_RB_PREV(struct type *); \388attr struct type *name##_RB_MINMAX(struct name *, int); \389\390391/* Main rb operation.392* Moves node close to the key of elm to top393*/394#define RB_GENERATE(name, type, field, cmp) \395RB_GENERATE_INTERNAL(name, type, field, cmp,)396#define RB_GENERATE_STATIC(name, type, field, cmp) \397RB_GENERATE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static)398#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \399attr void \400name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \401{ \402struct type *parent, *gparent, *tmp; \403while ((parent = RB_PARENT(elm, field)) && \404RB_COLOR(parent, field) == RB_RED) { \405gparent = RB_PARENT(parent, field); \406if (parent == RB_LEFT(gparent, field)) { \407tmp = RB_RIGHT(gparent, field); \408if (tmp && RB_COLOR(tmp, field) == RB_RED) { \409RB_COLOR(tmp, field) = RB_BLACK; \410RB_SET_BLACKRED(parent, gparent, field);\411elm = gparent; \412continue; \413} \414if (RB_RIGHT(parent, field) == elm) { \415RB_ROTATE_LEFT(head, parent, tmp, field);\416tmp = parent; \417parent = elm; \418elm = tmp; \419} \420RB_SET_BLACKRED(parent, gparent, field); \421RB_ROTATE_RIGHT(head, gparent, tmp, field); \422} else { \423tmp = RB_LEFT(gparent, field); \424if (tmp && RB_COLOR(tmp, field) == RB_RED) { \425RB_COLOR(tmp, field) = RB_BLACK; \426RB_SET_BLACKRED(parent, gparent, field);\427elm = gparent; \428continue; \429} \430if (RB_LEFT(parent, field) == elm) { \431RB_ROTATE_RIGHT(head, parent, tmp, field);\432tmp = parent; \433parent = elm; \434elm = tmp; \435} \436RB_SET_BLACKRED(parent, gparent, field); \437RB_ROTATE_LEFT(head, gparent, tmp, field); \438} \439} \440RB_COLOR(head->rbh_root, field) = RB_BLACK; \441} \442\443attr void \444name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \445{ \446struct type *tmp; \447while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \448elm != RB_ROOT(head)) { \449if (RB_LEFT(parent, field) == elm) { \450tmp = RB_RIGHT(parent, field); \451if (RB_COLOR(tmp, field) == RB_RED) { \452RB_SET_BLACKRED(tmp, parent, field); \453RB_ROTATE_LEFT(head, parent, tmp, field);\454tmp = RB_RIGHT(parent, field); \455} \456if ((RB_LEFT(tmp, field) == NULL || \457RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\458(RB_RIGHT(tmp, field) == NULL || \459RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\460RB_COLOR(tmp, field) = RB_RED; \461elm = parent; \462parent = RB_PARENT(elm, field); \463} else { \464if (RB_RIGHT(tmp, field) == NULL || \465RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\466struct type *oleft; \467if ((oleft = RB_LEFT(tmp, field)))\468RB_COLOR(oleft, field) = RB_BLACK;\469RB_COLOR(tmp, field) = RB_RED; \470RB_ROTATE_RIGHT(head, tmp, oleft, field);\471tmp = RB_RIGHT(parent, field); \472} \473RB_COLOR(tmp, field) = RB_COLOR(parent, field);\474RB_COLOR(parent, field) = RB_BLACK; \475if (RB_RIGHT(tmp, field)) \476RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\477RB_ROTATE_LEFT(head, parent, tmp, field);\478elm = RB_ROOT(head); \479break; \480} \481} else { \482tmp = RB_LEFT(parent, field); \483if (RB_COLOR(tmp, field) == RB_RED) { \484RB_SET_BLACKRED(tmp, parent, field); \485RB_ROTATE_RIGHT(head, parent, tmp, field);\486tmp = RB_LEFT(parent, field); \487} \488if ((RB_LEFT(tmp, field) == NULL || \489RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\490(RB_RIGHT(tmp, field) == NULL || \491RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\492RB_COLOR(tmp, field) = RB_RED; \493elm = parent; \494parent = RB_PARENT(elm, field); \495} else { \496if (RB_LEFT(tmp, field) == NULL || \497RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\498struct type *oright; \499if ((oright = RB_RIGHT(tmp, field)))\500RB_COLOR(oright, field) = RB_BLACK;\501RB_COLOR(tmp, field) = RB_RED; \502RB_ROTATE_LEFT(head, tmp, oright, field);\503tmp = RB_LEFT(parent, field); \504} \505RB_COLOR(tmp, field) = RB_COLOR(parent, field);\506RB_COLOR(parent, field) = RB_BLACK; \507if (RB_LEFT(tmp, field)) \508RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\509RB_ROTATE_RIGHT(head, parent, tmp, field);\510elm = RB_ROOT(head); \511break; \512} \513} \514} \515if (elm) \516RB_COLOR(elm, field) = RB_BLACK; \517} \518\519attr struct type * \520name##_RB_REMOVE(struct name *head, struct type *elm) \521{ \522struct type *child, *parent, *old = elm; \523int color; \524if (RB_LEFT(elm, field) == NULL) \525child = RB_RIGHT(elm, field); \526else if (RB_RIGHT(elm, field) == NULL) \527child = RB_LEFT(elm, field); \528else { \529struct type *left; \530elm = RB_RIGHT(elm, field); \531while ((left = RB_LEFT(elm, field))) \532elm = left; \533child = RB_RIGHT(elm, field); \534parent = RB_PARENT(elm, field); \535color = RB_COLOR(elm, field); \536if (child) \537RB_PARENT(child, field) = parent; \538if (parent) { \539if (RB_LEFT(parent, field) == elm) \540RB_LEFT(parent, field) = child; \541else \542RB_RIGHT(parent, field) = child; \543RB_AUGMENT(parent); \544} else \545RB_ROOT(head) = child; \546if (RB_PARENT(elm, field) == old) \547parent = elm; \548(elm)->field = (old)->field; \549if (RB_PARENT(old, field)) { \550if (RB_LEFT(RB_PARENT(old, field), field) == old)\551RB_LEFT(RB_PARENT(old, field), field) = elm;\552else \553RB_RIGHT(RB_PARENT(old, field), field) = elm;\554RB_AUGMENT(RB_PARENT(old, field)); \555} else \556RB_ROOT(head) = elm; \557RB_PARENT(RB_LEFT(old, field), field) = elm; \558if (RB_RIGHT(old, field)) \559RB_PARENT(RB_RIGHT(old, field), field) = elm; \560if (parent) { \561left = parent; \562do { \563RB_AUGMENT(left); \564} while ((left = RB_PARENT(left, field))); \565} \566goto color; \567} \568parent = RB_PARENT(elm, field); \569color = RB_COLOR(elm, field); \570if (child) \571RB_PARENT(child, field) = parent; \572if (parent) { \573if (RB_LEFT(parent, field) == elm) \574RB_LEFT(parent, field) = child; \575else \576RB_RIGHT(parent, field) = child; \577RB_AUGMENT(parent); \578} else \579RB_ROOT(head) = child; \580color: \581if (color == RB_BLACK) \582name##_RB_REMOVE_COLOR(head, parent, child); \583return (old); \584} \585\586/* Inserts a node into the RB tree */ \587attr struct type * \588name##_RB_INSERT(struct name *head, struct type *elm) \589{ \590struct type *tmp; \591struct type *parent = NULL; \592int comp = 0; \593tmp = RB_ROOT(head); \594while (tmp) { \595parent = tmp; \596comp = (cmp)(elm, parent); \597if (comp < 0) \598tmp = RB_LEFT(tmp, field); \599else if (comp > 0) \600tmp = RB_RIGHT(tmp, field); \601else \602return (tmp); \603} \604RB_SET(elm, parent, field); \605if (parent != NULL) { \606if (comp < 0) \607RB_LEFT(parent, field) = elm; \608else \609RB_RIGHT(parent, field) = elm; \610RB_AUGMENT(parent); \611} else \612RB_ROOT(head) = elm; \613name##_RB_INSERT_COLOR(head, elm); \614return (NULL); \615} \616\617/* Finds the node with the same key as elm */ \618attr struct type * \619name##_RB_FIND(struct name *head, struct type *elm) \620{ \621struct type *tmp = RB_ROOT(head); \622int comp; \623while (tmp) { \624comp = cmp(elm, tmp); \625if (comp < 0) \626tmp = RB_LEFT(tmp, field); \627else if (comp > 0) \628tmp = RB_RIGHT(tmp, field); \629else \630return (tmp); \631} \632return (NULL); \633} \634\635/* Finds the first node greater than or equal to the search key */ \636attr struct type * \637name##_RB_NFIND(struct name *head, struct type *elm) \638{ \639struct type *tmp = RB_ROOT(head); \640struct type *res = NULL; \641int comp; \642while (tmp) { \643comp = cmp(elm, tmp); \644if (comp < 0) { \645res = tmp; \646tmp = RB_LEFT(tmp, field); \647} \648else if (comp > 0) \649tmp = RB_RIGHT(tmp, field); \650else \651return (tmp); \652} \653return (res); \654} \655\656/* ARGSUSED */ \657attr struct type * \658name##_RB_NEXT(struct type *elm) \659{ \660if (RB_RIGHT(elm, field)) { \661elm = RB_RIGHT(elm, field); \662while (RB_LEFT(elm, field)) \663elm = RB_LEFT(elm, field); \664} else { \665if (RB_PARENT(elm, field) && \666(elm == RB_LEFT(RB_PARENT(elm, field), field))) \667elm = RB_PARENT(elm, field); \668else { \669while (RB_PARENT(elm, field) && \670(elm == RB_RIGHT(RB_PARENT(elm, field), field)))\671elm = RB_PARENT(elm, field); \672elm = RB_PARENT(elm, field); \673} \674} \675return (elm); \676} \677\678/* ARGSUSED */ \679attr struct type * \680name##_RB_PREV(struct type *elm) \681{ \682if (RB_LEFT(elm, field)) { \683elm = RB_LEFT(elm, field); \684while (RB_RIGHT(elm, field)) \685elm = RB_RIGHT(elm, field); \686} else { \687if (RB_PARENT(elm, field) && \688(elm == RB_RIGHT(RB_PARENT(elm, field), field))) \689elm = RB_PARENT(elm, field); \690else { \691while (RB_PARENT(elm, field) && \692(elm == RB_LEFT(RB_PARENT(elm, field), field)))\693elm = RB_PARENT(elm, field); \694elm = RB_PARENT(elm, field); \695} \696} \697return (elm); \698} \699\700attr struct type * \701name##_RB_MINMAX(struct name *head, int val) \702{ \703struct type *tmp = RB_ROOT(head); \704struct type *parent = NULL; \705while (tmp) { \706parent = tmp; \707if (val < 0) \708tmp = RB_LEFT(tmp, field); \709else \710tmp = RB_RIGHT(tmp, field); \711} \712return (parent); \713}714715#define RB_NEGINF -1716#define RB_INF 1717718#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)719#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)720#define RB_FIND(name, x, y) name##_RB_FIND(x, y)721#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y)722#define RB_NEXT(name, x, y) name##_RB_NEXT(y)723#define RB_PREV(name, x, y) name##_RB_PREV(y)724#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF)725#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF)726727#define RB_FOREACH(x, name, head) \728for ((x) = RB_MIN(name, head); \729(x) != NULL; \730(x) = name##_RB_NEXT(x))731732#define RB_FOREACH_SAFE(x, name, head, y) \733for ((x) = RB_MIN(name, head); \734((x) != NULL) && ((y) = name##_RB_NEXT(x), 1); \735(x) = (y))736737#define RB_FOREACH_REVERSE(x, name, head) \738for ((x) = RB_MAX(name, head); \739(x) != NULL; \740(x) = name##_RB_PREV(x))741742#define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \743for ((x) = RB_MAX(name, head); \744((x) != NULL) && ((y) = name##_RB_PREV(x), 1); \745(x) = (y))746747748/*749* Copyright (c) 2016 David Gwynne <[email protected]>750*751* Permission to use, copy, modify, and distribute this software for any752* purpose with or without fee is hereby granted, provided that the above753* copyright notice and this permission notice appear in all copies.754*755* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES756* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF757* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR758* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES759* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN760* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF761* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.762*/763764struct rb_type {765int (*t_compare)(const void *, const void *);766void (*t_augment)(void *);767unsigned int t_offset; /* offset of rb_entry in type */768};769770struct rb_tree {771struct rb_entry *rbt_root;772};773774struct rb_entry {775struct rb_entry *rbt_parent;776struct rb_entry *rbt_left;777struct rb_entry *rbt_right;778unsigned int rbt_color;779};780781#define RBT_HEAD(_name, _type) \782struct _name { \783struct rb_tree rbh_root; \784}785786#define RBT_ENTRY(_type) struct rb_entry787788static inline void789_rb_init(struct rb_tree *rbt)790{791rbt->rbt_root = NULL;792}793794static inline int795_rb_empty(struct rb_tree *rbt)796{797return (rbt->rbt_root == NULL);798}799800void *_rb_insert(const struct rb_type *, struct rb_tree *, void *);801void *_rb_remove(const struct rb_type *, struct rb_tree *, void *);802void *_rb_find(const struct rb_type *, struct rb_tree *, const void *);803void *_rb_nfind(const struct rb_type *, struct rb_tree *, const void *);804void *_rb_root(const struct rb_type *, struct rb_tree *);805void *_rb_min(const struct rb_type *, struct rb_tree *);806void *_rb_max(const struct rb_type *, struct rb_tree *);807void *_rb_next(const struct rb_type *, void *);808void *_rb_prev(const struct rb_type *, void *);809void *_rb_left(const struct rb_type *, void *);810void *_rb_right(const struct rb_type *, void *);811void *_rb_parent(const struct rb_type *, void *);812void _rb_set_left(const struct rb_type *, void *, void *);813void _rb_set_right(const struct rb_type *, void *, void *);814void _rb_set_parent(const struct rb_type *, void *, void *);815void _rb_poison(const struct rb_type *, void *, unsigned long);816int _rb_check(const struct rb_type *, void *, unsigned long);817818#define RBT_INITIALIZER(_head) { { NULL } }819820#define RBT_PROTOTYPE(_name, _type, _field, _cmp) \821extern const struct rb_type *const _name##_RBT_TYPE; \822\823__unused static inline void \824_name##_RBT_INIT(struct _name *head) \825{ \826_rb_init(&head->rbh_root); \827} \828\829__unused static inline struct _type * \830_name##_RBT_INSERT(struct _name *head, struct _type *elm) \831{ \832return _rb_insert(_name##_RBT_TYPE, &head->rbh_root, elm); \833} \834\835__unused static inline struct _type * \836_name##_RBT_REMOVE(struct _name *head, struct _type *elm) \837{ \838return _rb_remove(_name##_RBT_TYPE, &head->rbh_root, elm); \839} \840\841__unused static inline struct _type * \842_name##_RBT_FIND(struct _name *head, const struct _type *key) \843{ \844return _rb_find(_name##_RBT_TYPE, &head->rbh_root, key); \845} \846\847__unused static inline struct _type * \848_name##_RBT_NFIND(struct _name *head, const struct _type *key) \849{ \850return _rb_nfind(_name##_RBT_TYPE, &head->rbh_root, key); \851} \852\853__unused static inline struct _type * \854_name##_RBT_ROOT(struct _name *head) \855{ \856return _rb_root(_name##_RBT_TYPE, &head->rbh_root); \857} \858\859__unused static inline int \860_name##_RBT_EMPTY(struct _name *head) \861{ \862return _rb_empty(&head->rbh_root); \863} \864\865__unused static inline struct _type * \866_name##_RBT_MIN(struct _name *head) \867{ \868return _rb_min(_name##_RBT_TYPE, &head->rbh_root); \869} \870\871__unused static inline struct _type * \872_name##_RBT_MAX(struct _name *head) \873{ \874return _rb_max(_name##_RBT_TYPE, &head->rbh_root); \875} \876\877__unused static inline struct _type * \878_name##_RBT_NEXT(struct _type *elm) \879{ \880return _rb_next(_name##_RBT_TYPE, elm); \881} \882\883__unused static inline struct _type * \884_name##_RBT_PREV(struct _type *elm) \885{ \886return _rb_prev(_name##_RBT_TYPE, elm); \887} \888\889__unused static inline struct _type * \890_name##_RBT_LEFT(struct _type *elm) \891{ \892return _rb_left(_name##_RBT_TYPE, elm); \893} \894\895__unused static inline struct _type * \896_name##_RBT_RIGHT(struct _type *elm) \897{ \898return _rb_right(_name##_RBT_TYPE, elm); \899} \900\901__unused static inline struct _type * \902_name##_RBT_PARENT(struct _type *elm) \903{ \904return _rb_parent(_name##_RBT_TYPE, elm); \905} \906\907__unused static inline void \908_name##_RBT_SET_LEFT(struct _type *elm, struct _type *left) \909{ \910_rb_set_left(_name##_RBT_TYPE, elm, left); \911} \912\913__unused static inline void \914_name##_RBT_SET_RIGHT(struct _type *elm, struct _type *right) \915{ \916_rb_set_right(_name##_RBT_TYPE, elm, right); \917} \918\919__unused static inline void \920_name##_RBT_SET_PARENT(struct _type *elm, struct _type *parent) \921{ \922_rb_set_parent(_name##_RBT_TYPE, elm, parent); \923} \924\925__unused static inline void \926_name##_RBT_POISON(struct _type *elm, unsigned long poison) \927{ \928_rb_poison(_name##_RBT_TYPE, elm, poison); \929} \930\931__unused static inline int \932_name##_RBT_CHECK(struct _type *elm, unsigned long poison) \933{ \934return _rb_check(_name##_RBT_TYPE, elm, poison); \935}936937#define RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp, _aug) \938static int \939_name##_RBT_COMPARE(const void *lptr, const void *rptr) \940{ \941const struct _type *l = lptr, *r = rptr; \942return _cmp(l, r); \943} \944static const struct rb_type _name##_RBT_INFO = { \945_name##_RBT_COMPARE, \946_aug, \947offsetof(struct _type, _field), \948}; \949const struct rb_type *const _name##_RBT_TYPE = &_name##_RBT_INFO950951#define RBT_GENERATE_AUGMENT(_name, _type, _field, _cmp, _aug) \952static void \953_name##_RBT_AUGMENT(void *ptr) \954{ \955struct _type *p = ptr; \956return _aug(p); \957} \958RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp, _name##_RBT_AUGMENT)959960#define RBT_GENERATE(_name, _type, _field, _cmp) \961RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp, NULL)962963#define RBT_INIT(_name, _head) _name##_RBT_INIT(_head)964#define RBT_INSERT(_name, _head, _elm) _name##_RBT_INSERT(_head, _elm)965#define RBT_REMOVE(_name, _head, _elm) _name##_RBT_REMOVE(_head, _elm)966#define RBT_FIND(_name, _head, _key) _name##_RBT_FIND(_head, _key)967#define RBT_NFIND(_name, _head, _key) _name##_RBT_NFIND(_head, _key)968#define RBT_ROOT(_name, _head) _name##_RBT_ROOT(_head)969#define RBT_EMPTY(_name, _head) _name##_RBT_EMPTY(_head)970#define RBT_MIN(_name, _head) _name##_RBT_MIN(_head)971#define RBT_MAX(_name, _head) _name##_RBT_MAX(_head)972#define RBT_NEXT(_name, _elm) _name##_RBT_NEXT(_elm)973#define RBT_PREV(_name, _elm) _name##_RBT_PREV(_elm)974#define RBT_LEFT(_name, _elm) _name##_RBT_LEFT(_elm)975#define RBT_RIGHT(_name, _elm) _name##_RBT_RIGHT(_elm)976#define RBT_PARENT(_name, _elm) _name##_RBT_PARENT(_elm)977#define RBT_SET_LEFT(_name, _elm, _l) _name##_RBT_SET_LEFT(_elm, _l)978#define RBT_SET_RIGHT(_name, _elm, _r) _name##_RBT_SET_RIGHT(_elm, _r)979#define RBT_SET_PARENT(_name, _elm, _p) _name##_RBT_SET_PARENT(_elm, _p)980#define RBT_POISON(_name, _elm, _p) _name##_RBT_POISON(_elm, _p)981#define RBT_CHECK(_name, _elm, _p) _name##_RBT_CHECK(_elm, _p)982983#define RBT_FOREACH(_e, _name, _head) \984for ((_e) = RBT_MIN(_name, (_head)); \985(_e) != NULL; \986(_e) = RBT_NEXT(_name, (_e)))987988#define RBT_FOREACH_SAFE(_e, _name, _head, _n) \989for ((_e) = RBT_MIN(_name, (_head)); \990(_e) != NULL && ((_n) = RBT_NEXT(_name, (_e)), 1); \991(_e) = (_n))992993#define RBT_FOREACH_REVERSE(_e, _name, _head) \994for ((_e) = RBT_MAX(_name, (_head)); \995(_e) != NULL; \996(_e) = RBT_PREV(_name, (_e)))997998#define RBT_FOREACH_REVERSE_SAFE(_e, _name, _head, _n) \999for ((_e) = RBT_MAX(_name, (_head)); \1000(_e) != NULL && ((_n) = RBT_PREV(_name, (_e)), 1); \1001(_e) = (_n))10021003#endif /* _SYS_TREE_H_ */100410051006