The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netpfil/ipfilter/netinet/ipf_rb.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (C) 2012 by Darren Reed.
    3  *
    4  * See the IPFILTER.LICENCE file for details on licencing.
    5  *
    6  */
    7 typedef enum rbcolour_e {
    8         C_BLACK = 0,
    9         C_RED = 1
   10 } rbcolour_t;
   11 
   12 #define RBI_LINK(_n, _t)                                                        \
   13         struct _n##_rb_link {                                           \
   14                 struct _t       *left;                                  \
   15                 struct _t       *right;                                 \
   16                 struct _t       *parent;                                \
   17                 rbcolour_t      colour;                                 \
   18         }
   19 
   20 #define RBI_HEAD(_n, _t)                                                \
   21 struct _n##_rb_head {                                                   \
   22         struct _t       top;                                            \
   23         int             count;                                          \
   24         int             (* compare)(struct _t *, struct _t *);          \
   25 }
   26 
   27 #define RBI_CODE(_n, _t, _f, _cmp)                                      \
   28                                                                         \
   29 typedef void    (*_n##_rb_walker_t)(_t *, void *);                      \
   30                                                                         \
   31 _t *    _n##_rb_delete(struct _n##_rb_head *, _t *);                    \
   32 void    _n##_rb_init(struct _n##_rb_head *);                            \
   33 void    _n##_rb_insert(struct _n##_rb_head *, _t *);                    \
   34 _t *    _n##_rb_search(struct _n##_rb_head *, void *);                  \
   35 void    _n##_rb_walktree(struct _n##_rb_head *, _n##_rb_walker_t, void *);\
   36                                                                         \
   37 static void                                                             \
   38 rotate_left(struct _n##_rb_head *head, _t *node)                        \
   39 {                                                                       \
   40         _t *parent, *tmp1, *tmp2;                                       \
   41                                                                         \
   42         parent = node->_f.parent;                                       \
   43         tmp1 = node->_f.right;                                          \
   44         tmp2 = tmp1->_f.left;                                           \
   45         node->_f.right = tmp2;                                          \
   46         if (tmp2 != & _n##_rb_zero)                                     \
   47                 tmp2->_f.parent = node;                                 \
   48         if (parent == & _n##_rb_zero)                                   \
   49                 head->top._f.right = tmp1;                              \
   50         else if (parent->_f.right == node)                              \
   51                 parent->_f.right = tmp1;                                \
   52         else                                                            \
   53                 parent->_f.left = tmp1;                                 \
   54         tmp1->_f.left = node;                                           \
   55         tmp1->_f.parent = parent;                                       \
   56         node->_f.parent = tmp1;                                         \
   57 }                                                                       \
   58                                                                         \
   59 static void                                                             \
   60 rotate_right(struct _n##_rb_head *head, _t *node)                       \
   61 {                                                                       \
   62         _t *parent, *tmp1, *tmp2;                                       \
   63                                                                         \
   64         parent = node->_f.parent;                                       \
   65         tmp1 = node->_f.left;                                           \
   66         tmp2 = tmp1->_f.right;                                          \
   67         node->_f.left = tmp2;                                           \
   68         if (tmp2 != &_n##_rb_zero)                                      \
   69                 tmp2->_f.parent = node;                                 \
   70         if (parent == &_n##_rb_zero)                                    \
   71                 head->top._f.right = tmp1;                              \
   72         else if (parent->_f.right == node)                              \
   73                 parent->_f.right = tmp1;                                \
   74         else                                                            \
   75                 parent->_f.left = tmp1;                                 \
   76         tmp1->_f.right = node;                                          \
   77         tmp1->_f.parent = parent;                                       \
   78         node->_f.parent = tmp1;                                         \
   79 }                                                                       \
   80                                                                         \
   81 void                                                                    \
   82 _n##_rb_insert(struct _n##_rb_head *head, _t *node)                     \
   83 {                                                                       \
   84         _t *n, *parent, **p, *tmp1, *gparent;                           \
   85                                                                         \
   86         parent = &head->top;                                            \
   87         node->_f.left = &_n##_rb_zero;                                  \
   88         node->_f.right = &_n##_rb_zero;                                 \
   89         p = &head->top._f.right;                                        \
   90         while ((n = *p) != &_n##_rb_zero) {                             \
   91                 if (_cmp(node, n) < 0)                                  \
   92                         p = &n->_f.left;                                \
   93                 else                                                    \
   94                         p = &n->_f.right;                               \
   95                 parent = n;                                             \
   96         }                                                               \
   97         *p = node;                                                      \
   98         node->_f.colour = C_RED;                                        \
   99         node->_f.parent = parent;                                       \
  100                                                                         \
  101         while ((node != &_n##_rb_zero) && (parent->_f.colour == C_RED)){\
  102                 gparent = parent->_f.parent;                            \
  103                 if (parent == gparent->_f.left) {                       \
  104                         tmp1 = gparent->_f.right;                       \
  105                         if (tmp1->_f.colour == C_RED) {                 \
  106                                 parent->_f.colour = C_BLACK;            \
  107                                 tmp1->_f.colour = C_BLACK;              \
  108                                 gparent->_f.colour = C_RED;             \
  109                                 node = gparent;                         \
  110                         } else {                                        \
  111                                 if (node == parent->_f.right) {         \
  112                                         node = parent;                  \
  113                                         rotate_left(head, node);        \
  114                                         parent = node->_f.parent;       \
  115                                 }                                       \
  116                                 parent->_f.colour = C_BLACK;            \
  117                                 gparent->_f.colour = C_RED;             \
  118                                 rotate_right(head, gparent);            \
  119                         }                                               \
  120                 } else {                                                \
  121                         tmp1 = gparent->_f.left;                        \
  122                         if (tmp1->_f.colour == C_RED) {                 \
  123                                 parent->_f.colour = C_BLACK;            \
  124                                 tmp1->_f.colour = C_BLACK;              \
  125                                 gparent->_f.colour = C_RED;             \
  126                                 node = gparent;                         \
  127                         } else {                                        \
  128                                 if (node == parent->_f.left) {          \
  129                                         node = parent;                  \
  130                                         rotate_right(head, node);       \
  131                                         parent = node->_f.parent;       \
  132                                 }                                       \
  133                                 parent->_f.colour = C_BLACK;            \
  134                                 gparent->_f.colour = C_RED;             \
  135                                 rotate_left(head, parent->_f.parent);   \
  136                         }                                               \
  137                 }                                                       \
  138                 parent = node->_f.parent;                               \
  139         }                                                               \
  140         head->top._f.right->_f.colour = C_BLACK;                        \
  141         head->count++;                                          \
  142 }                                                                       \
  143                                                                         \
  144 static void                                                             \
  145 deleteblack(struct _n##_rb_head *head, _t *parent, _t *node)            \
  146 {                                                                       \
  147         _t *tmp;                                                        \
  148                                                                         \
  149         while ((node == &_n##_rb_zero || node->_f.colour == C_BLACK) && \
  150                node != &head->top) {                                    \
  151                 if (parent->_f.left == node) {                          \
  152                         tmp = parent->_f.right;                         \
  153                         if (tmp->_f.colour == C_RED) {                  \
  154                                 tmp->_f.colour = C_BLACK;               \
  155                                 parent->_f.colour = C_RED;              \
  156                                 rotate_left(head, parent);              \
  157                                 tmp = parent->_f.right;                 \
  158                         }                                               \
  159                         if ((tmp->_f.left == &_n##_rb_zero ||           \
  160                              tmp->_f.left->_f.colour == C_BLACK) &&     \
  161                             (tmp->_f.right == &_n##_rb_zero ||          \
  162                              tmp->_f.right->_f.colour == C_BLACK)) {    \
  163                                 tmp->_f.colour = C_RED;                 \
  164                                 node = parent;                          \
  165                                 parent = node->_f.parent;               \
  166                         } else {                                        \
  167                                 if (tmp->_f.right == &_n##_rb_zero ||   \
  168                                     tmp->_f.right->_f.colour == C_BLACK) {\
  169                                         _t *tmp2 = tmp->_f.left;        \
  170                                                                         \
  171                                         if (tmp2 != &_n##_rb_zero)      \
  172                                                 tmp2->_f.colour = C_BLACK;\
  173                                         tmp->_f.colour = C_RED;         \
  174                                         rotate_right(head, tmp);        \
  175                                         tmp = parent->_f.right;         \
  176                                 }                                       \
  177                                 tmp->_f.colour = parent->_f.colour;     \
  178                                 parent->_f.colour = C_BLACK;            \
  179                                 if (tmp->_f.right != &_n##_rb_zero)     \
  180                                         tmp->_f.right->_f.colour = C_BLACK;\
  181                                 rotate_left(head, parent);              \
  182                                 node = head->top._f.right;              \
  183                         }                                               \
  184                 } else {                                                \
  185                         tmp = parent->_f.left;                          \
  186                         if (tmp->_f.colour == C_RED) {                  \
  187                                 tmp->_f.colour = C_BLACK;               \
  188                                 parent->_f.colour = C_RED;              \
  189                                 rotate_right(head, parent);             \
  190                                 tmp = parent->_f.left;                  \
  191                         }                                               \
  192                         if ((tmp->_f.left == &_n##_rb_zero ||           \
  193                              tmp->_f.left->_f.colour == C_BLACK) &&     \
  194                             (tmp->_f.right == &_n##_rb_zero ||          \
  195                              tmp->_f.right->_f.colour == C_BLACK)) {    \
  196                                 tmp->_f.colour = C_RED;                 \
  197                                 node = parent;                          \
  198                                 parent = node->_f.parent;               \
  199                         } else {                                        \
  200                                 if (tmp->_f.left == &_n##_rb_zero ||    \
  201                                     tmp->_f.left->_f.colour == C_BLACK) {\
  202                                         _t *tmp2 = tmp->_f.right;       \
  203                                                                         \
  204                                         if (tmp2 != &_n##_rb_zero)      \
  205                                                 tmp2->_f.colour = C_BLACK;\
  206                                         tmp->_f.colour = C_RED;         \
  207                                         rotate_left(head, tmp);         \
  208                                         tmp = parent->_f.left;          \
  209                                 }                                       \
  210                                 tmp->_f.colour = parent->_f.colour;     \
  211                                 parent->_f.colour = C_BLACK;            \
  212                                 if (tmp->_f.left != &_n##_rb_zero)      \
  213                                         tmp->_f.left->_f.colour = C_BLACK;\
  214                                 rotate_right(head, parent);             \
  215                                 node = head->top._f.right;              \
  216                                 break;                                  \
  217                         }                                               \
  218                 }                                                       \
  219         }                                                               \
  220         if (node != &_n##_rb_zero)                                      \
  221                 node->_f.colour = C_BLACK;                              \
  222 }                                                                       \
  223                                                                         \
  224 _t *                                                                    \
  225 _n##_rb_delete(struct _n##_rb_head *head, _t *node)                     \
  226 {                                                                       \
  227         _t *child, *parent, *old = node, *left;                         \
  228         rbcolour_t color;                                               \
  229                                                                         \
  230         if (node->_f.left == &_n##_rb_zero) {                           \
  231                 child = node->_f.right;                                 \
  232         } else if (node->_f.right == &_n##_rb_zero) {                   \
  233                 child = node->_f.left;                                  \
  234         } else {                                                        \
  235                 node = node->_f.right;                                  \
  236                 while ((left = node->_f.left) != &_n##_rb_zero)         \
  237                         node = left;                                    \
  238                 child = node->_f.right;                                 \
  239                 parent = node->_f.parent;                               \
  240                 color = node->_f.colour;                                \
  241                 if (child != &_n##_rb_zero)                             \
  242                         child->_f.parent = parent;                      \
  243                 if (parent != &_n##_rb_zero) {                          \
  244                         if (parent->_f.left == node)                    \
  245                                 parent->_f.left = child;                \
  246                         else                                            \
  247                                 parent->_f.right = child;               \
  248                 } else {                                                \
  249                         head->top._f.right = child;                     \
  250                 }                                                       \
  251                 if (node->_f.parent == old)                             \
  252                         parent = node;                                  \
  253                 *node = *old;                                           \
  254                 if (old->_f.parent != &_n##_rb_zero) {                  \
  255                         if (old->_f.parent->_f.left == old)             \
  256                                 old->_f.parent->_f.left = node;         \
  257                         else                                            \
  258                                 old->_f.parent->_f.right = node;        \
  259                 } else {                                                \
  260                         head->top._f.right = child;                     \
  261                 }                                                       \
  262                 old->_f.left->_f.parent = node;                         \
  263                 if (old->_f.right != &_n##_rb_zero)                     \
  264                         old->_f.right->_f.parent = node;                \
  265                 if (parent != &_n##_rb_zero) {                          \
  266                         left = parent;                                  \
  267                 }                                                       \
  268                 goto colour;                                            \
  269         }                                                               \
  270         parent = node->_f.parent;                                       \
  271         color= node->_f.colour;                                         \
  272         if (child != &_n##_rb_zero)                                     \
  273                 child->_f.parent = parent;                              \
  274         if (parent != &_n##_rb_zero) {                                  \
  275                 if (parent->_f.left == node)                            \
  276                         parent->_f.left = child;                        \
  277                 else                                                    \
  278                         parent->_f.right = child;                       \
  279         } else {                                                        \
  280                 head->top._f.right = child;                             \
  281         }                                                               \
  282 colour:                                                                 \
  283         if (color == C_BLACK)                                           \
  284                 deleteblack(head, parent, node);                        \
  285         head->count--;                                                  \
  286         return (old);                                                   \
  287 }                                                                       \
  288                                                                         \
  289 void                                                                    \
  290 _n##_rb_init(struct _n##_rb_head *head)                                 \
  291 {                                                                       \
  292         memset(head, 0, sizeof(*head));                                 \
  293         memset(&_n##_rb_zero, 0, sizeof(_n##_rb_zero));                 \
  294         head->top._f.left = &_n##_rb_zero;                              \
  295         head->top._f.right = &_n##_rb_zero;                             \
  296         head->top._f.parent = &head->top;                               \
  297         _n##_rb_zero._f.left = &_n##_rb_zero;                           \
  298         _n##_rb_zero._f.right = &_n##_rb_zero;                          \
  299         _n##_rb_zero._f.parent = &_n##_rb_zero;                         \
  300 }                                                                       \
  301                                                                         \
  302 void                                                                    \
  303 _n##_rb_walktree(struct _n##_rb_head *head, _n##_rb_walker_t func, void *arg)\
  304 {                                                                       \
  305         _t *prev;                                                       \
  306         _t *next;                                                       \
  307         _t *node = head->top._f.right;                                  \
  308         _t *base;                                                       \
  309                                                                         \
  310         while (node != &_n##_rb_zero)                                   \
  311                 node = node->_f.left;                                   \
  312                                                                         \
  313         for (;;) {                                                      \
  314                 base = node;                                            \
  315                 prev = node;                                            \
  316                 while ((node->_f.parent->_f.right == node) &&           \
  317                        (node != &_n##_rb_zero)) {                       \
  318                         prev = node;                                    \
  319                         node = node->_f.parent;                         \
  320                 }                                                       \
  321                                                                         \
  322                 node = prev;                                            \
  323                 for (node = node->_f.parent->_f.right; node != &_n##_rb_zero;\
  324                      node = node->_f.left)                              \
  325                         prev = node;                                    \
  326                 next = prev;                                            \
  327                                                                         \
  328                 if (node != &_n##_rb_zero)                              \
  329                         func(node, arg);                                \
  330                                                                         \
  331                 node = next;                                            \
  332                 if (node == &_n##_rb_zero)                              \
  333                         break;                                          \
  334         }                                                               \
  335 }                                                                       \
  336                                                                         \
  337 _t *                                                                    \
  338 _n##_rb_search(struct _n##_rb_head *head, void *key)                    \
  339 {                                                                       \
  340         int     match;                                                  \
  341         _t      *node;                                                  \
  342         node = head->top._f.right;                                      \
  343         while (node != &_n##_rb_zero) {                                 \
  344                 match = _cmp(key, node);                                \
  345                 if (match == 0)                                         \
  346                         break;                                          \
  347                 if (match< 0)                                           \
  348                         node = node->_f.left;                           \
  349                 else                                                    \
  350                         node = node->_f.right;                          \
  351         }                                                               \
  352         if (node == &_n##_rb_zero || match != 0)                        \
  353                 return (NULL);                                          \
  354         return (node);                                                  \
  355 }
  356 
  357 #define RBI_DELETE(_n, _h, _v)          _n##_rb_delete(_h, _v)
  358 #define RBI_FIELD(_n)                   struct _n##_rb_link
  359 #define RBI_INIT(_n, _h)                _n##_rb_init(_h)
  360 #define RBI_INSERT(_n, _h, _v)          _n##_rb_insert(_h, _v)
  361 #define RBI_ISEMPTY(_h)                 ((_h)->count == 0)
  362 #define RBI_SEARCH(_n, _h, _k)          _n##_rb_search(_h, _k)
  363 #define RBI_WALK(_n, _h, _w, _a)        _n##_rb_walktree(_h, _w, _a)
  364 #define RBI_ZERO(_n)                    _n##_rb_zero

Cache object: d601282acfedf20c3c490540e057ee2d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.