LCOV - code coverage report
Current view: top level - kern - subr_tree.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 21 327 6.4 %
Date: 2018-10-19 03:25:38 Functions: 0 28 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: subr_tree.c,v 1.9 2017/06/08 03:30:52 dlg Exp $ */
       2             : 
       3             : /*
       4             :  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
       5             :  * All rights reserved.
       6             :  *
       7             :  * Redistribution and use in source and binary forms, with or without
       8             :  * modification, are permitted provided that the following conditions
       9             :  * are met:
      10             :  * 1. Redistributions of source code must retain the above copyright
      11             :  *    notice, this list of conditions and the following disclaimer.
      12             :  * 2. Redistributions in binary form must reproduce the above copyright
      13             :  *    notice, this list of conditions and the following disclaimer in the
      14             :  *    documentation and/or other materials provided with the distribution.
      15             :  *
      16             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
      17             :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      18             :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      19             :  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
      20             :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      21             :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      22             :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      23             :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      24             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      25             :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      26             :  */
      27             : 
      28             : /*
      29             :  * Copyright (c) 2016 David Gwynne <dlg@openbsd.org>
      30             :  *
      31             :  * Permission to use, copy, modify, and distribute this software for any
      32             :  * purpose with or without fee is hereby granted, provided that the above
      33             :  * copyright notice and this permission notice appear in all copies.
      34             :  *
      35             :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      36             :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      37             :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      38             :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      39             :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      40             :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      41             :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      42             :  */
      43             : 
      44             : #include <sys/tree.h>
      45             : 
      46             : static inline struct rb_entry *
      47           0 : rb_n2e(const struct rb_type *t, void *node)
      48             : {
      49           0 :         unsigned long addr = (unsigned long)node;
      50             : 
      51        4322 :         return ((struct rb_entry *)(addr + t->t_offset));
      52             : }
      53             : 
      54             : static inline void *
      55           0 : rb_e2n(const struct rb_type *t, struct rb_entry *rbe)
      56             : {
      57           0 :         unsigned long addr = (unsigned long)rbe;
      58             : 
      59        2143 :         return ((void *)(addr - t->t_offset));
      60             : }
      61             : 
      62             : #define RBE_LEFT(_rbe)          (_rbe)->rbt_left
      63             : #define RBE_RIGHT(_rbe)         (_rbe)->rbt_right
      64             : #define RBE_PARENT(_rbe)        (_rbe)->rbt_parent
      65             : #define RBE_COLOR(_rbe)         (_rbe)->rbt_color
      66             : 
      67             : #define RBH_ROOT(_rbt)          (_rbt)->rbt_root
      68             : 
      69             : static inline void
      70           0 : rbe_set(struct rb_entry *rbe, struct rb_entry *parent)
      71             : {
      72           0 :         RBE_PARENT(rbe) = parent;
      73           0 :         RBE_LEFT(rbe) = RBE_RIGHT(rbe) = NULL;
      74           0 :         RBE_COLOR(rbe) = RB_RED;
      75           0 : }
      76             : 
      77             : static inline void
      78           0 : rbe_set_blackred(struct rb_entry *black, struct rb_entry *red)
      79             : {
      80           0 :         RBE_COLOR(black) = RB_BLACK;
      81           0 :         RBE_COLOR(red) = RB_RED;
      82           0 : }
      83             : 
      84             : static inline void
      85           0 : rbe_augment(const struct rb_type *t, struct rb_entry *rbe)
      86             : {
      87           0 :         (*t->t_augment)(rb_e2n(t, rbe));
      88           0 : }
      89             : 
      90             : static inline void
      91           0 : rbe_if_augment(const struct rb_type *t, struct rb_entry *rbe)
      92             : {
      93           0 :         if (t->t_augment != NULL)
      94           0 :                 rbe_augment(t, rbe);
      95           0 : }
      96             : 
      97             : static inline void
      98           0 : rbe_rotate_left(const struct rb_type *t, struct rb_tree *rbt,
      99             :     struct rb_entry *rbe)
     100             : {
     101             :         struct rb_entry *parent;
     102             :         struct rb_entry *tmp;
     103             : 
     104           0 :         tmp = RBE_RIGHT(rbe);
     105           0 :         RBE_RIGHT(rbe) = RBE_LEFT(tmp);
     106           0 :         if (RBE_RIGHT(rbe) != NULL)
     107           0 :                 RBE_PARENT(RBE_LEFT(tmp)) = rbe;
     108             : 
     109          60 :         parent = RBE_PARENT(rbe);
     110           0 :         RBE_PARENT(tmp) = parent;
     111           0 :         if (parent != NULL) {
     112          60 :                 if (rbe == RBE_LEFT(parent))
     113           0 :                         RBE_LEFT(parent) = tmp;
     114             :                 else
     115           0 :                         RBE_RIGHT(parent) = tmp;
     116             :         } else
     117           0 :                 RBH_ROOT(rbt) = tmp;
     118             : 
     119           0 :         RBE_LEFT(tmp) = rbe;
     120           0 :         RBE_PARENT(rbe) = tmp;
     121             : 
     122          60 :         if (t->t_augment != NULL) {
     123           0 :                 rbe_augment(t, rbe);
     124           0 :                 rbe_augment(t, tmp);
     125           0 :                 parent = RBE_PARENT(tmp);
     126           0 :                 if (parent != NULL)
     127           0 :                         rbe_augment(t, parent);
     128             :         }
     129           0 : }
     130             : 
     131             : static inline void
     132           0 : rbe_rotate_right(const struct rb_type *t, struct rb_tree *rbt,
     133             :     struct rb_entry *rbe)
     134             : {
     135             :         struct rb_entry *parent;
     136             :         struct rb_entry *tmp;
     137             : 
     138           0 :         tmp = RBE_LEFT(rbe);
     139           0 :         RBE_LEFT(rbe) = RBE_RIGHT(tmp);
     140           0 :         if (RBE_LEFT(rbe) != NULL)
     141           0 :                 RBE_PARENT(RBE_RIGHT(tmp)) = rbe;
     142             : 
     143           0 :         parent = RBE_PARENT(rbe);
     144           0 :         RBE_PARENT(tmp) = parent;
     145           0 :         if (parent != NULL) {
     146           0 :                 if (rbe == RBE_LEFT(parent))
     147           0 :                         RBE_LEFT(parent) = tmp;
     148             :                 else
     149           0 :                         RBE_RIGHT(parent) = tmp;
     150             :         } else
     151           0 :                 RBH_ROOT(rbt) = tmp;
     152             : 
     153           0 :         RBE_RIGHT(tmp) = rbe;
     154           0 :         RBE_PARENT(rbe) = tmp;
     155             : 
     156           0 :         if (t->t_augment != NULL) {
     157           0 :                 rbe_augment(t, rbe);
     158           0 :                 rbe_augment(t, tmp);
     159           0 :                 parent = RBE_PARENT(tmp);
     160           0 :                 if (parent != NULL)
     161           0 :                         rbe_augment(t, parent);
     162             :         }
     163           0 : }
     164             : 
     165             : static inline void
     166           0 : rbe_insert_color(const struct rb_type *t, struct rb_tree *rbt,
     167             :     struct rb_entry *rbe)
     168             : {
     169             :         struct rb_entry *parent, *gparent, *tmp;
     170             : 
     171          60 :         while ((parent = RBE_PARENT(rbe)) != NULL &&
     172           0 :             RBE_COLOR(parent) == RB_RED) {
     173           0 :                 gparent = RBE_PARENT(parent);
     174             : 
     175           0 :                 if (parent == RBE_LEFT(gparent)) {
     176           0 :                         tmp = RBE_RIGHT(gparent);
     177           0 :                         if (tmp != NULL && RBE_COLOR(tmp) == RB_RED) {
     178           0 :                                 RBE_COLOR(tmp) = RB_BLACK;
     179           0 :                                 rbe_set_blackred(parent, gparent);
     180             :                                 rbe = gparent;
     181           0 :                                 continue;
     182             :                         }
     183             : 
     184           0 :                         if (RBE_RIGHT(parent) == rbe) {
     185           0 :                                 rbe_rotate_left(t, rbt, parent);
     186             :                                 tmp = parent;
     187             :                                 parent = rbe;
     188             :                                 rbe = tmp;
     189           0 :                         }
     190             : 
     191           0 :                         rbe_set_blackred(parent, gparent);
     192           0 :                         rbe_rotate_right(t, rbt, gparent);
     193           0 :                 } else {
     194             :                         tmp = RBE_LEFT(gparent);
     195           0 :                         if (tmp != NULL && RBE_COLOR(tmp) == RB_RED) {
     196           0 :                                 RBE_COLOR(tmp) = RB_BLACK;
     197           0 :                                 rbe_set_blackred(parent, gparent);
     198             :                                 rbe = gparent;
     199           0 :                                 continue;
     200             :                         }
     201             : 
     202         120 :                         if (RBE_LEFT(parent) == rbe) {
     203           0 :                                 rbe_rotate_right(t, rbt, parent);
     204             :                                 tmp = parent;
     205             :                                 parent = rbe;
     206             :                                 rbe = tmp;
     207           0 :                         }
     208             : 
     209           0 :                         rbe_set_blackred(parent, gparent);
     210           0 :                         rbe_rotate_left(t, rbt, gparent);
     211             :                 }
     212             :         }
     213             : 
     214         240 :         RBE_COLOR(RBH_ROOT(rbt)) = RB_BLACK;
     215           0 : }
     216             : 
     217             : static inline void
     218           0 : rbe_remove_color(const struct rb_type *t, struct rb_tree *rbt,
     219             :     struct rb_entry *parent, struct rb_entry *rbe)
     220             : {
     221             :         struct rb_entry *tmp;
     222             : 
     223          60 :         while ((rbe == NULL || RBE_COLOR(rbe) == RB_BLACK) &&
     224           0 :             rbe != RBH_ROOT(rbt)) {
     225           0 :                 if (RBE_LEFT(parent) == rbe) {
     226           0 :                         tmp = RBE_RIGHT(parent);
     227           0 :                         if (RBE_COLOR(tmp) == RB_RED) {
     228           0 :                                 rbe_set_blackred(tmp, parent);
     229           0 :                                 rbe_rotate_left(t, rbt, parent);
     230           0 :                                 tmp = RBE_RIGHT(parent);
     231           0 :                         }
     232           0 :                         if ((RBE_LEFT(tmp) == NULL ||
     233           0 :                              RBE_COLOR(RBE_LEFT(tmp)) == RB_BLACK) &&
     234           0 :                             (RBE_RIGHT(tmp) == NULL ||
     235           0 :                              RBE_COLOR(RBE_RIGHT(tmp)) == RB_BLACK)) {
     236           0 :                                 RBE_COLOR(tmp) = RB_RED;
     237             :                                 rbe = parent;
     238           0 :                                 parent = RBE_PARENT(rbe);
     239             :                         } else {
     240           0 :                                 if (RBE_RIGHT(tmp) == NULL ||
     241           0 :                                     RBE_COLOR(RBE_RIGHT(tmp)) == RB_BLACK) {
     242             :                                         struct rb_entry *oleft;
     243             : 
     244           0 :                                         oleft = RBE_LEFT(tmp);
     245           0 :                                         if (oleft != NULL)
     246           0 :                                                 RBE_COLOR(oleft) = RB_BLACK;
     247             : 
     248           0 :                                         RBE_COLOR(tmp) = RB_RED;
     249           0 :                                         rbe_rotate_right(t, rbt, tmp);
     250           0 :                                         tmp = RBE_RIGHT(parent);
     251           0 :                                 }
     252             : 
     253           0 :                                 RBE_COLOR(tmp) = RBE_COLOR(parent);
     254           0 :                                 RBE_COLOR(parent) = RB_BLACK;
     255           0 :                                 if (RBE_RIGHT(tmp))
     256           0 :                                         RBE_COLOR(RBE_RIGHT(tmp)) = RB_BLACK;
     257             : 
     258           0 :                                 rbe_rotate_left(t, rbt, parent);
     259           0 :                                 rbe = RBH_ROOT(rbt);
     260           0 :                                 break;
     261             :                         }
     262           0 :                 } else {
     263             :                         tmp = RBE_LEFT(parent);
     264           0 :                         if (RBE_COLOR(tmp) == RB_RED) {
     265           0 :                                 rbe_set_blackred(tmp, parent);
     266           0 :                                 rbe_rotate_right(t, rbt, parent);
     267           0 :                                 tmp = RBE_LEFT(parent);
     268           0 :                         }
     269             : 
     270           0 :                         if ((RBE_LEFT(tmp) == NULL ||
     271           0 :                              RBE_COLOR(RBE_LEFT(tmp)) == RB_BLACK) &&
     272           0 :                             (RBE_RIGHT(tmp) == NULL ||
     273           0 :                              RBE_COLOR(RBE_RIGHT(tmp)) == RB_BLACK)) {
     274           0 :                                 RBE_COLOR(tmp) = RB_RED;
     275             :                                 rbe = parent;
     276           0 :                                 parent = RBE_PARENT(rbe);
     277             :                         } else {
     278           0 :                                 if (RBE_LEFT(tmp) == NULL ||
     279           0 :                                     RBE_COLOR(RBE_LEFT(tmp)) == RB_BLACK) {
     280             :                                         struct rb_entry *oright;
     281             : 
     282           0 :                                         oright = RBE_RIGHT(tmp);
     283           0 :                                         if (oright != NULL)
     284           0 :                                                 RBE_COLOR(oright) = RB_BLACK;
     285             : 
     286           0 :                                         RBE_COLOR(tmp) = RB_RED;
     287           0 :                                         rbe_rotate_left(t, rbt, tmp);
     288           0 :                                         tmp = RBE_LEFT(parent);
     289           0 :                                 }
     290             : 
     291           0 :                                 RBE_COLOR(tmp) = RBE_COLOR(parent);
     292           0 :                                 RBE_COLOR(parent) = RB_BLACK;
     293           0 :                                 if (RBE_LEFT(tmp) != NULL)
     294           0 :                                         RBE_COLOR(RBE_LEFT(tmp)) = RB_BLACK;
     295             : 
     296           0 :                                 rbe_rotate_right(t, rbt, parent);
     297           0 :                                 rbe = RBH_ROOT(rbt);
     298           0 :                                 break;
     299             :                         }
     300             :                 }
     301             :         }
     302             : 
     303           0 :         if (rbe != NULL)
     304           0 :                 RBE_COLOR(rbe) = RB_BLACK;
     305           0 : }
     306             : 
     307             : static inline struct rb_entry *
     308           0 : rbe_remove(const struct rb_type *t, struct rb_tree *rbt, struct rb_entry *rbe)
     309             : {
     310          60 :         struct rb_entry *child, *parent, *old = rbe;
     311             :         unsigned int color;
     312             : 
     313           0 :         if (RBE_LEFT(rbe) == NULL)
     314           0 :                 child = RBE_RIGHT(rbe);
     315           0 :         else if (RBE_RIGHT(rbe) == NULL)
     316             :                 child = RBE_LEFT(rbe);
     317             :         else {
     318             :                 struct rb_entry *tmp;
     319             : 
     320             :                 rbe = RBE_RIGHT(rbe);
     321           0 :                 while ((tmp = RBE_LEFT(rbe)) != NULL)
     322             :                         rbe = tmp;
     323             : 
     324           0 :                 child = RBE_RIGHT(rbe);
     325           0 :                 parent = RBE_PARENT(rbe);
     326           0 :                 color = RBE_COLOR(rbe);
     327           0 :                 if (child != NULL)
     328           0 :                         RBE_PARENT(child) = parent;
     329           0 :                 if (parent != NULL) {
     330           0 :                         if (RBE_LEFT(parent) == rbe)
     331           0 :                                 RBE_LEFT(parent) = child;
     332             :                         else
     333           0 :                                 RBE_RIGHT(parent) = child;
     334             : 
     335           0 :                         rbe_if_augment(t, parent);
     336           0 :                 } else
     337           0 :                         RBH_ROOT(rbt) = child;
     338           0 :                 if (RBE_PARENT(rbe) == old)
     339           0 :                         parent = rbe;
     340           0 :                 *rbe = *old;
     341             : 
     342           0 :                 tmp = RBE_PARENT(old);
     343           0 :                 if (tmp != NULL) {
     344           0 :                         if (RBE_LEFT(tmp) == old)
     345           0 :                                 RBE_LEFT(tmp) = rbe;
     346             :                         else
     347           0 :                                 RBE_RIGHT(tmp) = rbe;
     348             : 
     349           0 :                         rbe_if_augment(t, parent);
     350           0 :                 } else
     351           0 :                         RBH_ROOT(rbt) = rbe;
     352             : 
     353           0 :                 RBE_PARENT(RBE_LEFT(old)) = rbe;
     354           0 :                 if (RBE_RIGHT(old))
     355           0 :                         RBE_PARENT(RBE_RIGHT(old)) = rbe;
     356             : 
     357           0 :                 if (t->t_augment != NULL && parent != NULL) {
     358             :                         tmp = parent;
     359           0 :                         do {
     360           0 :                                 rbe_augment(t, tmp);
     361           0 :                                 tmp = RBE_PARENT(tmp);
     362           0 :                         } while (tmp != NULL);
     363             :                 }
     364             : 
     365             :                 goto color;
     366             :         }
     367             : 
     368           0 :         parent = RBE_PARENT(rbe);
     369           0 :         color = RBE_COLOR(rbe);
     370             : 
     371         180 :         if (child != NULL)
     372           0 :                 RBE_PARENT(child) = parent;
     373           0 :         if (parent != NULL) {
     374           0 :                 if (RBE_LEFT(parent) == rbe)
     375           0 :                         RBE_LEFT(parent) = child;
     376             :                 else
     377           0 :                         RBE_RIGHT(parent) = child;
     378             : 
     379           0 :                 rbe_if_augment(t, parent);
     380           0 :         } else
     381           0 :                 RBH_ROOT(rbt) = child;
     382             : color:
     383         360 :         if (color == RB_BLACK)
     384           0 :                 rbe_remove_color(t, rbt, parent, child);
     385             : 
     386           0 :         return (old);
     387           0 : }
     388             : 
     389             : void *
     390           0 : _rb_remove(const struct rb_type *t, struct rb_tree *rbt, void *elm)
     391             : {
     392           0 :         struct rb_entry *rbe = rb_n2e(t, elm);
     393             :         struct rb_entry *old;
     394             : 
     395           0 :         old = rbe_remove(t, rbt, rbe);
     396             : 
     397           0 :         return (old == NULL ? NULL : rb_e2n(t, old));
     398             : }
     399             : 
     400             : void *
     401           0 : _rb_insert(const struct rb_type *t, struct rb_tree *rbt, void *elm)
     402             : {
     403           0 :         struct rb_entry *rbe = rb_n2e(t, elm);
     404             :         struct rb_entry *tmp;
     405             :         struct rb_entry *parent = NULL;
     406             :         void *node;
     407             :         int comp = 0;
     408             : 
     409           0 :         tmp = RBH_ROOT(rbt);
     410         240 :         while (tmp != NULL) {
     411             :                 parent = tmp;
     412             : 
     413           0 :                 node = rb_e2n(t, tmp);
     414           0 :                 comp = (*t->t_compare)(elm, node);
     415           0 :                 if (comp < 0)
     416         625 :                         tmp = RBE_LEFT(tmp);
     417           0 :                 else if (comp > 0)
     418         705 :                         tmp = RBE_RIGHT(tmp);
     419             :                 else
     420           0 :                         return (node);
     421             :         }
     422             : 
     423           0 :         rbe_set(rbe, parent);
     424             : 
     425           0 :         if (parent != NULL) {
     426           0 :                 if (comp < 0)
     427           0 :                         RBE_LEFT(parent) = rbe;
     428             :                 else
     429           0 :                         RBE_RIGHT(parent) = rbe;
     430             : 
     431           0 :                 rbe_if_augment(t, parent);
     432           0 :         } else
     433           0 :                 RBH_ROOT(rbt) = rbe;
     434             : 
     435           0 :         rbe_insert_color(t, rbt, rbe);
     436             : 
     437           0 :         return (NULL);
     438           0 : }
     439             : 
     440             : /* Finds the node with the same key as elm */
     441             : void *
     442           0 : _rb_find(const struct rb_type *t, struct rb_tree *rbt, const void *key)
     443             : {
     444           0 :         struct rb_entry *tmp = RBH_ROOT(rbt);
     445             :         void *node;
     446             :         int comp;
     447             : 
     448           0 :         while (tmp != NULL) {
     449           0 :                 node = rb_e2n(t, tmp);
     450           0 :                 comp = (*t->t_compare)(key, node);
     451           0 :                 if (comp < 0)
     452           0 :                         tmp = RBE_LEFT(tmp);
     453           0 :                 else if (comp > 0)
     454           0 :                         tmp = RBE_RIGHT(tmp);
     455             :                 else
     456           0 :                         return (node);
     457             :         }
     458             : 
     459           0 :         return (NULL);
     460           0 : }
     461             : 
     462             : /* Finds the first node greater than or equal to the search key */
     463             : void *
     464           0 : _rb_nfind(const struct rb_type *t, struct rb_tree *rbt, const void *key)
     465             : {
     466           0 :         struct rb_entry *tmp = RBH_ROOT(rbt);
     467             :         void *node;
     468             :         void *res = NULL;
     469             :         int comp;
     470             : 
     471           0 :         while (tmp != NULL) {
     472           0 :                 node = rb_e2n(t, tmp);
     473           0 :                 comp = (*t->t_compare)(key, node);
     474           0 :                 if (comp < 0) {
     475             :                         res = node;
     476           0 :                         tmp = RBE_LEFT(tmp);
     477           0 :                 } else if (comp > 0)
     478           0 :                         tmp = RBE_RIGHT(tmp);
     479             :                 else
     480           0 :                         return (node);
     481             :         }
     482             : 
     483           0 :         return (res);
     484           0 : }
     485             : 
     486             : void *
     487           0 : _rb_next(const struct rb_type *t, void *elm)
     488             : {
     489           0 :         struct rb_entry *rbe = rb_n2e(t, elm);
     490             : 
     491           0 :         if (RBE_RIGHT(rbe) != NULL) {
     492             :                 rbe = RBE_RIGHT(rbe);
     493          22 :                 while (RBE_LEFT(rbe) != NULL)
     494             :                         rbe = RBE_LEFT(rbe);
     495             :         } else {
     496          98 :                 if (RBE_PARENT(rbe) &&
     497           0 :                     (rbe == RBE_LEFT(RBE_PARENT(rbe))))
     498           0 :                         rbe = RBE_PARENT(rbe);
     499             :                 else {
     500           0 :                         while (RBE_PARENT(rbe) &&
     501           0 :                             (rbe == RBE_RIGHT(RBE_PARENT(rbe))))
     502             :                                 rbe = RBE_PARENT(rbe);
     503             :                         rbe = RBE_PARENT(rbe);
     504             :                 }
     505             :         }
     506             : 
     507           0 :         return (rbe == NULL ? NULL : rb_e2n(t, rbe));
     508             : }
     509             : 
     510             : void *
     511           0 : _rb_prev(const struct rb_type *t, void *elm)
     512             : {
     513           0 :         struct rb_entry *rbe = rb_n2e(t, elm);
     514             : 
     515           0 :         if (RBE_LEFT(rbe)) {
     516             :                 rbe = RBE_LEFT(rbe);
     517           0 :                 while (RBE_RIGHT(rbe))
     518             :                         rbe = RBE_RIGHT(rbe);
     519             :         } else {
     520           0 :                 if (RBE_PARENT(rbe) &&
     521           0 :                     (rbe == RBE_RIGHT(RBE_PARENT(rbe))))
     522           0 :                         rbe = RBE_PARENT(rbe);
     523             :                 else {
     524          60 :                         while (RBE_PARENT(rbe) &&
     525           0 :                             (rbe == RBE_LEFT(RBE_PARENT(rbe))))
     526             :                                 rbe = RBE_PARENT(rbe);
     527             :                         rbe = RBE_PARENT(rbe);
     528             :                 }
     529             :         }
     530             : 
     531           0 :         return (rbe == NULL ? NULL : rb_e2n(t, rbe));
     532             : }
     533             : 
     534             : void *
     535           0 : _rb_root(const struct rb_type *t, struct rb_tree *rbt)
     536             : {
     537         371 :         struct rb_entry *rbe = RBH_ROOT(rbt);
     538             : 
     539           0 :         return (rbe == NULL ? rbe : rb_e2n(t, rbe));
     540             : }
     541             : 
     542             : void *
     543           0 : _rb_min(const struct rb_type *t, struct rb_tree *rbt)
     544             : {
     545           0 :         struct rb_entry *rbe = RBH_ROOT(rbt);
     546             :         struct rb_entry *parent = NULL;
     547             : 
     548           0 :         while (rbe != NULL) {
     549             :                 parent = rbe;
     550           0 :                 rbe = RBE_LEFT(rbe);
     551             :         }
     552             : 
     553           0 :         return (parent == NULL ? NULL : rb_e2n(t, parent));
     554             : }
     555             : 
     556             : void *
     557           0 : _rb_max(const struct rb_type *t, struct rb_tree *rbt)
     558             : {
     559           0 :         struct rb_entry *rbe = RBH_ROOT(rbt);
     560             :         struct rb_entry *parent = NULL;
     561             : 
     562           0 :         while (rbe != NULL) {
     563             :                 parent = rbe;
     564           0 :                 rbe = RBE_RIGHT(rbe);
     565             :         }
     566             : 
     567           0 :         return (parent == NULL ? NULL : rb_e2n(t, parent));
     568             : }
     569             : 
     570             : void *
     571           0 : _rb_left(const struct rb_type *t, void *node)
     572             : {
     573           0 :         struct rb_entry *rbe = rb_n2e(t, node);
     574           0 :         rbe = RBE_LEFT(rbe);
     575           0 :         return (rbe == NULL ? NULL : rb_e2n(t, rbe));
     576             : }
     577             : 
     578             : void *
     579           0 : _rb_right(const struct rb_type *t, void *node)
     580             : {
     581           0 :         struct rb_entry *rbe = rb_n2e(t, node);
     582           0 :         rbe = RBE_RIGHT(rbe);
     583           0 :         return (rbe == NULL ? NULL : rb_e2n(t, rbe));
     584             : }
     585             : 
     586             : void *
     587           0 : _rb_parent(const struct rb_type *t, void *node)
     588             : {
     589           0 :         struct rb_entry *rbe = rb_n2e(t, node);
     590           0 :         rbe = RBE_PARENT(rbe);
     591           0 :         return (rbe == NULL ? NULL : rb_e2n(t, rbe));
     592             : }
     593             : 
     594             : void
     595           0 : _rb_set_left(const struct rb_type *t, void *node, void *left)
     596             : {
     597           0 :         struct rb_entry *rbe = rb_n2e(t, node);
     598           0 :         struct rb_entry *rbl = (left == NULL) ? NULL : rb_n2e(t, left);
     599             : 
     600           0 :         RBE_LEFT(rbe) = rbl;
     601           0 : }
     602             : 
     603             : void
     604           0 : _rb_set_right(const struct rb_type *t, void *node, void *right)
     605             : {
     606           0 :         struct rb_entry *rbe = rb_n2e(t, node);
     607           0 :         struct rb_entry *rbr = (right == NULL) ? NULL : rb_n2e(t, right);
     608             : 
     609           0 :         RBE_RIGHT(rbe) = rbr;
     610           0 : }
     611             : 
     612             : void
     613           0 : _rb_set_parent(const struct rb_type *t, void *node, void *parent)
     614             : {
     615           0 :         struct rb_entry *rbe = rb_n2e(t, node);
     616           0 :         struct rb_entry *rbp = (parent == NULL) ? NULL : rb_n2e(t, parent);
     617             : 
     618           0 :         RBE_PARENT(rbe) = rbp;
     619           0 : }
     620             : 
     621             : void
     622           0 : _rb_poison(const struct rb_type *t, void *node, unsigned long poison)
     623             : {
     624           0 :         struct rb_entry *rbe = rb_n2e(t, node);
     625             : 
     626           0 :         RBE_PARENT(rbe) = RBE_LEFT(rbe) = RBE_RIGHT(rbe) =
     627           0 :             (struct rb_entry *)poison;
     628           0 : }
     629             : 
     630             : int
     631           0 : _rb_check(const struct rb_type *t, void *node, unsigned long poison)
     632             : {
     633           0 :         struct rb_entry *rbe = rb_n2e(t, node);
     634             : 
     635           0 :         return ((unsigned long)RBE_PARENT(rbe) == poison &&
     636           0 :             (unsigned long)RBE_LEFT(rbe) == poison &&
     637          60 :             (unsigned long)RBE_RIGHT(rbe) == poison);
     638             : }

Generated by: LCOV version 1.13