patch 4.0
This commit is contained in:
245
deps/oblib/unittest/lib/container/test_rbtree.cpp
vendored
245
deps/oblib/unittest/lib/container/test_rbtree.cpp
vendored
@ -17,8 +17,10 @@
|
||||
#include "lib/container/ob_rbtree.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace container {
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace container
|
||||
{
|
||||
|
||||
#ifndef UNUSED
|
||||
#define UNUSED(v) ((void)(v))
|
||||
@ -26,13 +28,14 @@ namespace container {
|
||||
|
||||
typedef struct node_s node_t;
|
||||
|
||||
struct node_s {
|
||||
struct node_s
|
||||
{
|
||||
#define NODE_MAGIC 0x9823af7e
|
||||
int magic;
|
||||
RBNODE(node_t, rblink);
|
||||
int key;
|
||||
|
||||
inline int compare(const node_s* node) const
|
||||
inline int compare(const node_s *node) const
|
||||
{
|
||||
int ret = 0;
|
||||
EXPECT_EQ(this->magic, NODE_MAGIC);
|
||||
@ -43,7 +46,8 @@ struct node_s {
|
||||
* Duplicates are not allowed in the tree, so force an
|
||||
* arbitrary ordering for non-identical items with equal keys.
|
||||
*/
|
||||
ret = (((uintptr_t)this) > ((uintptr_t)node)) - (((uintptr_t)this) < ((uintptr_t)node));
|
||||
ret = (((uintptr_t)this) > ((uintptr_t)node))
|
||||
- (((uintptr_t)this) < ((uintptr_t)node));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -51,10 +55,10 @@ struct node_s {
|
||||
|
||||
typedef ObRbTree<node_t, ObDummyCompHelper<node_t>> tree_t;
|
||||
|
||||
TEST(TestRbTree, empty)
|
||||
TEST (TestRbTree, empty)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
node_t* r_node = NULL;
|
||||
node_t *r_node = NULL;
|
||||
tree_t tree;
|
||||
node_t key;
|
||||
tree.init_tree();
|
||||
@ -105,11 +109,12 @@ TEST(TestRbTree, empty)
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned tree_recurse(node_t* node, uint64_t black_height, unsigned black_depth, tree_t& rbtree)
|
||||
static unsigned tree_recurse(node_t *node, uint64_t black_height,
|
||||
unsigned black_depth, tree_t &rbtree)
|
||||
{
|
||||
unsigned ret = 0;
|
||||
node_t* left_node = NULL;
|
||||
node_t* right_node = NULL;
|
||||
node_t *left_node = NULL;
|
||||
node_t *right_node = NULL;
|
||||
|
||||
if (node == NULL) {
|
||||
return ret;
|
||||
@ -137,24 +142,24 @@ static unsigned tree_recurse(node_t* node, uint64_t black_height, unsigned black
|
||||
|
||||
/* Left subtree. */
|
||||
if (left_node != NULL) {
|
||||
ret += tree_recurse(left_node, black_height, black_depth, rbtree);
|
||||
ret += tree_recurse(left_node, black_height, black_depth, rbtree);
|
||||
} else {
|
||||
ret += (black_depth != black_height);
|
||||
ret += (black_depth != black_height);
|
||||
}
|
||||
|
||||
/* Right subtree. */
|
||||
if (right_node != NULL) {
|
||||
ret += tree_recurse(right_node, black_height, black_depth, rbtree);
|
||||
ret += tree_recurse(right_node, black_height, black_depth, rbtree);
|
||||
} else {
|
||||
ret += (black_depth != black_height);
|
||||
ret += (black_depth != black_height);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static node_t* tree_iterate_cb(tree_t* tree, node_t* node, void* data)
|
||||
static node_t *tree_iterate_cb(tree_t *tree, node_t *node, void *data)
|
||||
{
|
||||
unsigned* i = (unsigned*)data;
|
||||
node_t* search_node = NULL;
|
||||
unsigned *i = (unsigned *)data;
|
||||
node_t *search_node = NULL;
|
||||
int ret = OB_SUCCESS;
|
||||
EXPECT_EQ(node->magic, NODE_MAGIC);
|
||||
|
||||
@ -170,42 +175,42 @@ static node_t* tree_iterate_cb(tree_t* tree, node_t* node, void* data)
|
||||
/* Test rb_nsearch(). */
|
||||
ret = tree->nsearch(node, search_node);
|
||||
if (OB_FAIL(ret)) {
|
||||
fprintf(stderr, "red black tree nsearch fail %d", ret);
|
||||
EXPECT_EQ(ret, OB_SUCCESS);
|
||||
} else {
|
||||
EXPECT_EQ(node, search_node);
|
||||
}
|
||||
fprintf(stderr, "red black tree nsearch fail %d", ret);
|
||||
EXPECT_EQ(ret, OB_SUCCESS);
|
||||
} else {
|
||||
EXPECT_EQ(node, search_node);
|
||||
}
|
||||
|
||||
/* Test rb_psearch(). */
|
||||
ret = tree->psearch(node, search_node);
|
||||
ret = tree->psearch( node, search_node);
|
||||
if (OB_FAIL(ret)) {
|
||||
fprintf(stderr, "red black tree psearch fail %d", ret);
|
||||
EXPECT_EQ(ret, OB_SUCCESS);
|
||||
} else {
|
||||
EXPECT_EQ(node, search_node);
|
||||
}
|
||||
EXPECT_EQ(ret, OB_SUCCESS);
|
||||
} else {
|
||||
EXPECT_EQ(node, search_node);
|
||||
}
|
||||
(*i)++;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static unsigned tree_iterate(tree_t* tree)
|
||||
static unsigned tree_iterate(tree_t *tree)
|
||||
{
|
||||
unsigned i = 0;
|
||||
tree->iter_rbtree(tree, NULL, tree_iterate_cb, (void*)&i);
|
||||
tree->iter_rbtree(tree, NULL, tree_iterate_cb, (void *)&i);
|
||||
return i;
|
||||
}
|
||||
|
||||
static unsigned tree_iterate_reverse(tree_t* tree)
|
||||
static unsigned tree_iterate_reverse(tree_t *tree)
|
||||
{
|
||||
unsigned i = 0;
|
||||
tree->reverse_iter_rbtree(tree, NULL, tree_iterate_cb, (void*)&i);
|
||||
tree->reverse_iter_rbtree(tree, NULL, tree_iterate_cb, (void *)&i);
|
||||
return i;
|
||||
}
|
||||
|
||||
static void node_remove(tree_t* tree, node_t* node, unsigned nnodes)
|
||||
static void node_remove(tree_t *tree, node_t *node, unsigned nnodes)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
node_t* search_node = NULL;
|
||||
node_t *search_node = NULL;
|
||||
uint64_t black_height = 0;
|
||||
unsigned imbalances = 0;
|
||||
|
||||
@ -228,7 +233,7 @@ static void node_remove(tree_t* tree, node_t* node, unsigned nnodes)
|
||||
}
|
||||
|
||||
/* Test rb_psearch(). */
|
||||
ret = tree->psearch(node, search_node);
|
||||
ret = tree->psearch(node,search_node);
|
||||
if (OB_FAIL(ret)) {
|
||||
fprintf(stderr, "red tree psearch fail %d", ret);
|
||||
EXPECT_EQ(ret, OB_SUCCESS);
|
||||
@ -249,11 +254,11 @@ static void node_remove(tree_t* tree, node_t* node, unsigned nnodes)
|
||||
EXPECT_EQ(count, nnodes - 1);
|
||||
}
|
||||
|
||||
static node_t* remove_iterate_cb(tree_t* tree, node_t* node, void* data)
|
||||
static node_t *remove_iterate_cb(tree_t *tree, node_t *node, void *data)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
node_t* tmp_node = NULL;
|
||||
unsigned* nnodes = (unsigned*)data;
|
||||
node_t *tmp_node = NULL;
|
||||
unsigned *nnodes = (unsigned *)data;
|
||||
ret = tree->get_next(node, tmp_node);
|
||||
if (OB_FAIL(ret)) {
|
||||
fprintf(stderr, "red black tree get next fail %d", ret);
|
||||
@ -265,11 +270,10 @@ static node_t* remove_iterate_cb(tree_t* tree, node_t* node, void* data)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static node_t* remove_reverse_iterate_cb(tree_t* tree, node_t* node, void* data)
|
||||
{
|
||||
static node_t *remove_reverse_iterate_cb(tree_t *tree, node_t *node, void *data) {
|
||||
int ret = OB_SUCCESS;
|
||||
node_t* tmp_node = NULL;
|
||||
unsigned* nnodes = (unsigned*)data;
|
||||
node_t *tmp_node = NULL;
|
||||
unsigned *nnodes = (unsigned *)data;
|
||||
ret = tree->get_prev(node, tmp_node);
|
||||
if (OB_FAIL(ret)) {
|
||||
fprintf(stderr, "red black tree get prev fail %d", ret);
|
||||
@ -283,15 +287,14 @@ static node_t* remove_reverse_iterate_cb(tree_t* tree, node_t* node, void* data)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void destroy_cb(node_t* node, void* data)
|
||||
{
|
||||
static void destroy_cb(node_t *node , void *data) {
|
||||
UNUSED(node);
|
||||
unsigned* nnodes = (unsigned*)data;
|
||||
unsigned *nnodes = (unsigned *)data;
|
||||
assert(*nnodes > 0);
|
||||
(*nnodes)--;
|
||||
}
|
||||
|
||||
TEST(TestRbTree, random)
|
||||
TEST (TestRbTree, random)
|
||||
{
|
||||
#define NNODES 25
|
||||
#define NBAGS 250
|
||||
@ -306,37 +309,37 @@ TEST(TestRbTree, random)
|
||||
i = 2;
|
||||
int tmp = 0;
|
||||
bool test_bool = false;
|
||||
node_t* tmp_node = NULL;
|
||||
node_t* pre_node = NULL;
|
||||
node_t *tmp_node = NULL;
|
||||
node_t *pre_node = NULL;
|
||||
UNUSED(pre_node);
|
||||
for (i = 0; i < NBAGS; i++) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
/* Insert in order. */
|
||||
for (j = 0; j < NNODES; j++) {
|
||||
bag[j] = j;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
/* Insert in reverse order. */
|
||||
for (j = 0; j < NNODES; j++) {
|
||||
bag[j] = NNODES - j - 1;
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
// cout <<"Enter default"<<endl;
|
||||
for (j = 0; j < NNODES; j++) {
|
||||
bag[j] = rand() % 100;
|
||||
}
|
||||
}
|
||||
case 0:
|
||||
/* Insert in order. */
|
||||
for (j = 0; j < NNODES; j++) {
|
||||
bag[j] = j;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
/* Insert in reverse order. */
|
||||
for (j = 0; j < NNODES; j++) {
|
||||
bag[j] = NNODES - j - 1;
|
||||
}
|
||||
break;
|
||||
default:{
|
||||
//cout <<"Enter default"<<endl;
|
||||
for (j = 0; j < NNODES; j++) {
|
||||
bag[j] = rand()%100;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 1; j <= NNODES; j++) {
|
||||
/* Initialize tree and nodes. */
|
||||
/* Initialize tree and nodes. */
|
||||
tree.init_tree();
|
||||
for (k = 0; k < j; k++) {
|
||||
nodes[k].magic = NODE_MAGIC;
|
||||
nodes[k].key = bag[k];
|
||||
nodes[k].magic = NODE_MAGIC;
|
||||
nodes[k].key = bag[k];
|
||||
}
|
||||
|
||||
/* Insert nodes. */
|
||||
@ -345,13 +348,14 @@ TEST(TestRbTree, random)
|
||||
EXPECT_EQ(ret, OB_SUCCESS);
|
||||
black_height = tree.get_black_height(&tree);
|
||||
|
||||
imbalances = tree_recurse(tree.get_root(), black_height, 0, tree);
|
||||
imbalances = tree_recurse(tree.get_root(),
|
||||
black_height, 0, tree);
|
||||
EXPECT_EQ(imbalances, 0);
|
||||
|
||||
tmp = tree_iterate(&tree);
|
||||
EXPECT_EQ(tmp, k + 1);
|
||||
EXPECT_EQ(tmp, k+1);
|
||||
tmp = tree_iterate_reverse(&tree);
|
||||
EXPECT_EQ(tmp, k + 1);
|
||||
EXPECT_EQ(tmp, k+1);
|
||||
|
||||
test_bool = tree.is_empty();
|
||||
EXPECT_EQ(test_bool, false);
|
||||
@ -367,57 +371,57 @@ TEST(TestRbTree, random)
|
||||
if (OB_FAIL(ret)) {
|
||||
fprintf(stderr, "red black tree get last fail %d", ret);
|
||||
EXPECT_EQ(ret, OB_SUCCESS);
|
||||
} else {
|
||||
ASSERT_TRUE(tmp_node != NULL);
|
||||
}
|
||||
ret = tree.get_next(&nodes[k], tmp_node);
|
||||
EXPECT_EQ(ret, OB_SUCCESS);
|
||||
} else {
|
||||
ASSERT_TRUE(tmp_node != NULL);
|
||||
}
|
||||
ret = tree.get_next(&nodes[k],tmp_node);
|
||||
EXPECT_EQ(ret, OB_SUCCESS);
|
||||
|
||||
ret = tree.get_prev(&nodes[k], tmp_node);
|
||||
EXPECT_EQ(ret, OB_SUCCESS);
|
||||
ret = tree.get_prev(&nodes[k],tmp_node);
|
||||
EXPECT_EQ(ret, OB_SUCCESS);
|
||||
}
|
||||
|
||||
switch (i % 5) {
|
||||
case 0:
|
||||
for (k = 0; k < j; k++) {
|
||||
node_remove(&tree, &nodes[k], j - k);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
for (k = j; k > 0; k--) {
|
||||
node_remove(&tree, &nodes[k - 1], k);
|
||||
}
|
||||
break;
|
||||
case 2: {
|
||||
node_t* start = NULL;
|
||||
unsigned nnodes = j;
|
||||
case 0:
|
||||
for (k = 0; k < j; k++) {
|
||||
node_remove(&tree,&nodes[k],j-k);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
for (k = j;k > 0; k--) {
|
||||
node_remove(&tree, &nodes[k-1],k);
|
||||
}
|
||||
break;
|
||||
case 2: {
|
||||
node_t *start = NULL;
|
||||
unsigned nnodes = j;
|
||||
|
||||
start = NULL;
|
||||
do {
|
||||
start = tree.iter_rbtree(&tree, start, remove_iterate_cb, (void*)&nnodes);
|
||||
nnodes--;
|
||||
} while (start != NULL);
|
||||
assert(nnodes == 0);
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
node_t* start = NULL;
|
||||
unsigned nnodes = j;
|
||||
do {
|
||||
start = tree.reverse_iter_rbtree(&tree, start, remove_reverse_iterate_cb, (void*)&nnodes);
|
||||
nnodes--;
|
||||
} while (start != NULL);
|
||||
assert(nnodes == 0);
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
unsigned nnodes = j;
|
||||
tree.destroy(&tree, destroy_cb, &nnodes);
|
||||
assert(nnodes == 0);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
start = NULL;
|
||||
do {
|
||||
start = tree.iter_rbtree(&tree, start,
|
||||
remove_iterate_cb, (void *)&nnodes);
|
||||
nnodes--;
|
||||
} while (start != NULL);
|
||||
assert(nnodes == 0);
|
||||
break;
|
||||
} case 3: {
|
||||
node_t *start = NULL;
|
||||
unsigned nnodes = j;
|
||||
do {
|
||||
start = tree.reverse_iter_rbtree(&tree, start,
|
||||
remove_reverse_iterate_cb,
|
||||
(void *)&nnodes);
|
||||
nnodes--;
|
||||
} while (start != NULL);
|
||||
assert(nnodes == 0);
|
||||
break;
|
||||
} case 4: {
|
||||
unsigned nnodes = j;
|
||||
tree.destroy(&tree, destroy_cb, &nnodes);
|
||||
assert(nnodes == 0);
|
||||
break;
|
||||
} default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -426,11 +430,10 @@ TEST(TestRbTree, random)
|
||||
#undef SEED
|
||||
}
|
||||
|
||||
} // namespace container
|
||||
} // namespace oceanbase
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int main(int argc, char **argv) {
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user