Additional debugging
This commit is contained in:
parent
431fd9aa9c
commit
888569bba1
@ -4,6 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <3ds/synchronization.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
@ -21,16 +22,21 @@ typedef int (*rbtree_node_comparator_t)(const rbtree_node_t *lhs,
|
|||||||
/// An rbtree node.
|
/// An rbtree node.
|
||||||
struct rbtree_node
|
struct rbtree_node
|
||||||
{
|
{
|
||||||
|
char nodeTag[4]; ///< Node tag.
|
||||||
uintptr_t parent_color; ///< Parent color.
|
uintptr_t parent_color; ///< Parent color.
|
||||||
rbtree_node_t *child[2]; ///< Node children.
|
rbtree_node_t *child[2]; ///< Node children.
|
||||||
|
rbtree_t *tree; ///< Owning tree.
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An rbtree.
|
/// An rbtree.
|
||||||
struct rbtree
|
struct rbtree
|
||||||
{
|
{
|
||||||
|
char treeTag[4]; ///< Tree tag.
|
||||||
rbtree_node_t *root; ///< Root node.
|
rbtree_node_t *root; ///< Root node.
|
||||||
rbtree_node_comparator_t comparator; ///< Node comparator.
|
rbtree_node_comparator_t comparator; ///< Node comparator.
|
||||||
size_t size; ///< Size.
|
size_t size; ///< Size.
|
||||||
|
LightLock lock; ///< Tree mutex.
|
||||||
|
bool busy; ///< Busy flag.
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -5,27 +5,28 @@ void
|
|||||||
rbtree_clear(rbtree_t *tree,
|
rbtree_clear(rbtree_t *tree,
|
||||||
rbtree_node_destructor_t destructor)
|
rbtree_node_destructor_t destructor)
|
||||||
{
|
{
|
||||||
|
rbtree_set_busy(tree);
|
||||||
rbtree_validate(tree);
|
rbtree_validate(tree);
|
||||||
|
|
||||||
rbtree_node_t *node = tree->root;
|
rbtree_node_t *node = tree->root;
|
||||||
|
|
||||||
while(tree->root != NULL)
|
while(tree->root)
|
||||||
{
|
{
|
||||||
while(node->child[LEFT] != NULL)
|
while(node->child[LEFT])
|
||||||
node = node->child[LEFT];
|
node = node->child[LEFT];
|
||||||
|
|
||||||
if(node->child[RIGHT] != NULL)
|
if(node->child[RIGHT])
|
||||||
node = node->child[RIGHT];
|
node = node->child[RIGHT];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rbtree_node_t *parent = get_parent(node);
|
rbtree_node_t *parent = get_parent(node);
|
||||||
|
|
||||||
if(parent == NULL)
|
if(!parent)
|
||||||
tree->root = NULL;
|
tree->root = NULL;
|
||||||
else
|
else
|
||||||
parent->child[node != parent->child[LEFT]] = NULL;
|
parent->child[node != parent->child[LEFT]] = NULL;
|
||||||
|
|
||||||
if(destructor != NULL)
|
if(destructor)
|
||||||
(*destructor)(node);
|
(*destructor)(node);
|
||||||
|
|
||||||
node = parent;
|
node = parent;
|
||||||
@ -35,4 +36,5 @@ rbtree_clear(rbtree_t *tree,
|
|||||||
tree->size = 0;
|
tree->size = 0;
|
||||||
|
|
||||||
rbtree_validate(tree);
|
rbtree_validate(tree);
|
||||||
|
rbtree_clear_busy(tree);
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,11 @@
|
|||||||
int
|
int
|
||||||
rbtree_empty(const rbtree_t *tree)
|
rbtree_empty(const rbtree_t *tree)
|
||||||
{
|
{
|
||||||
|
rbtree_set_busy((rbtree_t*)tree);
|
||||||
rbtree_validate(tree);
|
rbtree_validate(tree);
|
||||||
|
|
||||||
return tree->root == NULL;
|
bool empty = !tree->root;
|
||||||
|
|
||||||
|
rbtree_clear_busy((rbtree_t*)tree);
|
||||||
|
return empty;
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,13 @@ rbtree_node_t*
|
|||||||
rbtree_find(const rbtree_t *tree,
|
rbtree_find(const rbtree_t *tree,
|
||||||
const rbtree_node_t *node)
|
const rbtree_node_t *node)
|
||||||
{
|
{
|
||||||
|
rbtree_set_busy((rbtree_t*)tree);
|
||||||
rbtree_validate(tree);
|
rbtree_validate(tree);
|
||||||
|
|
||||||
rbtree_node_t *tmp = tree->root;
|
rbtree_node_t *tmp = tree->root;
|
||||||
rbtree_node_t *save = NULL;
|
rbtree_node_t *save = NULL;
|
||||||
|
|
||||||
while(tmp != NULL)
|
while(tmp)
|
||||||
{
|
{
|
||||||
int rc = (*tree->comparator)(node, tmp);
|
int rc = (*tree->comparator)(node, tmp);
|
||||||
if(rc < 0)
|
if(rc < 0)
|
||||||
@ -29,6 +30,7 @@ rbtree_find(const rbtree_t *tree,
|
|||||||
}
|
}
|
||||||
|
|
||||||
rbtree_validate(tree);
|
rbtree_validate(tree);
|
||||||
|
rbtree_clear_busy((rbtree_t*)tree);
|
||||||
|
|
||||||
return save;
|
return save;
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,15 @@ void
|
|||||||
rbtree_init(rbtree_t *tree,
|
rbtree_init(rbtree_t *tree,
|
||||||
rbtree_node_comparator_t comparator)
|
rbtree_node_comparator_t comparator)
|
||||||
{
|
{
|
||||||
|
tree->treeTag[3] = 'T';
|
||||||
|
tree->treeTag[2] = 'R';
|
||||||
|
tree->treeTag[1] = 'E';
|
||||||
|
tree->treeTag[0] = 'E';
|
||||||
tree->root = NULL;
|
tree->root = NULL;
|
||||||
tree->comparator = comparator;
|
tree->comparator = comparator;
|
||||||
tree->size = 0;
|
tree->size = 0;
|
||||||
|
tree->busy = false;
|
||||||
|
LightLock_Init(&tree->lock);
|
||||||
|
|
||||||
rbtree_validate(tree);
|
rbtree_validate(tree);
|
||||||
}
|
}
|
||||||
|
@ -6,14 +6,24 @@ do_insert(rbtree_t *tree,
|
|||||||
rbtree_node_t *node,
|
rbtree_node_t *node,
|
||||||
int multi)
|
int multi)
|
||||||
{
|
{
|
||||||
|
rbtree_set_busy(tree);
|
||||||
rbtree_validate(tree);
|
rbtree_validate(tree);
|
||||||
|
|
||||||
|
node->nodeTag[3] = 'N';
|
||||||
|
node->nodeTag[2] = 'O';
|
||||||
|
node->nodeTag[1] = 'D';
|
||||||
|
node->nodeTag[0] = 'E';
|
||||||
|
node->parent_color = 0;
|
||||||
|
node->child[LEFT] = NULL;
|
||||||
|
node->child[RIGHT] = NULL;
|
||||||
|
node->tree = tree;
|
||||||
|
|
||||||
rbtree_node_t *original = node;
|
rbtree_node_t *original = node;
|
||||||
rbtree_node_t **tmp = &tree->root;
|
rbtree_node_t **tmp = &tree->root;
|
||||||
rbtree_node_t *parent = NULL;
|
rbtree_node_t *parent = NULL;
|
||||||
rbtree_node_t *save = NULL;
|
rbtree_node_t *save = NULL;
|
||||||
|
|
||||||
while(*tmp != NULL)
|
while(*tmp)
|
||||||
{
|
{
|
||||||
int cmp = (*(tree->comparator))(node, *tmp);
|
int cmp = (*(tree->comparator))(node, *tmp);
|
||||||
parent = *tmp;
|
parent = *tmp;
|
||||||
@ -31,9 +41,19 @@ do_insert(rbtree_t *tree,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(save != NULL)
|
if(save)
|
||||||
{
|
{
|
||||||
|
node->nodeTag[3] = 'D';
|
||||||
|
node->nodeTag[2] = 'O';
|
||||||
|
node->nodeTag[1] = 'N';
|
||||||
|
node->nodeTag[0] = 'E';
|
||||||
|
node->parent_color = 0;
|
||||||
|
node->child[LEFT] = NULL;
|
||||||
|
node->child[RIGHT] = NULL;
|
||||||
|
node->tree = NULL;
|
||||||
|
|
||||||
rbtree_validate(tree);
|
rbtree_validate(tree);
|
||||||
|
rbtree_clear_busy(tree);
|
||||||
|
|
||||||
return save;
|
return save;
|
||||||
}
|
}
|
||||||
@ -83,6 +103,7 @@ do_insert(rbtree_t *tree,
|
|||||||
tree->size += 1;
|
tree->size += 1;
|
||||||
|
|
||||||
rbtree_validate(tree);
|
rbtree_validate(tree);
|
||||||
|
rbtree_clear_busy(tree);
|
||||||
|
|
||||||
return original;
|
return original;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ set_red(rbtree_node_t *node)
|
|||||||
static inline rbtree_color_t
|
static inline rbtree_color_t
|
||||||
get_color(const rbtree_node_t *node)
|
get_color(const rbtree_node_t *node)
|
||||||
{
|
{
|
||||||
if(node == NULL)
|
if(!node)
|
||||||
return BLACK;
|
return BLACK;
|
||||||
return (rbtree_color_t)(node->parent_color & COLOR_MASK);
|
return (rbtree_color_t)(node->parent_color & COLOR_MASK);
|
||||||
}
|
}
|
||||||
@ -59,6 +59,12 @@ set_parent(rbtree_node_t *node,
|
|||||||
node->parent_color = (get_color(node)) | ((uintptr_t)parent);
|
node->parent_color = (get_color(node)) | ((uintptr_t)parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rbtree_set_busy(rbtree_t *tree);
|
||||||
|
|
||||||
|
void
|
||||||
|
rbtree_clear_busy(rbtree_t *tree);
|
||||||
|
|
||||||
void
|
void
|
||||||
rbtree_rotate(rbtree_t *tree,
|
rbtree_rotate(rbtree_t *tree,
|
||||||
rbtree_node_t *node,
|
rbtree_node_t *node,
|
||||||
|
@ -7,16 +7,16 @@ do_iterate(const rbtree_node_t *node,
|
|||||||
{
|
{
|
||||||
rbtree_node_t *it = (rbtree_node_t*)node;
|
rbtree_node_t *it = (rbtree_node_t*)node;
|
||||||
|
|
||||||
if(it->child[next] != NULL)
|
if(it->child[next])
|
||||||
{
|
{
|
||||||
it = it->child[next];
|
it = it->child[next];
|
||||||
while(it->child[!next] != NULL)
|
while(it->child[!next])
|
||||||
it = it->child[!next];
|
it = it->child[!next];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rbtree_node_t *parent = get_parent(node);
|
rbtree_node_t *parent = get_parent(node);
|
||||||
while(parent != NULL && it == parent->child[next])
|
while(parent && it == parent->child[next])
|
||||||
{
|
{
|
||||||
it = parent;
|
it = parent;
|
||||||
parent = get_parent(it);
|
parent = get_parent(it);
|
||||||
|
@ -5,35 +5,32 @@ static inline rbtree_node_t*
|
|||||||
do_minmax(const rbtree_t *tree,
|
do_minmax(const rbtree_t *tree,
|
||||||
int max)
|
int max)
|
||||||
{
|
{
|
||||||
|
rbtree_set_busy((rbtree_t*)tree);
|
||||||
rbtree_validate(tree);
|
rbtree_validate(tree);
|
||||||
|
|
||||||
rbtree_node_t *node = tree->root;
|
rbtree_node_t *node = tree->root;
|
||||||
|
|
||||||
if(node == NULL)
|
if(!node)
|
||||||
|
{
|
||||||
|
rbtree_clear_busy((rbtree_t*)tree);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
while(node->child[max] != NULL)
|
while(node->child[max])
|
||||||
node = node->child[max];
|
node = node->child[max];
|
||||||
|
|
||||||
|
rbtree_clear_busy((rbtree_t*)tree);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
rbtree_node_t*
|
rbtree_node_t*
|
||||||
rbtree_min(const rbtree_t *tree)
|
rbtree_min(const rbtree_t *tree)
|
||||||
{
|
{
|
||||||
rbtree_node_t *node;
|
return do_minmax(tree, LEFT);
|
||||||
|
|
||||||
node = do_minmax(tree, LEFT);
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rbtree_node_t*
|
rbtree_node_t*
|
||||||
rbtree_max(const rbtree_t *tree)
|
rbtree_max(const rbtree_t *tree)
|
||||||
{
|
{
|
||||||
rbtree_node_t *node;
|
return do_minmax(tree, RIGHT);
|
||||||
|
|
||||||
node = do_minmax(tree, RIGHT);
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
}
|
||||||
|
@ -51,15 +51,37 @@ recolor(rbtree_t *tree,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(node != NULL)
|
if(node)
|
||||||
set_black(node);
|
set_black(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
in_tree(const rbtree_t *tree,
|
||||||
|
const rbtree_node_t *node)
|
||||||
|
{
|
||||||
|
if(tree->root == node)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
const rbtree_node_t *parent = get_parent(node);
|
||||||
|
while(parent)
|
||||||
|
{
|
||||||
|
if(tree->root == parent)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
parent = get_parent(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
rbtree_node_t*
|
rbtree_node_t*
|
||||||
rbtree_remove(rbtree_t *tree,
|
rbtree_remove(rbtree_t *tree,
|
||||||
rbtree_node_t *node,
|
rbtree_node_t *node,
|
||||||
rbtree_node_destructor_t destructor)
|
rbtree_node_destructor_t destructor)
|
||||||
{
|
{
|
||||||
|
rbtree_set_busy(tree);
|
||||||
|
if(!in_tree(tree, node))
|
||||||
|
svcBreak(USERBREAK_PANIC);
|
||||||
rbtree_validate(tree);
|
rbtree_validate(tree);
|
||||||
|
|
||||||
rbtree_color_t color;
|
rbtree_color_t color;
|
||||||
@ -68,16 +90,16 @@ rbtree_remove(rbtree_t *tree,
|
|||||||
|
|
||||||
next = rbtree_node_next(node);
|
next = rbtree_node_next(node);
|
||||||
|
|
||||||
if(node->child[LEFT] != NULL && node->child[RIGHT] != NULL)
|
if(node->child[LEFT] && node->child[RIGHT])
|
||||||
{
|
{
|
||||||
rbtree_node_t *old = node;
|
rbtree_node_t *old = node;
|
||||||
|
|
||||||
node = node->child[RIGHT];
|
node = node->child[RIGHT];
|
||||||
while(node->child[LEFT] != NULL)
|
while(node->child[LEFT])
|
||||||
node = node->child[LEFT];
|
node = node->child[LEFT];
|
||||||
|
|
||||||
parent = get_parent(old);
|
parent = get_parent(old);
|
||||||
if(parent != NULL)
|
if(parent)
|
||||||
{
|
{
|
||||||
if(parent->child[LEFT] == old)
|
if(parent->child[LEFT] == old)
|
||||||
parent->child[LEFT] = node;
|
parent->child[LEFT] = node;
|
||||||
@ -95,7 +117,7 @@ rbtree_remove(rbtree_t *tree,
|
|||||||
parent = node;
|
parent = node;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(child != NULL)
|
if(child)
|
||||||
set_parent(child, parent);
|
set_parent(child, parent);
|
||||||
parent->child[LEFT] = child;
|
parent->child[LEFT] = child;
|
||||||
|
|
||||||
@ -109,7 +131,7 @@ rbtree_remove(rbtree_t *tree,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(node->child[LEFT] == NULL)
|
if(!node->child[LEFT])
|
||||||
child = node->child[RIGHT];
|
child = node->child[RIGHT];
|
||||||
else
|
else
|
||||||
child = node->child[LEFT];
|
child = node->child[LEFT];
|
||||||
@ -117,9 +139,9 @@ rbtree_remove(rbtree_t *tree,
|
|||||||
parent = get_parent(node);
|
parent = get_parent(node);
|
||||||
color = get_color(node);
|
color = get_color(node);
|
||||||
|
|
||||||
if(child != NULL)
|
if(child)
|
||||||
set_parent(child, parent);
|
set_parent(child, parent);
|
||||||
if(parent != NULL)
|
if(parent)
|
||||||
{
|
{
|
||||||
if(parent->child[LEFT] == node)
|
if(parent->child[LEFT] == node)
|
||||||
parent->child[LEFT] = child;
|
parent->child[LEFT] = child;
|
||||||
@ -133,12 +155,22 @@ rbtree_remove(rbtree_t *tree,
|
|||||||
if(color == BLACK)
|
if(color == BLACK)
|
||||||
recolor(tree, parent, child);
|
recolor(tree, parent, child);
|
||||||
|
|
||||||
if(destructor != NULL)
|
original->nodeTag[3] = 'D';
|
||||||
|
original->nodeTag[2] = 'O';
|
||||||
|
original->nodeTag[1] = 'N';
|
||||||
|
original->nodeTag[0] = 'E';
|
||||||
|
original->parent_color = 0;
|
||||||
|
original->child[LEFT] = NULL;
|
||||||
|
original->child[RIGHT] = NULL;
|
||||||
|
original->tree = NULL;
|
||||||
|
|
||||||
|
if(destructor)
|
||||||
(*destructor)(original);
|
(*destructor)(original);
|
||||||
|
|
||||||
tree->size -= 1;
|
tree->size -= 1;
|
||||||
|
|
||||||
rbtree_validate(tree);
|
rbtree_validate(tree);
|
||||||
|
rbtree_clear_busy(tree);
|
||||||
|
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
@ -10,12 +10,12 @@ rbtree_rotate(rbtree_t *tree,
|
|||||||
rbtree_node_t *parent = get_parent(node);
|
rbtree_node_t *parent = get_parent(node);
|
||||||
|
|
||||||
node->child[left] = tmp->child[!left];
|
node->child[left] = tmp->child[!left];
|
||||||
if(tmp->child[!left] != NULL)
|
if(tmp->child[!left])
|
||||||
set_parent(tmp->child[!left], node);
|
set_parent(tmp->child[!left], node);
|
||||||
|
|
||||||
tmp->child[!left] = node;
|
tmp->child[!left] = node;
|
||||||
set_parent(tmp, parent);
|
set_parent(tmp, parent);
|
||||||
if(parent != NULL)
|
if(parent)
|
||||||
{
|
{
|
||||||
if(node == parent->child[!left])
|
if(node == parent->child[!left])
|
||||||
parent->child[!left] = tmp;
|
parent->child[!left] = tmp;
|
||||||
|
@ -4,7 +4,11 @@
|
|||||||
size_t
|
size_t
|
||||||
rbtree_size(const rbtree_t *tree)
|
rbtree_size(const rbtree_t *tree)
|
||||||
{
|
{
|
||||||
|
rbtree_set_busy((rbtree_t*)tree);
|
||||||
rbtree_validate(tree);
|
rbtree_validate(tree);
|
||||||
|
|
||||||
return tree->size;
|
size_t size = tree->size;
|
||||||
|
|
||||||
|
rbtree_clear_busy((rbtree_t*)tree);
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
abort(); \
|
abort(); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
rbtree_validate(const rbtree_t *tree)
|
rbtree_validate(const rbtree_t *tree)
|
||||||
{
|
{
|
||||||
@ -23,7 +22,7 @@ rbtree_validate(const rbtree_t *tree)
|
|||||||
// root node's parent must be null
|
// root node's parent must be null
|
||||||
if(tree->root)
|
if(tree->root)
|
||||||
{
|
{
|
||||||
if(get_parent(tree->root) != NULL)
|
if(get_parent(tree->root))
|
||||||
panic();
|
panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +41,7 @@ rbtree_node_validate(const rbtree_t *tree, const rbtree_node_t *node, size_t *si
|
|||||||
if(!node) // implies is_black
|
if(!node) // implies is_black
|
||||||
{
|
{
|
||||||
if(black)
|
if(black)
|
||||||
*black += 1;
|
*black = 1;
|
||||||
|
|
||||||
if(depth)
|
if(depth)
|
||||||
*depth = 1;
|
*depth = 1;
|
||||||
@ -108,14 +107,14 @@ rbtree_node_validate(const rbtree_t *tree, const rbtree_node_t *node, size_t *si
|
|||||||
|
|
||||||
// size is left+right subtrees plus self
|
// size is left+right subtrees plus self
|
||||||
if(size)
|
if(size)
|
||||||
*size += left_size + right_size + 1;
|
*size = left_size + right_size + 1;
|
||||||
|
|
||||||
// all possible paths to leaf nodes must have the same number of black nodes along the path
|
// all possible paths to leaf nodes must have the same number of black nodes along the path
|
||||||
if(left_black != right_black)
|
if(left_black != right_black)
|
||||||
panic();
|
panic();
|
||||||
|
|
||||||
if(black)
|
if(black)
|
||||||
*black += left_black + (is_black(node) ? 1 : 0);
|
*black = left_black + (is_black(node) ? 1 : 0);
|
||||||
|
|
||||||
// depth of one subtree must not exceed 2x depth of the other subtree
|
// depth of one subtree must not exceed 2x depth of the other subtree
|
||||||
if(left_depth < right_depth)
|
if(left_depth < right_depth)
|
||||||
@ -134,3 +133,25 @@ rbtree_node_validate(const rbtree_t *tree, const rbtree_node_t *node, size_t *si
|
|||||||
*depth = right_depth + 1;
|
*depth = right_depth + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rbtree_set_busy(rbtree_t *tree)
|
||||||
|
{
|
||||||
|
LightLock_Lock(&tree->lock);
|
||||||
|
if(tree->busy)
|
||||||
|
panic();
|
||||||
|
|
||||||
|
tree->busy = true;
|
||||||
|
LightLock_Unlock(&tree->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rbtree_clear_busy(rbtree_t *tree)
|
||||||
|
{
|
||||||
|
LightLock_Lock(&tree->lock);
|
||||||
|
if(!tree->busy)
|
||||||
|
panic();
|
||||||
|
|
||||||
|
tree->busy = false;
|
||||||
|
LightLock_Unlock(&tree->lock);
|
||||||
|
}
|
||||||
|
@ -111,7 +111,8 @@ int main(int argc, char *argv[])
|
|||||||
else
|
else
|
||||||
nodes.emplace_back(node);
|
nodes.emplace_back(node);
|
||||||
|
|
||||||
if(remove() < chance)
|
// remove random node
|
||||||
|
if(remove() <= chance)
|
||||||
{
|
{
|
||||||
auto it = std::begin(nodes) + (eng() % nodes.size());
|
auto it = std::begin(nodes) + (eng() % nodes.size());
|
||||||
rbtree_remove(&tree, &(*it)->node, IntNodeDestructor);
|
rbtree_remove(&tree, &(*it)->node, IntNodeDestructor);
|
||||||
@ -122,5 +123,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::printf("Ended with %zu nodes in tree\n", rbtree_size(&tree));
|
||||||
|
|
||||||
rbtree_clear(&tree, IntNodeDestructor);
|
rbtree_clear(&tree, IntNodeDestructor);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user