kbtree.h
Go to the documentation of this file.
1 /*-
2  * Copyright 1997-1999, 2001, John-Mark Gurney.
3  * 2008-2009, Attractive Chaos <[email protected]>
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  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #ifndef NVIM_LIB_KBTREE_H
29 #define NVIM_LIB_KBTREE_H
30 
31 #include <stdlib.h>
32 #include <string.h>
33 #include <stdint.h>
34 
35 #include "nvim/memory.h"
36 
37 #define KB_MAX_DEPTH 64
38 
39 #define __KB_KEY(type, x) (x->key)
40 #define __KB_PTR(btr, x) (x->ptr)
41 
42 #define __KB_TREE_T(name,key_t,T) \
43  typedef struct kbnode_##name##_s kbnode_##name##_t; \
44  struct kbnode_##name##_s { \
45  int32_t n; \
46  bool is_internal; \
47  key_t key[2*T-1]; \
48  kbnode_##name##_t *ptr[]; \
49  } ; \
50  \
51  typedef struct { \
52  kbnode_##name##_t *root; \
53  int n_keys, n_nodes; \
54  } kbtree_##name##_t; \
55  \
56  typedef struct { \
57  kbnode_##name##_t *x; \
58  int i; \
59  } kbpos_##name##_t; \
60  typedef struct { \
61  kbpos_##name##_t stack[KB_MAX_DEPTH], *p; \
62  } kbitr_##name##_t; \
63 
64 
65 #define __kb_destroy(kbnode_t,b) do { \
66  int i; \
67  unsigned int max = 8; \
68  kbnode_t *x, **top, **stack = 0; \
69  if (b->root) { \
70  top = stack = (kbnode_t**)xcalloc(max, sizeof(kbnode_t*)); \
71  *top++ = (b)->root; \
72  while (top != stack) { \
73  x = *--top; \
74  if (x->is_internal == 0) { xfree(x); continue; } \
75  for (i = 0; i <= x->n; ++i) \
76  if (__KB_PTR(b, x)[i]) { \
77  if (top - stack == (int)max) { \
78  max <<= 1; \
79  stack = (kbnode_t**)xrealloc(stack, max * sizeof(kbnode_t*)); \
80  top = stack + (max>>1); \
81  } \
82  *top++ = __KB_PTR(b, x)[i]; \
83  } \
84  xfree(x); \
85  } \
86  } \
87  xfree(stack); \
88  } while (0)
89 
90 #define __KB_GET_AUX1(name, key_t, kbnode_t, __cmp) \
91  static inline int __kb_getp_aux_##name(const kbnode_t * __restrict x, key_t * __restrict k, int *r) \
92  { \
93  int tr, *rr, begin = 0, end = x->n; \
94  if (x->n == 0) return -1; \
95  rr = r? r : &tr; \
96  while (begin < end) { \
97  int mid = (begin + end) >> 1; \
98  if (__cmp(__KB_KEY(key_t, x)[mid], *k) < 0) begin = mid + 1; \
99  else end = mid; \
100  } \
101  if (begin == x->n) { *rr = 1; return x->n - 1; } \
102  if ((*rr = __cmp(*k, __KB_KEY(key_t, x)[begin])) < 0) --begin; \
103  return begin; \
104  }
105 
106 #define __KB_GET(name, key_t, kbnode_t) \
107  static key_t *kb_getp_##name(kbtree_##name##_t *b, key_t * __restrict k) \
108  { \
109  if (!b->root) { \
110  return 0; \
111  } \
112  int i, r = 0; \
113  kbnode_t *x = b->root; \
114  while (x) { \
115  i = __kb_getp_aux_##name(x, k, &r); \
116  if (i >= 0 && r == 0) return &__KB_KEY(key_t, x)[i]; \
117  if (x->is_internal == 0) return 0; \
118  x = __KB_PTR(b, x)[i + 1]; \
119  } \
120  return 0; \
121  } \
122  static inline key_t *kb_get_##name(kbtree_##name##_t *b, key_t k) \
123  { \
124  return kb_getp_##name(b, &k); \
125  }
126 
127 #define __KB_INTERVAL(name, key_t, kbnode_t) \
128  static inline void kb_intervalp_##name(kbtree_##name##_t *b, key_t * __restrict k, key_t **lower, key_t **upper) \
129  { \
130  if (!b->root) { \
131  return; \
132  } \
133  int i, r = 0; \
134  kbnode_t *x = b->root; \
135  *lower = *upper = 0; \
136  while (x) { \
137  i = __kb_getp_aux_##name(x, k, &r); \
138  if (i >= 0 && r == 0) { \
139  *lower = *upper = &__KB_KEY(key_t, x)[i]; \
140  return; \
141  } \
142  if (i >= 0) *lower = &__KB_KEY(key_t, x)[i]; \
143  if (i < x->n - 1) *upper = &__KB_KEY(key_t, x)[i + 1]; \
144  if (x->is_internal == 0) return; \
145  x = __KB_PTR(b, x)[i + 1]; \
146  } \
147  } \
148  static inline void kb_interval_##name(kbtree_##name##_t *b, key_t k, key_t **lower, key_t **upper) \
149  { \
150  kb_intervalp_##name(b, &k, lower, upper); \
151  }
152 
153 #define __KB_PUT(name, key_t, kbnode_t, __cmp, T, ILEN) \
154  /* x must be an internal node */ \
155  static inline void __kb_split_##name(kbtree_##name##_t *b, kbnode_t *x, int i, kbnode_t *y) \
156  { \
157  kbnode_t *z; \
158  z = (kbnode_t*)xcalloc(1, y->is_internal? ILEN : sizeof(kbnode_##name##_t)); \
159  ++b->n_nodes; \
160  z->is_internal = y->is_internal; \
161  z->n = T - 1; \
162  memcpy(__KB_KEY(key_t, z), &__KB_KEY(key_t, y)[T], sizeof(key_t) * (T - 1)); \
163  if (y->is_internal) memcpy(__KB_PTR(b, z), &__KB_PTR(b, y)[T], sizeof(void*) * T); \
164  y->n = T - 1; \
165  memmove(&__KB_PTR(b, x)[i + 2], &__KB_PTR(b, x)[i + 1], sizeof(void*) * (unsigned int)(x->n - i)); \
166  __KB_PTR(b, x)[i + 1] = z; \
167  memmove(&__KB_KEY(key_t, x)[i + 1], &__KB_KEY(key_t, x)[i], sizeof(key_t) * (unsigned int)(x->n - i)); \
168  __KB_KEY(key_t, x)[i] = __KB_KEY(key_t, y)[T - 1]; \
169  ++x->n; \
170  } \
171  static inline key_t *__kb_putp_aux_##name(kbtree_##name##_t *b, kbnode_t *x, key_t * __restrict k) \
172  { \
173  int i = x->n - 1; \
174  key_t *ret; \
175  if (x->is_internal == 0) { \
176  i = __kb_getp_aux_##name(x, k, 0); \
177  if (i != x->n - 1) \
178  memmove(&__KB_KEY(key_t, x)[i + 2], &__KB_KEY(key_t, x)[i + 1], (unsigned int)(x->n - i - 1) * sizeof(key_t)); \
179  ret = &__KB_KEY(key_t, x)[i + 1]; \
180  *ret = *k; \
181  ++x->n; \
182  } else { \
183  i = __kb_getp_aux_##name(x, k, 0) + 1; \
184  if (__KB_PTR(b, x)[i]->n == 2 * T - 1) { \
185  __kb_split_##name(b, x, i, __KB_PTR(b, x)[i]); \
186  if (__cmp(*k, __KB_KEY(key_t, x)[i]) > 0) ++i; \
187  } \
188  ret = __kb_putp_aux_##name(b, __KB_PTR(b, x)[i], k); \
189  } \
190  return ret; \
191  } \
192  static inline key_t *kb_putp_##name(kbtree_##name##_t *b, key_t * __restrict k) \
193  { \
194  if (!b->root) { \
195  b->root = (kbnode_t*)xcalloc(1, ILEN); \
196  ++b->n_nodes; \
197  } \
198  kbnode_t *r, *s; \
199  ++b->n_keys; \
200  r = b->root; \
201  if (r->n == 2 * T - 1) { \
202  ++b->n_nodes; \
203  s = (kbnode_t*)xcalloc(1, ILEN); \
204  b->root = s; s->is_internal = 1; s->n = 0; \
205  __KB_PTR(b, s)[0] = r; \
206  __kb_split_##name(b, s, 0, r); \
207  r = s; \
208  } \
209  return __kb_putp_aux_##name(b, r, k); \
210  } \
211  static inline void kb_put_##name(kbtree_##name##_t *b, key_t k) \
212  { \
213  kb_putp_##name(b, &k); \
214  }
215 
216 
217 #define __KB_DEL(name, key_t, kbnode_t, T) \
218  static inline key_t __kb_delp_aux_##name(kbtree_##name##_t *b, kbnode_t *x, key_t * __restrict k, int s) \
219  { \
220  int yn, zn, i, r = 0; \
221  kbnode_t *xp, *y, *z; \
222  key_t kp; \
223  if (x == 0) return *k; \
224  if (s) { /* s can only be 0, 1 or 2 */ \
225  r = x->is_internal == 0? 0 : s == 1? 1 : -1; \
226  i = s == 1? x->n - 1 : -1; \
227  } else i = __kb_getp_aux_##name(x, k, &r); \
228  if (x->is_internal == 0) { \
229  if (s == 2) ++i; \
230  kp = __KB_KEY(key_t, x)[i]; \
231  memmove(&__KB_KEY(key_t, x)[i], &__KB_KEY(key_t, x)[i + 1], (unsigned int)(x->n - i - 1) * sizeof(key_t)); \
232  --x->n; \
233  return kp; \
234  } \
235  if (r == 0) { \
236  if ((yn = __KB_PTR(b, x)[i]->n) >= T) { \
237  xp = __KB_PTR(b, x)[i]; \
238  kp = __KB_KEY(key_t, x)[i]; \
239  __KB_KEY(key_t, x)[i] = __kb_delp_aux_##name(b, xp, 0, 1); \
240  return kp; \
241  } else if ((zn = __KB_PTR(b, x)[i + 1]->n) >= T) { \
242  xp = __KB_PTR(b, x)[i + 1]; \
243  kp = __KB_KEY(key_t, x)[i]; \
244  __KB_KEY(key_t, x)[i] = __kb_delp_aux_##name(b, xp, 0, 2); \
245  return kp; \
246  } else if (yn == T - 1 && zn == T - 1) { \
247  y = __KB_PTR(b, x)[i]; z = __KB_PTR(b, x)[i + 1]; \
248  __KB_KEY(key_t, y)[y->n++] = *k; \
249  memmove(&__KB_KEY(key_t, y)[y->n], __KB_KEY(key_t, z), (unsigned int)z->n * sizeof(key_t)); \
250  if (y->is_internal) memmove(&__KB_PTR(b, y)[y->n], __KB_PTR(b, z), (unsigned int)(z->n + 1) * sizeof(void*)); \
251  y->n += z->n; \
252  memmove(&__KB_KEY(key_t, x)[i], &__KB_KEY(key_t, x)[i + 1], (unsigned int)(x->n - i - 1) * sizeof(key_t)); \
253  memmove(&__KB_PTR(b, x)[i + 1], &__KB_PTR(b, x)[i + 2], (unsigned int)(x->n - i - 1) * sizeof(void*)); \
254  --x->n; \
255  xfree(z); \
256  return __kb_delp_aux_##name(b, y, k, s); \
257  } \
258  } \
259  ++i; \
260  if ((xp = __KB_PTR(b, x)[i])->n == T - 1) { \
261  if (i > 0 && (y = __KB_PTR(b, x)[i - 1])->n >= T) { \
262  memmove(&__KB_KEY(key_t, xp)[1], __KB_KEY(key_t, xp), (unsigned int)xp->n * sizeof(key_t)); \
263  if (xp->is_internal) memmove(&__KB_PTR(b, xp)[1], __KB_PTR(b, xp), (unsigned int)(xp->n + 1) * sizeof(void*)); \
264  __KB_KEY(key_t, xp)[0] = __KB_KEY(key_t, x)[i - 1]; \
265  __KB_KEY(key_t, x)[i - 1] = __KB_KEY(key_t, y)[y->n - 1]; \
266  if (xp->is_internal) __KB_PTR(b, xp)[0] = __KB_PTR(b, y)[y->n]; \
267  --y->n; ++xp->n; \
268  } else if (i < x->n && (y = __KB_PTR(b, x)[i + 1])->n >= T) { \
269  __KB_KEY(key_t, xp)[xp->n++] = __KB_KEY(key_t, x)[i]; \
270  __KB_KEY(key_t, x)[i] = __KB_KEY(key_t, y)[0]; \
271  if (xp->is_internal) __KB_PTR(b, xp)[xp->n] = __KB_PTR(b, y)[0]; \
272  --y->n; \
273  memmove(__KB_KEY(key_t, y), &__KB_KEY(key_t, y)[1], (unsigned int)y->n * sizeof(key_t)); \
274  if (y->is_internal) memmove(__KB_PTR(b, y), &__KB_PTR(b, y)[1], (unsigned int)(y->n + 1) * sizeof(void*)); \
275  } else if (i > 0 && (y = __KB_PTR(b, x)[i - 1])->n == T - 1) { \
276  __KB_KEY(key_t, y)[y->n++] = __KB_KEY(key_t, x)[i - 1]; \
277  memmove(&__KB_KEY(key_t, y)[y->n], __KB_KEY(key_t, xp), (unsigned int)xp->n * sizeof(key_t)); \
278  if (y->is_internal) memmove(&__KB_PTR(b, y)[y->n], __KB_PTR(b, xp), (unsigned int)(xp->n + 1) * sizeof(void*)); \
279  y->n += xp->n; \
280  memmove(&__KB_KEY(key_t, x)[i - 1], &__KB_KEY(key_t, x)[i], (unsigned int)(x->n - i) * sizeof(key_t)); \
281  memmove(&__KB_PTR(b, x)[i], &__KB_PTR(b, x)[i + 1], (unsigned int)(x->n - i) * sizeof(void*)); \
282  --x->n; \
283  xfree(xp); \
284  xp = y; \
285  } else if (i < x->n && (y = __KB_PTR(b, x)[i + 1])->n == T - 1) { \
286  __KB_KEY(key_t, xp)[xp->n++] = __KB_KEY(key_t, x)[i]; \
287  memmove(&__KB_KEY(key_t, xp)[xp->n], __KB_KEY(key_t, y), (unsigned int)y->n * sizeof(key_t)); \
288  if (xp->is_internal) memmove(&__KB_PTR(b, xp)[xp->n], __KB_PTR(b, y), (unsigned int)(y->n + 1) * sizeof(void*)); \
289  xp->n += y->n; \
290  memmove(&__KB_KEY(key_t, x)[i], &__KB_KEY(key_t, x)[i + 1], (unsigned int)(x->n - i - 1) * sizeof(key_t)); \
291  memmove(&__KB_PTR(b, x)[i + 1], &__KB_PTR(b, x)[i + 2], (unsigned int)(x->n - i - 1) * sizeof(void*)); \
292  --x->n; \
293  xfree(y); \
294  } \
295  } \
296  return __kb_delp_aux_##name(b, xp, k, s); \
297  } \
298  static inline key_t kb_delp_##name(kbtree_##name##_t *b, key_t * __restrict k) \
299  { \
300  kbnode_t *x; \
301  key_t ret; \
302  ret = __kb_delp_aux_##name(b, b->root, k, 0); \
303  --b->n_keys; \
304  if (b->root->n == 0 && b->root->is_internal) { \
305  --b->n_nodes; \
306  x = b->root; \
307  b->root = __KB_PTR(b, x)[0]; \
308  xfree(x); \
309  } \
310  return ret; \
311  } \
312  static inline key_t kb_del_##name(kbtree_##name##_t *b, key_t k) \
313  { \
314  return kb_delp_##name(b, &k); \
315  }
316 
317 #define __KB_ITR(name, key_t, kbnode_t) \
318  static inline void kb_itr_first_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \
319  { \
320  itr->p = 0; \
321  if (b->n_keys == 0) return; \
322  itr->p = itr->stack; \
323  itr->p->x = b->root; itr->p->i = 0; \
324  while (itr->p->x->is_internal && __KB_PTR(b, itr->p->x)[0] != 0) { \
325  kbnode_t *x = itr->p->x; \
326  ++itr->p; \
327  itr->p->x = __KB_PTR(b, x)[0]; itr->p->i = 0; \
328  } \
329  } \
330  static inline int kb_itr_next_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \
331  { \
332  if (itr->p < itr->stack) return 0; \
333  for (;;) { \
334  ++itr->p->i; \
335  while (itr->p->x && itr->p->i <= itr->p->x->n) { \
336  itr->p[1].i = 0; \
337  itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[itr->p->i] : 0; \
338  ++itr->p; \
339  } \
340  --itr->p; \
341  if (itr->p < itr->stack) return 0; \
342  if (itr->p->x && itr->p->i < itr->p->x->n) return 1; \
343  } \
344  } \
345  static inline int kb_itr_prev_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \
346  { \
347  if (itr->p < itr->stack) return 0; \
348  for (;;) { \
349  while (itr->p->x && itr->p->i >= 0) { \
350  itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[itr->p->i] : 0; \
351  itr->p[1].i = itr->p[1].x ? itr->p[1].x->n : -1; \
352  ++itr->p; \
353  } \
354  --itr->p; \
355  if (itr->p < itr->stack) return 0; \
356  --itr->p->i; \
357  if (itr->p->x && itr->p->i >= 0) return 1; \
358  } \
359  } \
360  static inline int kb_itr_getp_##name(kbtree_##name##_t *b, key_t * __restrict k, kbitr_##name##_t *itr) \
361  { \
362  if (b->n_keys == 0) { \
363  itr->p = NULL; \
364  return 0; \
365  } \
366  int i, r = 0; \
367  itr->p = itr->stack; \
368  itr->p->x = b->root; \
369  while (itr->p->x) { \
370  i = __kb_getp_aux_##name(itr->p->x, k, &r); \
371  itr->p->i = i; \
372  if (i >= 0 && r == 0) return 1; \
373  ++itr->p->i; \
374  itr->p[1].x = itr->p->x->is_internal? __KB_PTR(b, itr->p->x)[i + 1] : 0; \
375  ++itr->p; \
376  } \
377  return 0; \
378  } \
379  static inline int kb_itr_get_##name(kbtree_##name##_t *b, key_t k, kbitr_##name##_t *itr) \
380  { \
381  return kb_itr_getp_##name(b,&k,itr); \
382  } \
383  static inline void kb_del_itr_##name(kbtree_##name##_t *b, kbitr_##name##_t *itr) \
384  { \
385  key_t k = kb_itr_key(itr); \
386  kb_delp_##name(b, &k); \
387  kb_itr_getp_##name(b, &k, itr); \
388  }
389 
390 #define KBTREE_INIT(name, key_t, __cmp, T) \
391  KBTREE_INIT_IMPL(name, key_t, kbnode_##name##_t, __cmp, T, (sizeof(kbnode_##name##_t)+(2*T)*sizeof(void *)))
392 
393 #define KBTREE_INIT_IMPL(name, key_t, kbnode_t, __cmp, T, ILEN) \
394  __KB_TREE_T(name, key_t, T) \
395  __KB_GET_AUX1(name, key_t, kbnode_t, __cmp) \
396  __KB_GET(name, key_t, kbnode_t) \
397  __KB_INTERVAL(name, key_t, kbnode_t) \
398  __KB_PUT(name, key_t, kbnode_t, __cmp, T, ILEN) \
399  __KB_DEL(name, key_t, kbnode_t, T) \
400  __KB_ITR(name, key_t, kbnode_t)
401 
402 #define KB_DEFAULT_SIZE 512
403 
404 #define kbtree_t(name) kbtree_##name##_t
405 #define kbitr_t(name) kbitr_##name##_t
406 #define kb_init(b) ((b)->n_keys = (b)->n_nodes = 0, (b)->root = 0)
407 #define kb_destroy(name, b) __kb_destroy(kbnode_##name##_t, b)
408 #define kb_get(name, b, k) kb_get_##name(b, k)
409 #define kb_put(name, b, k) kb_put_##name(b, k)
410 #define kb_del(name, b, k) kb_del_##name(b, k)
411 #define kb_interval(name, b, k, l, u) kb_interval_##name(b, k, l, u)
412 #define kb_getp(name, b, k) kb_getp_##name(b, k)
413 #define kb_putp(name, b, k) kb_putp_##name(b, k)
414 #define kb_delp(name, b, k) kb_delp_##name(b, k)
415 #define kb_intervalp(name, b, k, l, u) kb_intervalp_##name(b, k, l, u)
416 
417 #define kb_itr_first(name, b, i) kb_itr_first_##name(b, i)
418 #define kb_itr_get(name, b, k, i) kb_itr_get_##name(b, k, i)
419 #define kb_itr_getp(name, b, k, i) kb_itr_getp_##name(b, k, i)
420 #define kb_itr_next(name, b, i) kb_itr_next_##name(b, i)
421 #define kb_itr_prev(name, b, i) kb_itr_prev_##name(b, i)
422 #define kb_del_itr(name, b, i) kb_del_itr_##name(b, i)
423 #define kb_itr_key(itr) __KB_KEY(dummy, (itr)->p->x)[(itr)->p->i]
424 #define kb_itr_valid(itr) ((itr)->p >= (itr)->stack)
425 
426 #define kb_size(b) ((b)->n_keys)
427 
428 #define kb_generic_cmp(a, b) (((b) < (a)) - ((a) < (b)))
429 #define kb_str_cmp(a, b) strcmp(a, b)
430 
431 #endif // NVIM_LIB_KBTREE_H