Open SCAP Library
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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
38 int posix_memalign(void **memptr, size_t alignment, size_t size);
39 # endif /* HAVE_MEMALIGN */
40 #endif /* HAVE_POSIX_MEMALIGN */
41 
42 typedef enum {
43  RBT_GENKEY,
44  RBT_STRKEY,
45  RBT_I32KEY,
46  RBT_I64KEY
47 } rbt_type_t;
48 
49 typedef 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 
64 struct 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 
129 struct 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 
138 typedef struct rbt rbt_t;
139 
144 rbt_t *rbt_new(rbt_type_t type);
145 
152 void rbt_free(rbt_t *rbt, void (*callback)(void *));
153 void rbt_free2(rbt_t *rbt, void (*callback)(void *, void *), void *user);
154 
159 int rbt_rlock(rbt_t *rbt);
160 
165 void rbt_runlock(rbt_t *rbt);
166 
171 int rbt_wlock(rbt_t *rbt);
172 
177 void rbt_wunlock(rbt_t *rbt);
178 
179 struct rbt_node *rbt_node_rotate_L(struct rbt_node *);
180 struct rbt_node *rbt_node_rotate_R(struct rbt_node *);
181 struct rbt_node *rbt_node_rotate_LR(struct rbt_node *);
182 struct rbt_node *rbt_node_rotate_RL(struct rbt_node *);
183 
184 size_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 
190 int rbt_walk_preorder(rbt_t *rbt, int (*callback)(void *), rbt_walk_t flags);
191 int rbt_walk_inorder(rbt_t *rbt, int (*callback)(void *), rbt_walk_t flags);
192 int rbt_walk_inorder2(rbt_t *rbt, int (*callback)(void *, void *), void *user, rbt_walk_t flags);
193 int rbt_walk_postorder(rbt_t *rbt, int (*callback)(void *), rbt_walk_t flags);
194 
195 #endif /* RBT_COMMON_H */
Definition: _sexp-value.h:42
Definition: rbt_common.h:129
Generic node structure Lowest bit of _chld[0] holds the color bit.
Definition: rbt_common.h:64