summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2018-06-28 12:19:04 +0200
committerantirez <antirez@gmail.com>2018-06-28 12:19:06 +0200
commit5baf50d850e1c58967fe3d2601ea61ee0d7b4ecd (patch)
tree24e1c3f2e7dee5e788a5a4140fe32dbf2d538f6f
parentab55f9da5eb10aabd78304941903e8657aa210e6 (diff)
downloadredis-5baf50d850e1c58967fe3d2601ea61ee0d7b4ecd.tar.gz
Rax library updated (node callback).
-rw-r--r--src/rax.c4
-rw-r--r--src/rax.h20
2 files changed, 19 insertions, 5 deletions
diff --git a/src/rax.c b/src/rax.c
index fff580272..c2aa95c3d 100644
--- a/src/rax.c
+++ b/src/rax.c
@@ -1241,6 +1241,8 @@ int raxIteratorNextStep(raxIterator *it, int noup) {
if (!raxIteratorAddChars(it,it->node->data,
it->node->iscompr ? it->node->size : 1)) return 0;
memcpy(&it->node,cp,sizeof(it->node));
+ /* Call the node callback if any, and replace the node pointer
+ * if the callback returns true. */
if (it->node_cb && it->node_cb(&it->node))
memcpy(cp,&it->node,sizeof(it->node));
/* For "next" step, stop every time we find a key along the
@@ -1295,6 +1297,8 @@ int raxIteratorNextStep(raxIterator *it, int noup) {
raxIteratorAddChars(it,it->node->data+i,1);
if (!raxStackPush(&it->stack,it->node)) return 0;
memcpy(&it->node,cp,sizeof(it->node));
+ /* Call the node callback if any, and replace the node
+ * pointer if the callback returns true. */
if (it->node_cb && it->node_cb(&it->node))
memcpy(cp,&it->node,sizeof(it->node));
if (it->node->iskey) {
diff --git a/src/rax.h b/src/rax.h
index 9e6bc0b51..226cd9b70 100644
--- a/src/rax.h
+++ b/src/rax.h
@@ -119,9 +119,18 @@ typedef struct raxStack {
int oom; /* True if pushing into this stack failed for OOM at some point. */
} raxStack;
-/* Optional callback used for iterators and be notified on each rax node.
- * This is used by active defrag, the return value is an indication that
- * the noderef was chagned, and the tree needs to be updated.
+/* Optional callback used for iterators and be notified on each rax node,
+ * including nodes not representing keys. If the callback returns true
+ * the callback changed the node pointer in the iterator structure, and the
+ * iterator implementation will have to replace the pointer in the radix tree
+ * internals. This allows the callback to reallocate the node to perform
+ * very special operations, normally not needed by normal applications.
+ *
+ * This callback is used to perform very low level analysis of the radix tree
+ * structure, scanning each possible node (but the root node), or in order to
+ * reallocate the nodes to reduce the allocation fragmentation (this is the
+ * Redis application for this callback).
+ *
* This is currently only supported in forward iterations (raxNext) */
typedef int (*raxNodeCallback)(raxNode **noderef);
@@ -143,7 +152,7 @@ typedef struct raxIterator {
unsigned char key_static_string[RAX_ITER_STATIC_LEN];
raxNode *node; /* Current node. Only for unsafe iteration. */
raxStack stack; /* Stack used for unsafe iteration. */
- raxNodeCallback node_cb;
+ raxNodeCallback node_cb; /* Optional node callback. Normally set to NULL. */
} raxIterator;
/* A special pointer returned for not found items. */
@@ -168,7 +177,8 @@ int raxEOF(raxIterator *it);
void raxShow(rax *rax);
uint64_t raxSize(rax *rax);
-/* internals */
+/* Internal API. May be used by the node callback in order to access rax nodes
+ * in a low level way, so this function is exported as well. */
void raxSetData(raxNode *n, void *data);
#endif