aboutsummaryrefslogtreecommitdiff
path: root/examples/redis-unstable/src/rax.h
diff options
context:
space:
mode:
Diffstat (limited to 'examples/redis-unstable/src/rax.h')
-rw-r--r--examples/redis-unstable/src/rax.h204
1 files changed, 0 insertions, 204 deletions
diff --git a/examples/redis-unstable/src/rax.h b/examples/redis-unstable/src/rax.h
deleted file mode 100644
index db8c463..0000000
--- a/examples/redis-unstable/src/rax.h
+++ /dev/null
@@ -1,204 +0,0 @@
1/* Rax -- A radix tree implementation.
2 *
3 * Copyright (c) 2017-Present, Redis Ltd.
4 * All rights reserved.
5 *
6 * Licensed under your choice of (a) the Redis Source Available License 2.0
7 * (RSALv2); or (b) the Server Side Public License v1 (SSPLv1); or (c) the
8 * GNU Affero General Public License v3 (AGPLv3).
9 */
10
11#ifndef RAX_H
12#define RAX_H
13
14#include <stdint.h>
15
16/* Representation of a radix tree as implemented in this file, that contains
17 * the strings "foo", "foobar" and "footer" after the insertion of each
18 * word. When the node represents a key inside the radix tree, we write it
19 * between [], otherwise it is written between ().
20 *
21 * This is the vanilla representation:
22 *
23 * (f) ""
24 * \
25 * (o) "f"
26 * \
27 * (o) "fo"
28 * \
29 * [t b] "foo"
30 * / \
31 * "foot" (e) (a) "foob"
32 * / \
33 * "foote" (r) (r) "fooba"
34 * / \
35 * "footer" [] [] "foobar"
36 *
37 * However, this implementation implements a very common optimization where
38 * successive nodes having a single child are "compressed" into the node
39 * itself as a string of characters, each representing a next-level child,
40 * and only the link to the node representing the last character node is
41 * provided inside the representation. So the above representation is turned
42 * into:
43 *
44 * ["foo"] ""
45 * |
46 * [t b] "foo"
47 * / \
48 * "foot" ("er") ("ar") "foob"
49 * / \
50 * "footer" [] [] "foobar"
51 *
52 * However this optimization makes the implementation a bit more complex.
53 * For instance if a key "first" is added in the above radix tree, a
54 * "node splitting" operation is needed, since the "foo" prefix is no longer
55 * composed of nodes having a single child one after the other. This is the
56 * above tree and the resulting node splitting after this event happens:
57 *
58 *
59 * (f) ""
60 * /
61 * (i o) "f"
62 * / \
63 * "firs" ("rst") (o) "fo"
64 * / \
65 * "first" [] [t b] "foo"
66 * / \
67 * "foot" ("er") ("ar") "foob"
68 * / \
69 * "footer" [] [] "foobar"
70 *
71 * Similarly after deletion, if a new chain of nodes having a single child
72 * is created (the chain must also not include nodes that represent keys),
73 * it must be compressed back into a single node.
74 *
75 */
76
77#define RAX_NODE_MAX_SIZE ((1<<29)-1)
78typedef struct raxNode {
79 uint32_t iskey:1; /* Does this node contain a key? */
80 uint32_t isnull:1; /* Associated value is NULL (don't store it). */
81 uint32_t iscompr:1; /* Node is compressed. */
82 uint32_t size:29; /* Number of children, or compressed string len. */
83 /* Data layout is as follows:
84 *
85 * If node is not compressed we have 'size' bytes, one for each children
86 * character, and 'size' raxNode pointers, point to each child node.
87 * Note how the character is not stored in the children but in the
88 * edge of the parents:
89 *
90 * [header iscompr=0][abc][a-ptr][b-ptr][c-ptr](value-ptr?)
91 *
92 * if node is compressed (iscompr bit is 1) the node has 1 child.
93 * In that case the 'size' bytes of the string stored immediately at
94 * the start of the data section, represent a sequence of successive
95 * nodes linked one after the other, for which only the last one in
96 * the sequence is actually represented as a node, and pointed to by
97 * the current compressed node.
98 *
99 * [header iscompr=1][xyz][z-ptr](value-ptr?)
100 *
101 * Both compressed and not compressed nodes can represent a key
102 * with associated data in the radix tree at any level (not just terminal
103 * nodes).
104 *
105 * If the node has an associated key (iskey=1) and is not NULL
106 * (isnull=0), then after the raxNode pointers pointing to the
107 * children, an additional value pointer is present (as you can see
108 * in the representation above as "value-ptr" field).
109 */
110 unsigned char data[];
111} raxNode;
112
113typedef struct rax {
114 raxNode *head;
115 uint64_t numele;
116 uint64_t numnodes;
117 size_t *alloc_size;
118 void *metadata[];
119} rax;
120
121/* Stack data structure used by raxLowWalk() in order to, optionally, return
122 * a list of parent nodes to the caller. The nodes do not have a "parent"
123 * field for space concerns, so we use the auxiliary stack when needed. */
124#define RAX_STACK_STATIC_ITEMS 32
125typedef struct raxStack {
126 void **stack; /* Points to static_items or an heap allocated array. */
127 size_t items, maxitems; /* Number of items contained and total space. */
128 /* Up to RAXSTACK_STACK_ITEMS items we avoid to allocate on the heap
129 * and use this static array of pointers instead. */
130 void *static_items[RAX_STACK_STATIC_ITEMS];
131 int oom; /* True if pushing into this stack failed for OOM at some point. */
132} raxStack;
133
134/* Optional callback used for iterators and be notified on each rax node,
135 * including nodes not representing keys. If the callback returns true
136 * the callback changed the node pointer in the iterator structure, and the
137 * iterator implementation will have to replace the pointer in the radix tree
138 * internals. This allows the callback to reallocate the node to perform
139 * very special operations, normally not needed by normal applications.
140 *
141 * This callback is used to perform very low level analysis of the radix tree
142 * structure, scanning each possible node (but the root node), or in order to
143 * reallocate the nodes to reduce the allocation fragmentation (this is the
144 * Redis application for this callback).
145 *
146 * This is currently only supported in forward iterations (raxNext) */
147typedef int (*raxNodeCallback)(raxNode **noderef, void *privdata);
148
149/* Radix tree iterator state is encapsulated into this data structure. */
150#define RAX_ITER_STATIC_LEN 128
151#define RAX_ITER_JUST_SEEKED (1<<0) /* Iterator was just seeked. Return current
152 element for the first iteration and
153 clear the flag. */
154#define RAX_ITER_EOF (1<<1) /* End of iteration reached. */
155#define RAX_ITER_SAFE (1<<2) /* Safe iterator, allows operations while
156 iterating. But it is slower. */
157typedef struct raxIterator {
158 int flags;
159 rax *rt; /* Radix tree we are iterating. */
160 unsigned char *key; /* The current string. */
161 void *data; /* Data associated to this key. */
162 size_t key_len; /* Current key length. */
163 size_t key_max; /* Max key len the current key buffer can hold. */
164 unsigned char key_static_string[RAX_ITER_STATIC_LEN];
165 raxNode *node; /* Current node. Only for unsafe iteration. */
166 raxStack stack; /* Stack used for unsafe iteration. */
167 raxNodeCallback node_cb; /* Optional node callback. Normally set to NULL. */
168 void *privdata; /* Optional private data for node callback. */
169} raxIterator;
170
171/* Exported API. */
172rax *raxNew(void);
173rax *raxNewWithMetadata(int metaSize, size_t *alloc_size);
174int raxInsert(rax *rax, unsigned char *s, size_t len, void *data, void **old);
175int raxTryInsert(rax *rax, unsigned char *s, size_t len, void *data, void **old);
176int raxRemove(rax *rax, unsigned char *s, size_t len, void **old);
177int raxFind(rax *rax, unsigned char *s, size_t len, void **value);
178void raxFree(rax *rax);
179void raxFreeWithCallback(rax *rax, void (*free_callback)(void*));
180void raxFreeWithCbAndContext(rax *rax,
181 void (*free_callback)(void *item, void *ctx),
182 void *ctx);
183void raxStart(raxIterator *it, rax *rt);
184int raxSeek(raxIterator *it, const char *op, unsigned char *ele, size_t len);
185int raxNext(raxIterator *it);
186int raxPrev(raxIterator *it);
187int raxRandomWalk(raxIterator *it, size_t steps);
188int raxCompare(raxIterator *iter, const char *op, unsigned char *key, size_t key_len);
189void raxStop(raxIterator *it);
190int raxEOF(raxIterator *it);
191void raxShow(rax *rax);
192uint64_t raxSize(rax *rax);
193unsigned long raxTouch(raxNode *n);
194void raxSetDebugMsg(int onoff);
195
196/* Internal API. May be used by the node callback in order to access rax nodes
197 * in a low level way, so this function is exported as well. */
198void raxSetData(raxNode *n, void *data);
199
200#ifdef REDIS_TEST
201int raxTest(int argc, char *argv[], int flags);
202#endif
203
204#endif