0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <stdio.h>
0015 #include <stdlib.h>
0016 #include <cgreen/cgreen.h>
0017 #include <ndrstandard.h>
0018 #include <string.h>
0019 #include <unistd.h>
0020 #include "ndebug.h"
0021 #include <rbtree.h>
0022
0023 int M_size;
0024 int M_delSize;
0025
0026
0027
0028
0029 typedef struct ndrx_int_RBTree_Node
0030 {
0031 ndrx_rbt_node_t rbtnode;
0032 int key;
0033 } ndrx_int_RBTree_Node_t;
0034
0035
0036
0037
0038
0039
0040 static int ndrx_irbt_cmp(const ndrx_rbt_node_t *a, const ndrx_rbt_node_t *b, void *arg)
0041 {
0042 const ndrx_int_RBTree_Node_t *ea = (const ndrx_int_RBTree_Node_t *) a;
0043 const ndrx_int_RBTree_Node_t *eb = (const ndrx_int_RBTree_Node_t *) b;
0044
0045 return ea->key - eb->key;
0046 }
0047
0048
0049
0050
0051
0052 static void ndrx_irbt_combine(ndrx_rbt_node_t *existing, const ndrx_rbt_node_t *newdata, void *arg)
0053 {
0054 const ndrx_int_RBTree_Node_t *eexist = (const ndrx_int_RBTree_Node_t *) existing;
0055 const ndrx_int_RBTree_Node_t *enew = (const ndrx_int_RBTree_Node_t *) newdata;
0056
0057 assert_equal(eexist->key, enew->key);
0058
0059
0060 NDRX_FPFREE((void*)newdata);
0061
0062
0063
0064
0065
0066
0067
0068
0069 }
0070
0071
0072 static ndrx_rbt_node_t *ndrx_irbt_alloc(void *arg)
0073 {
0074 return (ndrx_rbt_node_t *) NDRX_FPMALLOC(sizeof(ndrx_int_RBTree_Node_t), 0);
0075 }
0076
0077
0078 static void ndrx_irbt_free(ndrx_rbt_node_t *node, void *arg)
0079 {
0080 NDRX_FPFREE(node);
0081 }
0082
0083
0084
0085
0086 static ndrx_rbt_tree_t *ndrx_create_int_rbtree(void)
0087 {
0088 return ndrx_rbt_create(ndrx_irbt_cmp,
0089 ndrx_irbt_combine,
0090 ndrx_irbt_free,
0091 NULL);
0092 }
0093
0094
0095
0096
0097 static int *ndrx_GetPermutation(int size)
0098 {
0099 int *permutation;
0100 int i;
0101
0102 permutation = (int *) NDRX_FPMALLOC(size * sizeof(int), 0);
0103
0104 permutation[0] = 0;
0105
0106
0107
0108
0109
0110
0111
0112
0113 for (i = 1; i < size; i++)
0114 {
0115 int j = ndrx_rand() % (i + 1);
0116
0117 if (j < i)
0118 permutation[i] = permutation[j];
0119
0120 permutation[j] = i;
0121 }
0122
0123 return permutation;
0124 }
0125
0126
0127
0128
0129
0130 static void ndrx_rbt_populate(ndrx_rbt_tree_t *tree, int size, int step)
0131 {
0132 int *permutation = ndrx_GetPermutation(size);
0133 ndrx_int_RBTree_Node_t *node;
0134 int isNew = EXFALSE;
0135 int i;
0136 int isOk = EXTRUE;
0137
0138
0139 for (i = 0; i < size; i++)
0140 {
0141 node=(ndrx_int_RBTree_Node_t *)ndrx_irbt_alloc(NULL);
0142 assert_not_equal(node, NULL);
0143 node->key = step * permutation[i];
0144 ndrx_rbt_insert(tree, (ndrx_rbt_node_t *) node, &isNew);
0145 if (!isNew){
0146 NDRX_LOG(log_error, "unexpected !isNew result from ndrx_rbt_insert");
0147 isOk = EXFALSE;
0148 }
0149 }
0150
0151 assert_true(isOk);
0152
0153
0154
0155
0156
0157 if (size > 0)
0158 {
0159 node=(ndrx_int_RBTree_Node_t *)ndrx_irbt_alloc(NULL);
0160 assert_not_equal(node, NULL);
0161
0162 node->key = step * permutation[0];
0163 ndrx_rbt_insert(tree, (ndrx_rbt_node_t *) node, &isNew);
0164 assert_false_with_message(isNew, "unexpected isNew result from ndrx_rbt_insert");
0165 }
0166
0167 NDRX_FPFREE(permutation);
0168 }
0169
0170
0171
0172
0173
0174
0175 Ensure(test_rbt_leftright)
0176 {
0177 ndrx_rbt_tree_t *tree = ndrx_create_int_rbtree();
0178 ndrx_int_RBTree_Node_t *node;
0179 ndrx_rbt_tree_iterator_t iter;
0180 int lastKey = -1;
0181 int count = 0;
0182 int size = M_size;
0183
0184
0185 ndrx_rbt_begin_iterate(tree, LeftRightWalk, &iter);
0186
0187 assert_true_with_message(ndrx_rbt_iterate(&iter) == NULL, "ndrx_rbt_iterate(&iter) != NULL");
0188
0189
0190 ndrx_rbt_populate(tree, size, 1);
0191
0192
0193 ndrx_rbt_begin_iterate(tree, LeftRightWalk, &iter);
0194
0195 while ((node = (ndrx_int_RBTree_Node_t *) ndrx_rbt_iterate(&iter)) != NULL)
0196 {
0197
0198 assert_true_with_message(node->key > lastKey, "left-right walk gives elements not in sorted order");
0199 lastKey = node->key;
0200 count++;
0201 }
0202
0203 assert_true_with_message(lastKey == size - 1, "left-right walk did not reach end");
0204 assert_true_with_message(count == size, "left-right walk missed some elements");
0205 }
0206
0207
0208
0209
0210
0211
0212 Ensure (test_rbt_rightleft)
0213 {
0214 ndrx_rbt_tree_t *tree = ndrx_create_int_rbtree();
0215 ndrx_int_RBTree_Node_t *node;
0216 ndrx_rbt_tree_iterator_t iter;
0217 int lastKey = M_size;
0218 int count = 0;
0219 int size = M_size;
0220
0221
0222 ndrx_rbt_begin_iterate(tree, RightLeftWalk, &iter);
0223 assert_true_with_message(ndrx_rbt_iterate(&iter) == NULL, "ndrx_rbt_iterate(&iter) != NULL");
0224
0225
0226 ndrx_rbt_populate(tree, size, 1);
0227
0228
0229 ndrx_rbt_begin_iterate(tree, RightLeftWalk, &iter);
0230
0231 while ((node = (ndrx_int_RBTree_Node_t *) ndrx_rbt_iterate(&iter)) != NULL)
0232 {
0233
0234 assert_true_with_message(node->key < lastKey, "right-left walk gives elements not in sorted order");
0235
0236 lastKey = node->key;
0237 count++;
0238 }
0239
0240 assert_true_with_message(lastKey == 0, "right-left walk did not reach end");
0241 assert_true_with_message(count == size, "right-left walk missed some elements");
0242 }
0243
0244
0245
0246
0247
0248 Ensure(test_rbt_find)
0249 {
0250 ndrx_rbt_tree_t *tree = ndrx_create_int_rbtree();
0251 int i;
0252 int size = M_size;
0253 int isOk = EXTRUE;
0254
0255 ndrx_rbt_populate(tree, size, 2);
0256
0257
0258 for (i = 0; i < size; i++)
0259 {
0260 ndrx_int_RBTree_Node_t node;
0261 ndrx_int_RBTree_Node_t *resultNode;
0262
0263 node.key = 2 * i;
0264 resultNode = (ndrx_int_RBTree_Node_t *) ndrx_rbt_find(tree, (ndrx_rbt_node_t *) &node);
0265 assert_true_with_message(resultNode != NULL, "inserted element was not found");
0266 assert_true_with_message(resultNode->key == node.key, "find operation in rbtree gave wrong result");
0267 }
0268
0269
0270
0271
0272
0273 for (i = -1; i <= 2 * size; i += 2)
0274 {
0275 ndrx_int_RBTree_Node_t node;
0276 ndrx_int_RBTree_Node_t *resultNode;
0277
0278 node.key = i;
0279 resultNode = (ndrx_int_RBTree_Node_t *) ndrx_rbt_find(tree, (ndrx_rbt_node_t *) &node);
0280 if (resultNode != NULL)
0281 {
0282 NDRX_LOG(log_error, "not-inserted element was found");
0283 isOk = EXFALSE;
0284 }
0285 }
0286 assert_true_with_message(isOk, "not-inserted element was found");
0287 }
0288
0289
0290
0291
0292
0293
0294 Ensure(test_rbt_findltgt)
0295 {
0296 ndrx_rbt_tree_t *tree = ndrx_create_int_rbtree();
0297 int size = M_size;
0298 int isOk = EXTRUE;
0299
0300
0301
0302
0303
0304 int randomKey = ndrx_rand() % (size - 1);
0305 int keyDeleted;
0306 ndrx_int_RBTree_Node_t searchNode = {.key = randomKey};
0307 ndrx_int_RBTree_Node_t *lteNode;
0308 ndrx_int_RBTree_Node_t *gteNode;
0309 ndrx_int_RBTree_Node_t *node;
0310
0311
0312 ndrx_rbt_populate(tree, size, 1);
0313
0314
0315
0316
0317
0318 lteNode = (ndrx_int_RBTree_Node_t *) ndrx_rbt_find_less(tree, (ndrx_rbt_node_t *) &searchNode, EXTRUE);
0319 gteNode = (ndrx_int_RBTree_Node_t *) ndrx_rbt_find_great(tree, (ndrx_rbt_node_t *) &searchNode, EXTRUE);
0320
0321 if (lteNode == NULL || lteNode->key != searchNode.key)
0322 {
0323 NDRX_LOG(log_error, "rbt_find_less() didn't find the equal key");
0324 assert_true(EXFALSE);
0325 }
0326
0327 if (gteNode == NULL || gteNode->key != searchNode.key)
0328 {
0329 NDRX_LOG(log_error, "rbt_find_great() didn't find the equal key");
0330 assert_true(EXFALSE);
0331 }
0332
0333 if (lteNode != gteNode)
0334 {
0335 NDRX_LOG(log_error, "rbt_find_less() and rbt_find_great() found different equal keys");
0336 assert_true(EXFALSE);
0337 }
0338
0339
0340 keyDeleted = EXFALSE;
0341 for (; searchNode.key > 0; searchNode.key--)
0342 {
0343
0344
0345
0346
0347 node = (ndrx_int_RBTree_Node_t *) ndrx_rbt_find_less(tree, (ndrx_rbt_node_t *) &searchNode,
0348 keyDeleted);
0349
0350
0351 if (!node || !(node->key < searchNode.key))
0352 {
0353 NDRX_LOG(log_error, "rbt_find_less() didn't find a lesser key");
0354 isOk = EXFALSE;
0355 }
0356
0357
0358 keyDeleted = ndrx_rand() % 2;
0359 if (keyDeleted)
0360 {
0361 ndrx_rbt_delete(tree, (ndrx_rbt_node_t *) node);
0362 }
0363 }
0364 assert_true(isOk); isOk = EXTRUE;
0365
0366 keyDeleted = EXFALSE;
0367 for (searchNode.key = randomKey; searchNode.key < size - 1; searchNode.key++)
0368 {
0369
0370
0371
0372
0373 node = (ndrx_int_RBTree_Node_t *) ndrx_rbt_find_great(tree, (ndrx_rbt_node_t *) &searchNode,
0374 keyDeleted);
0375
0376
0377 if (!node || !(node->key > searchNode.key))
0378 {
0379 NDRX_LOG(log_error, "rbt_find_great() didn't find a greater key");
0380 isOk = EXFALSE;
0381 }
0382
0383
0384 keyDeleted = ndrx_rand() % 2;
0385 if (keyDeleted)
0386 ndrx_rbt_delete(tree, (ndrx_rbt_node_t *) node);
0387 }
0388 assert_true(isOk); isOk = EXTRUE;
0389
0390
0391 searchNode.key = -1;
0392 node = (ndrx_int_RBTree_Node_t *) ndrx_rbt_find_less(tree, (ndrx_rbt_node_t *) &searchNode, EXTRUE);
0393 if (node != NULL)
0394 {
0395 NDRX_LOG(log_error, "rbt_find_less() found non-inserted element");
0396 assert_true(EXFALSE);
0397 }
0398 searchNode.key = 0;
0399 node = (ndrx_int_RBTree_Node_t *) ndrx_rbt_find_less(tree, (ndrx_rbt_node_t *) &searchNode, EXFALSE);
0400 if (node != NULL)
0401 {
0402 NDRX_LOG(log_error, "rbt_find_less() found non-inserted element");
0403 assert_true(EXFALSE);
0404 }
0405
0406 searchNode.key = size;
0407 node = (ndrx_int_RBTree_Node_t *) ndrx_rbt_find_great(tree, (ndrx_rbt_node_t *) &searchNode, EXTRUE);
0408 if (node != NULL)
0409 {
0410 NDRX_LOG(log_error, "rbt_find_great() found non-inserted element");
0411 assert_true(EXFALSE);
0412 }
0413 searchNode.key = size - 1;
0414 node = (ndrx_int_RBTree_Node_t *) ndrx_rbt_find_great(tree, (ndrx_rbt_node_t *) &searchNode, EXFALSE);
0415 if (node != NULL)
0416 {
0417 NDRX_LOG(log_error, "rbt_find_great() found non-inserted element");
0418 assert_true(EXFALSE);
0419 }
0420 }
0421
0422
0423
0424
0425
0426 Ensure(test_rbt_leftmost)
0427 {
0428 ndrx_rbt_tree_t *tree = ndrx_create_int_rbtree();
0429 ndrx_int_RBTree_Node_t *result;
0430 int size = M_size;
0431
0432
0433 if (ndrx_rbt_leftmost(tree) != NULL)
0434 {
0435 NDRX_LOG(log_error, "leftmost node of empty tree is not NULL");
0436 assert_true(EXFALSE);
0437 }
0438
0439
0440 ndrx_rbt_populate(tree, size, 1);
0441
0442
0443 result = (ndrx_int_RBTree_Node_t *) ndrx_rbt_leftmost(tree);
0444 if (result == NULL || result->key != 0)
0445 {
0446 NDRX_LOG(log_error, "rbt_leftmost gave wrong result");
0447 assert_true(EXFALSE);
0448 }
0449 }
0450
0451
0452
0453
0454 Ensure(test_rbt_delete)
0455 {
0456 ndrx_rbt_tree_t *tree = ndrx_create_int_rbtree();
0457 int *deleteIds;
0458 int i;
0459 int size = M_size;
0460 int delsize = M_delSize;
0461 int isOk = EXTRUE;
0462
0463
0464 ndrx_rbt_populate(tree, size, 1);
0465
0466 deleteIds = (int *) NDRX_FPMALLOC(delsize * sizeof(int), 0);
0467
0468
0469 for (i = 0; i < delsize; i++)
0470 {
0471 int k = ndrx_rand() % size;
0472
0473 deleteIds[i] = k;
0474 }
0475
0476
0477 for (i = 0; i < delsize; i++)
0478 {
0479 ndrx_int_RBTree_Node_t find;
0480 ndrx_int_RBTree_Node_t *node;
0481
0482 find.key = deleteIds[i];
0483
0484 node = (ndrx_int_RBTree_Node_t *) ndrx_rbt_find(tree, (ndrx_rbt_node_t *) &find);
0485 if (node == NULL || node->key != deleteIds[i])
0486 {
0487
0488 }
0489 else
0490 {
0491
0492 ndrx_rbt_delete(tree, (ndrx_rbt_node_t *) node);
0493 }
0494 }
0495
0496
0497 for (i = 0; i < delsize; i++)
0498 {
0499 ndrx_int_RBTree_Node_t find;
0500 ndrx_int_RBTree_Node_t *node;
0501
0502 find.key = deleteIds[i];
0503
0504 node = (ndrx_int_RBTree_Node_t *) ndrx_rbt_find(tree, (ndrx_rbt_node_t *) &find);
0505 if (node != NULL)
0506 {
0507 NDRX_LOG(log_error, "deleted element still present in the rbtree");
0508 isOk = EXFALSE;
0509 }
0510 }
0511
0512 assert_true(isOk); isOk = EXTRUE;
0513
0514
0515 for (i = 0; i < size; i++)
0516 {
0517 int j;
0518 ndrx_int_RBTree_Node_t find;
0519 ndrx_int_RBTree_Node_t *node;
0520
0521
0522 for (j = 0; j < delsize; j++)
0523 {
0524 if (deleteIds[j] == i)
0525 {
0526 break;
0527 }
0528 }
0529
0530 find.key = i;
0531
0532
0533 node = (ndrx_int_RBTree_Node_t *) ndrx_rbt_find(tree, (ndrx_rbt_node_t *) &find);
0534 if (node == NULL || node->key != i)
0535 {
0536
0537 }
0538 else
0539 {
0540
0541 ndrx_rbt_delete(tree, (ndrx_rbt_node_t *) node);
0542 }
0543 }
0544
0545
0546 if (ndrx_rbt_leftmost(tree) != NULL)
0547 {
0548 NDRX_LOG(log_error, "deleting all elements failed");
0549 assert_true(EXFALSE);
0550 }
0551
0552 NDRX_FPFREE(deleteIds);
0553 }
0554
0555 TestSuite *test_rbt_tree(void)
0556 {
0557 TestSuite *suite = create_test_suite();
0558
0559 M_size = 300;
0560 M_delSize = 200;
0561
0562 add_test(suite, test_rbt_leftright);
0563 add_test(suite, test_rbt_rightleft);
0564 add_test(suite, test_rbt_find);
0565 add_test(suite, test_rbt_findltgt);
0566 add_test(suite, test_rbt_leftmost);
0567 add_test(suite, test_rbt_delete);
0568
0569 return suite;
0570 }
0571