30#ifndef PSPLAY_TRAIL_DEPTH
31#define PSPLAY_TRAIL_DEPTH 128
46#define PSPLAY_FORMULA (self->log2*100/(depth + (psplay_fast_prng () & 63)) + trail->dir) * splayfactor
48#ifndef PSPLAY_PROB_ZIGZIG
49#define PSPLAY_PROB_ZIGZIG 5000
51#ifndef PSPLAY_PROB_ZIGZAG
52#define PSPLAY_PROB_ZIGZAG 2500
60 static uint32_t rnd=0xbabeface;
61 return rnd = rnd<<1 ^ ((rnd >> 30) & 1) ^ ((rnd>>2) & 1);
76 self->found_parent = &self->tree;
90 PSplay self = malloc (
sizeof *self);
104 if (self)
while (self->tree)
125 self->left = self->right =
NULL;
149static inline unsigned
159 TRACE (psplay_dbg,
"%p %u", self, splayfactor);
161 if (trail->
dir < 0) trail->
dir = - trail->
dir;
170 TRACE (psplay_dbg,
"r is %u", r);
172 if (parent == grandparent->left)
174 TRACE (psplay_dbg,
"ZIG..");
175 if (node == parent->left)
177 TRACE (psplay_dbg,
"..ZIG");
180 TRACE (psplay_dbg,
"BREAK");
184 grandparent->left = parent->right;
185 parent->right = grandparent;
187 parent->left = node->right;
188 node->right = parent;
192 TRACE (psplay_dbg,
"..ZAG");
195 TRACE (psplay_dbg,
"BREAK");
199 parent->right = node->left;
202 grandparent->left = node->right;
203 node->right = grandparent;
208 TRACE (psplay_dbg,
"ZAG..");
209 if (node == parent->left)
211 TRACE (psplay_dbg,
"..ZIG");
214 TRACE (psplay_dbg,
"BREAK");
218 parent->left = node->right;
219 node->right = parent;
221 grandparent->right = node->left;
222 node->left = grandparent;
226 TRACE (psplay_dbg,
"..ZAG");
229 TRACE (psplay_dbg,
"BREAK");
233 grandparent->right = parent->left;
234 parent->left = grandparent;
236 parent->right = node->left;
254 trail.trail [0] = &self->tree;
263 c = self->cmp (self->key (node), self->key (n));
284 WARN (psplay_dbg,
"dropping duplicate entry for psplay");
291 if (self->elem_cnt >= 1UL<<self->log2) ++self->log2;
292 if (splayfactor &&
trail.depth > 2)
307 trail.trail [0] = &self->tree;
312 c = self->cmp (key, self->key (node));
333 if (node && splayfactor &&
trail.depth > 2)
343 if (!node)
return NULL;
351 WARN (psplay_dbg,
"node %p is not in splay tree %p", node, self);
354 r = self->found_parent;
359 else if (!node->right)
366 for (i = node->left; i->right; iparent = i, i = i->right);
368 iparent->right = i->left;
370 i->left = node->left;
371 i->right = node->right;
375 for (i = node->right; i->left; iparent = i, i = i->left);
377 iparent->left = i->right;
378 if (node->right != i)
379 i->right = node->right;
380 i->left = node->left;
385 if (self->elem_cnt < 1UL<<self->log2) --self->log2;
457 if (!
psplay_walk (self, node->left, action, level+1, data))
465 if (!
psplay_walk (self, node->right, action, level+1, data))
480 static char* sp =
" ";
484 fprintf (fh,
"%s ...\n", sp);
491 fprintf (fh,
"%s%p\n", sp+40-level, node);
493 fprintf (fh,
"%sleft %p\n", sp+40-level, node->left);
497 fprintf (fh,
"%sright %p\n", sp+40-level, node->right);
509 fprintf (dest,
"root %p\n", self->tree);
const_LList llist_cmpfn cmp
This header is for including and configuring NoBug.
void psplay_delete(PSplay self)
Delete a splay tree Frees all elements and associated resources of a splay tree and then itseld.
int psplay_walk(PSplay self, PSplaynode node, psplay_action_fn action, int level, void *data)
Start a tree traversal.
PSplay psplay_init(PSplay self, psplay_cmp_fn cmp, psplay_key_fn key, psplay_delete_fn del)
Initialize a splay tree.
#define PSPLAY_TRAIL_DEPTH
PSplay psplay_destroy(PSplay self)
Destroy a splay tree Frees all elements and associated resources of a splay tree.
PSplaynode psplay_insert(PSplay self, PSplaynode node, int splayfactor)
Insert a element into a splay tree.
#define PSPLAY_PROB_ZIGZAG
#define PSPLAY_PROB_ZIGZIG
const psplay_delete_fn PSPLAY_CONT
PSplay psplay_new(psplay_cmp_fn cmp, psplay_key_fn key, psplay_delete_fn del)
Allocate a splay tree.
PSplaynode psplaynode_init(PSplaynode self)
Initialise a splay tree node The user has to place this nodes within his datastructure and must Initi...
static unsigned trailidx(unsigned n)
static uint32_t psplay_fast_prng()
static psplay_delete_fn psplay_print_node(PSplaynode node, const enum psplay_order_enum which, int level, void *data)
void psplay_delete_key(PSplay self, void *key)
Delete a node by key from a splay tree.
const psplay_delete_fn PSPLAY_REMOVE
static int psplay_handle(PSplay self, PSplaynode node, psplay_delete_fn res)
const psplay_delete_fn PSPLAY_STOP
void psplay_delete_node(PSplay self, PSplaynode node)
Delete a node from a splay tree.
PSplaynode * trail[PSPLAY_TRAIL_DEPTH]
PSplaynode psplay_remove(PSplay self, PSplaynode node)
Remove a node from a splay tree.
void psplay_dump(PSplay self, FILE *dest)
static void psplay_splay(PSplay self, struct psplaytrail *trail, unsigned splayfactor)
PSplaynode psplay_find(PSplay self, const void *key, int splayfactor)
Find a element in a splay tree.
PSplaynode psplay_remove_key(PSplay self, void *key)
Remove a node by key from a splay tree.
Probabilistic splay tree.
psplay_delete_fn(* psplay_action_fn)(PSplaynode node, const enum psplay_order_enum which, int level, void *data)
Traverse a splay tree Traversing a tree calls a user supplied action three times An 'action' must not...
const void *(* psplay_key_fn)(const PSplaynode node)
Retrieve the key from a user datastructure.
void(* psplay_delete_fn)(PSplaynode node)
Destructor for user defined data Called when an element got removed from a splay tree.
int(* psplay_cmp_fn)(const void *a, const void *b)
Function use to compare keys.