Open SCAP Library
Loading...
Searching...
No Matches
rbt_common.h
1/*
2 * Copyright 2010 Red Hat Inc., Durham, North Carolina.
3 * All Rights Reserved.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 *
19 * Authors:
20 * "Daniel Kopecek" <dkopecek@redhat.com>
21 */
22#ifndef RBT_COMMON_H
23#define RBT_COMMON_H
24
25#ifdef HAVE_CONFIG_H
26#include <config.h>
27#endif
28
29#include <stdint.h>
30#include <stdbool.h>
31
32#if defined(RBT_IMPLICIT_LOCKING)
33# include <pthread.h>
34#endif
35
36#ifndef HAVE_POSIX_MEMALIGN
37# ifdef HAVE_MEMALIGN
38int posix_memalign(void **memptr, size_t alignment, size_t size);
39# endif /* HAVE_MEMALIGN */
40#endif /* HAVE_POSIX_MEMALIGN */
41
42typedef enum {
43 RBT_GENKEY,
44 RBT_STRKEY,
45 RBT_I32KEY,
46 RBT_I64KEY
47} rbt_type_t;
48
49typedef enum {
50 RBT_WALK_PREORDER = 0x01,
51 RBT_WALK_INORDER = 0x02,
52 RBT_WALK_POSTORDER = 0x03,
53 RBT_WALK_LEVELORDER = 0x04,
54 RBT_WALK_RAWNODE = 0x10
55} rbt_walk_t;
56
57#define RBT_WALK_TYPEMASK 0x0f
58#define RBT_WALK_FLAGMASK 0xf0
59
64struct rbt_node {
65 struct rbt_node *_chld[2];
66 uint8_t _node[];
67};
68
69#define RBT_NODE_CB 0
70#define RBT_NODE_CR 1
71#define RBT_NODE_SL 0
72#define RBT_NODE_SR 1
73
74__attribute__((pure)) static inline struct rbt_node *rbt_node_ptr(const struct rbt_node *nodep)
75{
76 register uintptr_t nodep_uint = (uintptr_t)(nodep);
77 nodep_uint &= UINTPTR_MAX << 1;
78 return (struct rbt_node *)(nodep_uint);
79}
80
81#define rbt_node_setptr(dst,src) (dst) = (struct rbt_node *)((uintptr_t)rbt_node_ptr(src)|((uintptr_t)(dst)&1))
82
83#define rbt_node_setcolor(np, cb) \
84 do { \
85 register struct rbt_node *__n = rbt_node_ptr(np); \
86 register uint8_t __c = (cb) & 1; \
87 \
88 if (__n != NULL) { \
89 if (__c) __n->_chld[0] = (struct rbt_node *)((uintptr_t)(__n->_chld[0]) | 1); \
90 else __n->_chld[0] = rbt_node_ptr(__n->_chld[0]); \
91 } \
92 } while(0)
93#define rbt_node_getcolor_raw(cp) ((uintptr_t)(cp) & 1)
94#define rbt_node_getcolor(np) (rbt_node_ptr(np) == NULL ? RBT_NODE_CB : rbt_node_getcolor_raw(rbt_node_ptr(np)->_chld[0]))
95#define rbt_node_cpycolor(dn, sn) rbt_node_setcolor((dn), rbt_node_getcolor(sn))
96
97#define rbt_hpush4(__a, __p) \
98 do { \
99 __a[3] = __a[2]; \
100 __a[2] = __a[1]; \
101 __a[1] = __a[0]; \
102 __a[0] = __p; \
103 } while(0)
104
105#define rbt_hpush3(__a, __p) \
106 do { \
107 __a[2] = __a[1]; \
108 __a[1] = __a[0]; \
109 __a[0] = __p; \
110 } while(0)
111
112#define rbt_redfix(__h, __d, v) \
113 do { \
114 if (((__d) & 3) < 2) { \
115 if (((__d) & 3) == 0) { \
116 rbt_node_setptr(v, rbt_node_rotate_R(__h[2])); \
117 } else { \
118 rbt_node_setptr(v, rbt_node_rotate_RL(__h[2])); \
119 } \
120 } else { \
121 if (((__d) & 3) == 2) { \
122 rbt_node_setptr(v, rbt_node_rotate_LR(__h[2])); \
123 } else { \
124 rbt_node_setptr(v, rbt_node_rotate_L(__h[2])); \
125 } \
126 } \
127 } while(0)
128
129struct rbt {
130 struct rbt_node *root;
131 size_t size;
132 rbt_type_t type;
133#if defined(RBT_IMPLICIT_LOCKING)
134 pthread_rwlock_t lock;
135#endif
136};
137
138typedef struct rbt rbt_t;
139
144rbt_t *rbt_new(rbt_type_t type);
145
152void rbt_free(rbt_t *rbt, void (*callback)(void *));
153void rbt_free2(rbt_t *rbt, void (*callback)(void *, void *), void *user);
154
159int rbt_rlock(rbt_t *rbt);
160
165void rbt_runlock(rbt_t *rbt);
166
171int rbt_wlock(rbt_t *rbt);
172
177void rbt_wunlock(rbt_t *rbt);
178
179struct rbt_node *rbt_node_rotate_L(struct rbt_node *);
180struct rbt_node *rbt_node_rotate_R(struct rbt_node *);
181struct rbt_node *rbt_node_rotate_LR(struct rbt_node *);
182struct rbt_node *rbt_node_rotate_RL(struct rbt_node *);
183
184size_t rbt_size(rbt_t *rbt);
185
186#define rbt_walk_push(n) stack[depth++] = (n)
187#define rbt_walk_pop() stack[--depth]
188#define rbt_walk_top() stack[depth-1]
189
190int rbt_walk_preorder(rbt_t *rbt, int (*callback)(void *), rbt_walk_t flags);
191int rbt_walk_inorder(rbt_t *rbt, int (*callback)(void *), rbt_walk_t flags);
192int rbt_walk_inorder2(rbt_t *rbt, int (*callback)(void *, void *), void *user, rbt_walk_t flags);
193int rbt_walk_postorder(rbt_t *rbt, int (*callback)(void *), rbt_walk_t flags);
194
195#endif /* RBT_COMMON_H */
Generic node structure Lowest bit of _chld[0] holds the color bit.
Definition rbt_common.h:64
Definition rbt_common.h:129