rdxtree.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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. #ifndef _RDXTREE_H
  35. #define _RDXTREE_H
  36. #include <stddef.h>
  37. #include <stdint.h>
  38. /*
  39. * Initialize the node cache.
  40. */
  41. void rdxtree_cache_init(void);
  42. /*
  43. * This macro selects between 32 or 64-bits (the default) keys.
  44. */
  45. #if 0
  46. #define RDXTREE_KEY_32
  47. #endif
  48. #ifdef RDXTREE_KEY_32
  49. typedef uint32_t rdxtree_key_t;
  50. #else /* RDXTREE_KEY_32 */
  51. typedef uint64_t rdxtree_key_t;
  52. #endif /* RDXTREE_KEY_32 */
  53. /*
  54. * Radix tree.
  55. */
  56. struct rdxtree;
  57. /*
  58. * Radix tree iterator.
  59. */
  60. struct rdxtree_iter;
  61. /*
  62. * Static tree initializer.
  63. */
  64. #define RDXTREE_INITIALIZER { 0, NULL }
  65. #include "rdxtree_i.h"
  66. /*
  67. * Initialize a tree.
  68. */
  69. static inline void
  70. rdxtree_init(struct rdxtree *tree)
  71. {
  72. tree->height = 0;
  73. tree->root = NULL;
  74. }
  75. /*
  76. * Insert a pointer in a tree.
  77. *
  78. * The ptr parameter must not be NULL.
  79. */
  80. static inline int
  81. rdxtree_insert(struct rdxtree *tree, rdxtree_key_t key, void *ptr)
  82. {
  83. return rdxtree_insert_common(tree, key, ptr, NULL);
  84. }
  85. /*
  86. * Insert a pointer in a tree and obtain its slot.
  87. *
  88. * The ptr and slotp parameters must not be NULL. If successful, the slot of
  89. * the newly inserted pointer is stored at the address pointed to by the slotp
  90. * parameter.
  91. */
  92. static inline int
  93. rdxtree_insert_slot(struct rdxtree *tree, rdxtree_key_t key,
  94. void *ptr, void ***slotp)
  95. {
  96. return rdxtree_insert_common(tree, key, ptr, slotp);
  97. }
  98. /*
  99. * Insert a pointer in a tree, for which a new key is allocated.
  100. *
  101. * The ptr and keyp parameters must not be NULL. The newly allocated key is
  102. * stored at the address pointed to by the keyp parameter.
  103. */
  104. static inline int
  105. rdxtree_insert_alloc(struct rdxtree *tree, void *ptr, rdxtree_key_t *keyp)
  106. {
  107. return rdxtree_insert_alloc_common(tree, ptr, keyp, NULL);
  108. }
  109. /*
  110. * Insert a pointer in a tree, for which a new key is allocated, and obtain
  111. * its slot.
  112. *
  113. * The ptr, keyp and slotp parameters must not be NULL. The newly allocated
  114. * key is stored at the address pointed to by the keyp parameter while the
  115. * slot of the inserted pointer is stored at the address pointed to by the
  116. * slotp parameter.
  117. */
  118. static inline int
  119. rdxtree_insert_alloc_slot(struct rdxtree *tree, void *ptr,
  120. rdxtree_key_t *keyp, void ***slotp)
  121. {
  122. return rdxtree_insert_alloc_common(tree, ptr, keyp, slotp);
  123. }
  124. /*
  125. * Remove a pointer from a tree.
  126. *
  127. * The matching pointer is returned if successful, NULL otherwise.
  128. */
  129. void * rdxtree_remove(struct rdxtree *tree, rdxtree_key_t key);
  130. /*
  131. * Look up a pointer in a tree.
  132. *
  133. * The matching pointer is returned if successful, NULL otherwise.
  134. */
  135. static inline void *
  136. rdxtree_lookup(const struct rdxtree *tree, rdxtree_key_t key)
  137. {
  138. return rdxtree_lookup_common(tree, key, 0);
  139. }
  140. /*
  141. * Look up a slot in a tree.
  142. *
  143. * A slot is a pointer to a stored pointer in a tree. It can be used as
  144. * a placeholder for fast replacements to avoid multiple lookups on the same
  145. * key.
  146. *
  147. * A slot for the matching pointer is returned if successful, NULL otherwise.
  148. *
  149. * See rdxtree_replace_slot().
  150. */
  151. static inline void **
  152. rdxtree_lookup_slot(const struct rdxtree *tree, rdxtree_key_t key)
  153. {
  154. return rdxtree_lookup_common(tree, key, 1);
  155. }
  156. /*
  157. * Replace a pointer in a tree.
  158. *
  159. * The ptr parameter must not be NULL. The previous pointer is returned.
  160. *
  161. * See rdxtree_lookup_slot().
  162. */
  163. void * rdxtree_replace_slot(void **slot, void *ptr);
  164. /*
  165. * Forge a loop to process all pointers of a tree.
  166. */
  167. #define rdxtree_for_each(tree, iter, ptr) \
  168. for (rdxtree_iter_init(iter), ptr = rdxtree_walk(tree, iter); \
  169. ptr != NULL; \
  170. ptr = rdxtree_walk(tree, iter))
  171. /*
  172. * Return the key of the current pointer from an iterator.
  173. */
  174. static inline rdxtree_key_t
  175. rdxtree_iter_key(const struct rdxtree_iter *iter)
  176. {
  177. return iter->key;
  178. }
  179. /*
  180. * Remove all pointers from a tree.
  181. *
  182. * The common way to destroy a tree and its pointers is to loop over all
  183. * the pointers using rdxtree_for_each(), freeing them, then call this
  184. * function.
  185. */
  186. void rdxtree_remove_all(struct rdxtree *tree);
  187. #endif /* _RDXTREE_H */