MCPcopy Create free account
hub / github.com/antirez/ds4 / raxRandomWalk

Function raxRandomWalk

rax.c:2152–2215  ·  view source on GitHub ↗

Perform a random walk starting in the current position of the iterator. * Return 0 if the tree is empty or on out of memory. Otherwise 1 is returned * and the iterator is set to the node reached after doing a random walk * of 'steps' steps. If the 'steps' argument is 0, the random walk is performed * using a random number of steps between 1 and two times the logarithm of * the number of eleme

Source from the content-addressed store, hash-verified

2150 * tree certain keys will be reported much more often than others. At least
2151 * this function should be able to expore every possible element eventually. */
2152int raxRandomWalk(raxIterator *it, size_t steps) {
2153 if (it->rt->numele == 0) {
2154 it->flags |= RAX_ITER_EOF;
2155 return 0;
2156 }
2157
2158 if (steps == 0) {
2159 size_t fle = 1+floor(log(it->rt->numele));
2160 fle *= 2;
2161 steps = 1 + rand() % fle;
2162 }
2163
2164 raxNode *n = it->node;
2165 int inline_leaf = raxIteratorIsInlineLeaf(it);
2166 int node_child = it->node_child;
2167 while(steps > 0 || !(inline_leaf || n->iskey)) {
2168 if (inline_leaf) {
2169 inline_leaf = 0;
2170 int todel = n->iscompr ? n->size : 1;
2171 raxIteratorDelChars(it,todel);
2172 if (n->iskey) steps--;
2173 continue;
2174 }
2175
2176 int numchildren = n->iscompr ? 1 : n->size;
2177 int r = rand() % (numchildren+(n != it->rt->head));
2178
2179 if (r == numchildren) {
2180 /* Go up to parent. */
2181 n = raxStackPop(&it->stack);
2182 node_child = -1;
2183 int todel = n->iscompr ? n->size : 1;
2184 raxIteratorDelChars(it,todel);
2185 } else {
2186 /* Select a random child. */
2187 raxNode **cp = raxNodeFirstChildPtr(n)+r;
2188 int cidx = n->iscompr ? 0 : r;
2189 if (n->iscompr) {
2190 if (!raxIteratorAddChars(it,n->data,n->size)) return 0;
2191 } else {
2192 if (!raxIteratorAddChars(it,n->data+r,1)) return 0;
2193 }
2194 if (raxIsInlineLeaf(n,cidx)) {
2195 memcpy(&it->data,cp,sizeof(it->data));
2196 inline_leaf = 1;
2197 node_child = cidx;
2198 } else {
2199 if (!raxStackPush(&it->stack,n)) return 0;
2200 memcpy(&n,cp,sizeof(n));
2201 node_child = cidx;
2202 }
2203 }
2204 if (inline_leaf || n->iskey) steps--;
2205 }
2206 it->node = n;
2207 it->node_child = node_child;
2208 if (inline_leaf) {
2209 it->flags |= RAX_ITER_INLINE_LEAF;

Callers

nothing calls this directly

Calls 7

raxIteratorIsInlineLeafFunction · 0.85
raxIteratorDelCharsFunction · 0.85
raxStackPopFunction · 0.85
raxIteratorAddCharsFunction · 0.85
raxIsInlineLeafFunction · 0.85
raxStackPushFunction · 0.85
raxGetDataFunction · 0.85

Tested by

no test coverage detected