art.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. #ifndef ART_ART_H
  2. #define ART_ART_H
  3. #include <stdbool.h>
  4. #include <stddef.h>
  5. #include <stdint.h>
  6. /*
  7. * This file contains an implementation of an Adaptive Radix Tree as described
  8. * in https://db.in.tum.de/~leis/papers/ART.pdf.
  9. *
  10. * The ART contains the keys in _byte lexographical_ order.
  11. *
  12. * Other features:
  13. * * Fixed 48 bit key length: all keys are assumed to be be 48 bits in size.
  14. * This allows us to put the key and key prefixes directly in nodes, reducing
  15. * indirection at no additional memory overhead.
  16. * * Key compression: the only inner nodes created are at points where key
  17. * chunks _differ_. This means that if there are two entries with different
  18. * high 48 bits, then there is only one inner node containing the common key
  19. * prefix, and two leaves.
  20. * * Intrusive leaves: the leaf struct is included in user values. This removes
  21. * a layer of indirection.
  22. */
  23. // Fixed length of keys in the ART. All keys are assumed to be of this length.
  24. #define ART_KEY_BYTES 6
  25. #ifdef __cplusplus
  26. extern "C" {
  27. namespace roaring {
  28. namespace internal {
  29. #endif
  30. typedef uint8_t art_key_chunk_t;
  31. typedef struct art_node_s art_node_t;
  32. /**
  33. * Wrapper to allow an empty tree.
  34. */
  35. typedef struct art_s {
  36. art_node_t *root;
  37. } art_t;
  38. /**
  39. * Values inserted into the tree have to be cast-able to art_val_t. This
  40. * improves performance by reducing indirection.
  41. *
  42. * NOTE: Value pointers must be unique! This is because each value struct
  43. * contains the key corresponding to the value.
  44. */
  45. typedef struct art_val_s {
  46. art_key_chunk_t key[ART_KEY_BYTES];
  47. } art_val_t;
  48. /**
  49. * Compares two keys, returns their relative order:
  50. * * Key 1 < key 2: returns a negative value
  51. * * Key 1 == key 2: returns 0
  52. * * Key 1 > key 2: returns a positive value
  53. */
  54. int art_compare_keys(const art_key_chunk_t key1[],
  55. const art_key_chunk_t key2[]);
  56. /**
  57. * Inserts the given key and value.
  58. */
  59. void art_insert(art_t *art, const art_key_chunk_t *key, art_val_t *val);
  60. /**
  61. * Returns the value erased, NULL if not found.
  62. */
  63. art_val_t *art_erase(art_t *art, const art_key_chunk_t *key);
  64. /**
  65. * Returns the value associated with the given key, NULL if not found.
  66. */
  67. art_val_t *art_find(const art_t *art, const art_key_chunk_t *key);
  68. /**
  69. * Returns true if the ART is empty.
  70. */
  71. bool art_is_empty(const art_t *art);
  72. /**
  73. * Frees the nodes of the ART except the values, which the user is expected to
  74. * free.
  75. */
  76. void art_free(art_t *art);
  77. /**
  78. * Returns the size in bytes of the ART. Includes size of pointers to values,
  79. * but not the values themselves.
  80. */
  81. size_t art_size_in_bytes(const art_t *art);
  82. /**
  83. * Prints the ART using printf, useful for debugging.
  84. */
  85. void art_printf(const art_t *art);
  86. /**
  87. * Callback for validating the value stored in a leaf.
  88. *
  89. * Should return true if the value is valid, false otherwise
  90. * If false is returned, `*reason` should be set to a static string describing
  91. * the reason for the failure.
  92. */
  93. typedef bool (*art_validate_cb_t)(const art_val_t *val, const char **reason);
  94. /**
  95. * Validate the ART tree, ensuring it is internally consistent.
  96. */
  97. bool art_internal_validate(const art_t *art, const char **reason,
  98. art_validate_cb_t validate_cb);
  99. /**
  100. * ART-internal iterator bookkeeping. Users should treat this as an opaque type.
  101. */
  102. typedef struct art_iterator_frame_s {
  103. art_node_t *node;
  104. uint8_t index_in_node;
  105. } art_iterator_frame_t;
  106. /**
  107. * Users should only access `key` and `value` in iterators. The iterator is
  108. * valid when `value != NULL`.
  109. */
  110. typedef struct art_iterator_s {
  111. art_key_chunk_t key[ART_KEY_BYTES];
  112. art_val_t *value;
  113. uint8_t depth; // Key depth
  114. uint8_t frame; // Node depth
  115. // State for each node in the ART the iterator has travelled from the root.
  116. // This is `ART_KEY_BYTES + 1` because it includes state for the leaf too.
  117. art_iterator_frame_t frames[ART_KEY_BYTES + 1];
  118. } art_iterator_t;
  119. /**
  120. * Creates an iterator initialzed to the first or last entry in the ART,
  121. * depending on `first`. The iterator is not valid if there are no entries in
  122. * the ART.
  123. */
  124. art_iterator_t art_init_iterator(const art_t *art, bool first);
  125. /**
  126. * Returns an initialized iterator positioned at a key equal to or greater than
  127. * the given key, if it exists.
  128. */
  129. art_iterator_t art_lower_bound(const art_t *art, const art_key_chunk_t *key);
  130. /**
  131. * Returns an initialized iterator positioned at a key greater than the given
  132. * key, if it exists.
  133. */
  134. art_iterator_t art_upper_bound(const art_t *art, const art_key_chunk_t *key);
  135. /**
  136. * The following iterator movement functions return true if a new entry was
  137. * encountered.
  138. */
  139. bool art_iterator_move(art_iterator_t *iterator, bool forward);
  140. bool art_iterator_next(art_iterator_t *iterator);
  141. bool art_iterator_prev(art_iterator_t *iterator);
  142. /**
  143. * Moves the iterator forward to a key equal to or greater than the given key.
  144. */
  145. bool art_iterator_lower_bound(art_iterator_t *iterator,
  146. const art_key_chunk_t *key);
  147. /**
  148. * Insert the value and positions the iterator at the key.
  149. */
  150. void art_iterator_insert(art_t *art, art_iterator_t *iterator,
  151. const art_key_chunk_t *key, art_val_t *val);
  152. /**
  153. * Erase the value pointed at by the iterator. Moves the iterator to the next
  154. * leaf. Returns the value erased or NULL if nothing was erased.
  155. */
  156. art_val_t *art_iterator_erase(art_t *art, art_iterator_t *iterator);
  157. #ifdef __cplusplus
  158. } // extern "C"
  159. } // namespace roaring
  160. } // namespace internal
  161. #endif
  162. #endif