|
|
1.1 root 1: /*
2: * Copyright (c) 2011-2015 Richard Braun.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: *
14: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16: * 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, BUT
19: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24: *
25: *
26: * Radix tree.
27: *
28: * In addition to the standard insertion operation, this implementation
29: * can allocate keys for the caller at insertion time.
30: *
31: * Upstream site with license notes :
32: * http://git.sceen.net/rbraun/librbraun.git/
33: */
34:
35: #ifndef _RDXTREE_H
36: #define _RDXTREE_H
37:
38: #include <stddef.h>
39: #include <sys/types.h>
40:
41: /*
42: * Initialize the node cache.
43: */
44: void rdxtree_cache_init(void);
45:
46: /*
47: * This macro selects between 32 or 64-bits (the default) keys.
48: */
49: #if 0
50: #define RDXTREE_KEY_32
51: #endif
52:
53: #ifdef RDXTREE_KEY_32
54: typedef uint32_t rdxtree_key_t;
55: #else /* RDXTREE_KEY_32 */
56: typedef uint64_t rdxtree_key_t;
57: #endif /* RDXTREE_KEY_32 */
58:
59: /*
60: * Radix tree.
61: */
62: struct rdxtree;
63:
64: /*
65: * Radix tree iterator.
66: */
67: struct rdxtree_iter;
68:
69: /*
70: * Static tree initializer.
71: */
72: #define RDXTREE_INITIALIZER { 0, NULL }
73:
74: #include "rdxtree_i.h"
75:
76: /*
77: * Initialize a tree.
78: */
79: static inline void
80: rdxtree_init(struct rdxtree *tree)
81: {
82: tree->height = 0;
83: tree->root = NULL;
84: }
85:
86: /*
87: * Insert a pointer in a tree.
88: *
89: * The ptr parameter must not be NULL.
90: */
91: static inline int
92: rdxtree_insert(struct rdxtree *tree, rdxtree_key_t key, void *ptr)
93: {
94: return rdxtree_insert_common(tree, key, ptr, NULL);
95: }
96:
97: /*
98: * Insert a pointer in a tree and obtain its slot.
99: *
100: * The ptr and slotp parameters must not be NULL. If successful, the slot of
101: * the newly inserted pointer is stored at the address pointed to by the slotp
102: * parameter.
103: */
104: static inline int
105: rdxtree_insert_slot(struct rdxtree *tree, rdxtree_key_t key,
106: void *ptr, void ***slotp)
107: {
108: return rdxtree_insert_common(tree, key, ptr, slotp);
109: }
110:
111: /*
112: * Insert a pointer in a tree, for which a new key is allocated.
113: *
114: * The ptr and keyp parameters must not be NULL. The newly allocated key is
115: * stored at the address pointed to by the keyp parameter.
116: */
117: static inline int
118: rdxtree_insert_alloc(struct rdxtree *tree, void *ptr, rdxtree_key_t *keyp)
119: {
120: return rdxtree_insert_alloc_common(tree, ptr, keyp, NULL);
121: }
122:
123: /*
124: * Insert a pointer in a tree, for which a new key is allocated, and obtain
125: * its slot.
126: *
127: * The ptr, keyp and slotp parameters must not be NULL. The newly allocated
128: * key is stored at the address pointed to by the keyp parameter while the
129: * slot of the inserted pointer is stored at the address pointed to by the
130: * slotp parameter.
131: */
132: static inline int
133: rdxtree_insert_alloc_slot(struct rdxtree *tree, void *ptr,
134: rdxtree_key_t *keyp, void ***slotp)
135: {
136: return rdxtree_insert_alloc_common(tree, ptr, keyp, slotp);
137: }
138:
139: /*
140: * Remove a pointer from a tree.
141: *
142: * The matching pointer is returned if successful, NULL otherwise.
143: */
144: void * rdxtree_remove(struct rdxtree *tree, rdxtree_key_t key);
145:
146: /*
147: * Look up a pointer in a tree.
148: *
149: * The matching pointer is returned if successful, NULL otherwise.
150: */
151: static inline void *
152: rdxtree_lookup(const struct rdxtree *tree, rdxtree_key_t key)
153: {
154: return rdxtree_lookup_common(tree, key, 0);
155: }
156:
157: /*
158: * Look up a slot in a tree.
159: *
160: * A slot is a pointer to a stored pointer in a tree. It can be used as
161: * a placeholder for fast replacements to avoid multiple lookups on the same
162: * key.
163: *
164: * A slot for the matching pointer is returned if successful, NULL otherwise.
165: *
166: * See rdxtree_replace_slot().
167: */
168: static inline void **
169: rdxtree_lookup_slot(const struct rdxtree *tree, rdxtree_key_t key)
170: {
171: return rdxtree_lookup_common(tree, key, 1);
172: }
173:
174: /*
175: * Replace a pointer in a tree.
176: *
177: * The ptr parameter must not be NULL. The previous pointer is returned.
178: *
179: * See rdxtree_lookup_slot().
180: */
181: void * rdxtree_replace_slot(void **slot, void *ptr);
182:
183: /*
184: * Forge a loop to process all pointers of a tree.
185: */
186: #define rdxtree_for_each(tree, iter, ptr) \
187: for (rdxtree_iter_init(iter), ptr = rdxtree_walk(tree, iter); \
188: ptr != NULL; \
189: ptr = rdxtree_walk(tree, iter))
190:
191: /*
192: * Return the key of the current pointer from an iterator.
193: */
194: static inline rdxtree_key_t
195: rdxtree_iter_key(const struct rdxtree_iter *iter)
196: {
197: return iter->key;
198: }
199:
200: /*
201: * Remove all pointers from a tree.
202: *
203: * The common way to destroy a tree and its pointers is to loop over all
204: * the pointers using rdxtree_for_each(), freeing them, then call this
205: * function.
206: */
207: void rdxtree_remove_all(struct rdxtree *tree);
208:
209: #endif /* _RDXTREE_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.