patch 4.0
This commit is contained in:
@ -18,17 +18,20 @@
|
||||
#include "lib/container/ob_paringheap.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace container {
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace container
|
||||
{
|
||||
|
||||
typedef struct node_s node_t;
|
||||
struct node_s {
|
||||
struct node_s
|
||||
{
|
||||
#define NODE_MAGIC 0x9823af7e
|
||||
uint32_t magic;
|
||||
PHNODE(node_t, phlink);
|
||||
uint64_t key;
|
||||
|
||||
inline int compare(const node_t* node) const
|
||||
inline int compare(const node_t *node) const
|
||||
{
|
||||
int ret = 0;
|
||||
EXPECT_EQ(this->magic, NODE_MAGIC);
|
||||
@ -39,54 +42,57 @@ struct node_s {
|
||||
* Duplicates are not allowed in the heap, 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;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
typedef ObParingHeap<node_t, ObDummyCompHelper<node_t>> heap_t;
|
||||
|
||||
static void node_print(heap_t* heap, node_t* node, unsigned depth)
|
||||
{
|
||||
static void node_print(heap_t *heap , node_t *node, unsigned depth) {
|
||||
unsigned i;
|
||||
node_t *leftmost_child, *sibling;
|
||||
|
||||
for (i = 0; i < depth; i++) {
|
||||
printf("\t");
|
||||
printf("\t");
|
||||
}
|
||||
printf("%ld\n", node->key);
|
||||
leftmost_child = heap->get_lchild(node);
|
||||
if (leftmost_child == NULL) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
node_print(heap, leftmost_child, depth + 1);
|
||||
|
||||
for (sibling = heap->get_next(leftmost_child); sibling != NULL; sibling = heap->get_next(sibling)) {
|
||||
node_print(heap, sibling, depth + 1);
|
||||
for (sibling = heap->get_next(leftmost_child); sibling !=
|
||||
NULL; sibling = heap->get_next(sibling)) {
|
||||
node_print(heap, sibling, depth + 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void heap_print(heap_t* heap)
|
||||
{
|
||||
node_t* auxelm;
|
||||
static void heap_print(heap_t *heap) {
|
||||
node_t *auxelm;
|
||||
|
||||
printf("vvv heap %p vvv\n", heap);
|
||||
if (heap->get_root() == NULL) {
|
||||
goto label_return;
|
||||
goto label_return;
|
||||
}
|
||||
node_print(heap, heap->get_root(), 0);
|
||||
|
||||
for (auxelm = heap->get_next(heap->get_root()); auxelm != NULL; auxelm = heap->get_next(auxelm)) {
|
||||
assert(heap->get_next(heap->get_prev(auxelm)) == auxelm);
|
||||
node_print(heap, auxelm, 0);
|
||||
for (auxelm = heap->get_next(heap->get_root()); auxelm != NULL;
|
||||
auxelm = heap->get_next(auxelm)) {
|
||||
assert(heap->get_next(heap->get_prev(auxelm)) == auxelm);
|
||||
node_print(heap, auxelm, 0);
|
||||
}
|
||||
|
||||
label_return:
|
||||
printf("^^^ heap %p ^^^\n", heap);
|
||||
printf("^^^ heap %p ^^^\n", heap);
|
||||
}
|
||||
|
||||
static unsigned node_validate(heap_t* heap, node_t* node, const node_t* parent)
|
||||
static unsigned node_validate(heap_t *heap, node_t *node,
|
||||
const node_t *parent)
|
||||
{
|
||||
unsigned nnodes = 1;
|
||||
node_t *leftmost_child, *sibling;
|
||||
@ -97,31 +103,33 @@ static unsigned node_validate(heap_t* heap, node_t* node, const node_t* parent)
|
||||
|
||||
leftmost_child = heap->get_lchild(node);
|
||||
if (leftmost_child == NULL) {
|
||||
return nnodes;
|
||||
return nnodes;
|
||||
}
|
||||
assert(heap->get_prev(leftmost_child) == node);
|
||||
nnodes += node_validate(heap, leftmost_child, node);
|
||||
|
||||
for (sibling = heap->get_next(leftmost_child); sibling != NULL; sibling = heap->get_next(sibling)) {
|
||||
EXPECT_TRUE(heap->get_next(heap->get_prev(sibling)) == sibling);
|
||||
nnodes += node_validate(heap, sibling, node);
|
||||
for (sibling = heap->get_next(leftmost_child); sibling !=
|
||||
NULL; sibling = heap->get_next(sibling)) {
|
||||
EXPECT_TRUE(heap->get_next(heap->get_prev(sibling)) == sibling);
|
||||
nnodes += node_validate(heap, sibling, node);
|
||||
}
|
||||
return nnodes;
|
||||
}
|
||||
|
||||
static unsigned heap_validate(heap_t* heap)
|
||||
static unsigned heap_validate(heap_t *heap)
|
||||
{
|
||||
unsigned nnodes = 0;
|
||||
node_t* auxelm;
|
||||
node_t *auxelm;
|
||||
|
||||
if (heap->get_root() == NULL) {
|
||||
goto label_return;
|
||||
goto label_return;
|
||||
}
|
||||
|
||||
nnodes += node_validate(heap, heap->get_root(), NULL);
|
||||
|
||||
for (auxelm = heap->get_next(heap->get_root()); auxelm != NULL; auxelm = heap->get_next(auxelm)) {
|
||||
// EXPECT_TRUE(auxelm->ph_link.get_prev()->ph_link.get_next() == auxelm);
|
||||
for (auxelm = heap->get_next(heap->get_root()); auxelm != NULL;
|
||||
auxelm = heap->get_next(auxelm)) {
|
||||
//EXPECT_TRUE(auxelm->ph_link.get_prev()->ph_link.get_next() == auxelm);
|
||||
EXPECT_TRUE(heap->get_next(heap->get_prev(auxelm)) == auxelm);
|
||||
nnodes += node_validate(heap, auxelm, NULL);
|
||||
}
|
||||
@ -133,11 +141,11 @@ label_return:
|
||||
return nnodes;
|
||||
}
|
||||
|
||||
TEST(TEST_ParingHeap, empty)
|
||||
TEST (TEST_ParingHeap, empty)
|
||||
{
|
||||
heap_t heap;
|
||||
int ret = 0;
|
||||
node_t* r_node = NULL;
|
||||
node_t *r_node = NULL;
|
||||
heap.init();
|
||||
ASSERT_TRUE(heap.is_empty() == true);
|
||||
|
||||
@ -155,12 +163,13 @@ TEST(TEST_ParingHeap, empty)
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Test_ParingHeap, random)
|
||||
TEST (Test_ParingHeap, random)
|
||||
{
|
||||
#define NNODES 25
|
||||
#define NBAGS 250
|
||||
#define SEED 42
|
||||
|
||||
|
||||
int bag[NNODES];
|
||||
heap_t heap;
|
||||
node_t nodes[NNODES];
|
||||
@ -169,172 +178,181 @@ TEST(Test_ParingHeap, random)
|
||||
srand((unsigned)time(NULL));
|
||||
|
||||
int ret = 0;
|
||||
node_t* r_node = NULL;
|
||||
node_t *r_node = NULL;
|
||||
i = 0;
|
||||
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:
|
||||
for (j = 0; j < NNODES; j++) {
|
||||
bag[j] = rand();
|
||||
}
|
||||
break;
|
||||
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:
|
||||
for (j = 0; j < NNODES; j++) {
|
||||
bag[j] = rand();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
for (j = 1; j <= NNODES; j++) {
|
||||
/* Initialize heap and nodes. */
|
||||
ret = heap.init();
|
||||
if (0 != ret) {
|
||||
fprintf(stderr, "paring heap new fail %d", ret);
|
||||
ASSERT_TRUE(ret == 0);
|
||||
} else {
|
||||
ASSERT_TRUE(heap_validate(&heap) == 0);
|
||||
}
|
||||
/* Initialize heap and nodes. */
|
||||
ret = heap.init();
|
||||
if (0 != ret) {
|
||||
fprintf(stderr, "paring heap new fail %d", ret);
|
||||
ASSERT_TRUE(ret == 0);
|
||||
} else {
|
||||
ASSERT_TRUE(heap_validate(&heap) == 0);
|
||||
}
|
||||
|
||||
for (k = 0; k < j; k++) {
|
||||
nodes[k].magic = NODE_MAGIC;
|
||||
nodes[k].key = bag[k];
|
||||
}
|
||||
for (k = 0; k < j; k++) {
|
||||
nodes[k].magic = NODE_MAGIC;
|
||||
nodes[k].key = bag[k];
|
||||
}
|
||||
|
||||
/* Insert nodes. */
|
||||
for (k = 0; k < j; k++) {
|
||||
ret = heap.insert(&nodes[k]);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "heap paring insert fail %d", ret);
|
||||
ASSERT_TRUE(ret == 0);
|
||||
}
|
||||
if (i % 13 == 12) {
|
||||
ret = heap.get_any(r_node);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "heap paring any fail %d",ret);
|
||||
ASSERT_TRUE(ret == 0);
|
||||
} else {
|
||||
ASSERT_TRUE(r_node != NULL);
|
||||
}
|
||||
|
||||
|
||||
ret = heap.get_first(r_node);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "paring heap get first fail %d", ret);
|
||||
ASSERT_TRUE(ret == 0);
|
||||
} else {
|
||||
ASSERT_TRUE(r_node != NULL);
|
||||
}
|
||||
/* Trigger merging. */
|
||||
}
|
||||
ASSERT_TRUE(heap_validate(&heap) == (k+1));
|
||||
}
|
||||
|
||||
ASSERT_TRUE(heap.is_empty() != true);
|
||||
|
||||
switch(i % 6) {
|
||||
case 0 :
|
||||
{
|
||||
for (k = 0; k < j; k++) {
|
||||
ASSERT_TRUE(heap_validate(&heap) == (j-k));
|
||||
heap.remove(&nodes[k]);
|
||||
ASSERT_TRUE(heap_validate(&heap) == (j-k-1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
for (k = j; k > 0; k--) {
|
||||
heap.remove(&nodes[k-1]);
|
||||
ASSERT_TRUE(heap_validate(&heap) == (k - 1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
node_t *prev = NULL;
|
||||
for (k = 0; k < j; k++) {
|
||||
ret = heap.remove_first(r_node);
|
||||
if (0 != ret) {
|
||||
fprintf(stderr, "ERROR:remove_first ret error %d", ret);
|
||||
ASSERT_TRUE(ret == 0);
|
||||
}
|
||||
ASSERT_TRUE(heap_validate(&heap) == (j-k-1));
|
||||
if (prev != NULL) {
|
||||
ASSERT_TRUE(r_node->compare(prev) >= 0);
|
||||
}
|
||||
prev = r_node;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
node_t *prev = NULL;
|
||||
for (k = 0; k < j; k++) {
|
||||
ret = heap.get_first(r_node);
|
||||
if (0 != ret) {
|
||||
fprintf(stderr,"ERROR :ph_first ret error %d", ret);
|
||||
ASSERT_TRUE(ret == 0);
|
||||
}
|
||||
ASSERT_TRUE(heap_validate(&heap) == (j-k));
|
||||
if (prev != NULL) {
|
||||
ASSERT_TRUE(r_node->compare(prev) >= 0);
|
||||
}
|
||||
heap.remove(r_node);
|
||||
ASSERT_TRUE(heap_validate(&heap) == (j-k-1));
|
||||
prev = r_node;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
for (k = 0; k < j; k++) {
|
||||
ret = heap.remove_any(r_node);
|
||||
if (0 != ret) {
|
||||
fprintf(stderr, "ERROR: ph_remove_any ret error %d", ret);
|
||||
ASSERT_TRUE(ret == 0);
|
||||
}
|
||||
ASSERT_TRUE(heap_validate(&heap) == (j-k-1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
for (k = 0; k < j; k++) {
|
||||
ret = heap.get_any(r_node);
|
||||
if (0 != ret) {
|
||||
fprintf(stderr, "ERROR:ph_any ret error %d", ret);
|
||||
ASSERT_TRUE(ret == 0);
|
||||
}
|
||||
ASSERT_TRUE(heap_validate(&heap) == (j-k));
|
||||
ret = heap.remove(r_node);
|
||||
if (0 != ret) {
|
||||
fprintf(stderr, "ERROR:paring heap remove error %d", ret);
|
||||
ASSERT_TRUE(ret == 0);
|
||||
}
|
||||
ASSERT_TRUE(heap_validate(&heap) == (j-k-1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Insert nodes. */
|
||||
for (k = 0; k < j; k++) {
|
||||
ret = heap.insert(&nodes[k]);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "heap paring insert fail %d", ret);
|
||||
ASSERT_TRUE(ret == 0);
|
||||
}
|
||||
if (i % 13 == 12) {
|
||||
ret = heap.get_any(r_node);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "heap paring any fail %d", ret);
|
||||
ASSERT_TRUE(ret == 0);
|
||||
} else {
|
||||
ASSERT_TRUE(r_node != NULL);
|
||||
}
|
||||
|
||||
ret = heap.get_first(r_node);
|
||||
if (ret != 0) {
|
||||
fprintf(stderr, "paring heap get first fail %d", ret);
|
||||
ASSERT_TRUE(ret == 0);
|
||||
} else {
|
||||
ASSERT_TRUE(r_node != NULL);
|
||||
}
|
||||
/* Trigger merging. */
|
||||
}
|
||||
ASSERT_TRUE(heap_validate(&heap) == (k + 1));
|
||||
}
|
||||
ASSERT_TRUE(ret == 0);
|
||||
ASSERT_TRUE(heap.is_empty() == true);
|
||||
|
||||
ASSERT_TRUE(heap.is_empty() != true);
|
||||
|
||||
switch (i % 6) {
|
||||
case 0: {
|
||||
for (k = 0; k < j; k++) {
|
||||
ASSERT_TRUE(heap_validate(&heap) == (j - k));
|
||||
heap.remove(&nodes[k]);
|
||||
ASSERT_TRUE(heap_validate(&heap) == (j - k - 1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
for (k = j; k > 0; k--) {
|
||||
heap.remove(&nodes[k - 1]);
|
||||
ASSERT_TRUE(heap_validate(&heap) == (k - 1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
node_t* prev = NULL;
|
||||
for (k = 0; k < j; k++) {
|
||||
ret = heap.remove_first(r_node);
|
||||
if (0 != ret) {
|
||||
fprintf(stderr, "ERROR:remove_first ret error %d", ret);
|
||||
ASSERT_TRUE(ret == 0);
|
||||
}
|
||||
ASSERT_TRUE(heap_validate(&heap) == (j - k - 1));
|
||||
if (prev != NULL) {
|
||||
ASSERT_TRUE(r_node->compare(prev) >= 0);
|
||||
}
|
||||
prev = r_node;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
node_t* prev = NULL;
|
||||
for (k = 0; k < j; k++) {
|
||||
ret = heap.get_first(r_node);
|
||||
if (0 != ret) {
|
||||
fprintf(stderr, "ERROR :ph_first ret error %d", ret);
|
||||
ASSERT_TRUE(ret == 0);
|
||||
}
|
||||
ASSERT_TRUE(heap_validate(&heap) == (j - k));
|
||||
if (prev != NULL) {
|
||||
ASSERT_TRUE(r_node->compare(prev) >= 0);
|
||||
}
|
||||
heap.remove(r_node);
|
||||
ASSERT_TRUE(heap_validate(&heap) == (j - k - 1));
|
||||
prev = r_node;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
for (k = 0; k < j; k++) {
|
||||
ret = heap.remove_any(r_node);
|
||||
if (0 != ret) {
|
||||
fprintf(stderr, "ERROR: ph_remove_any ret error %d", ret);
|
||||
ASSERT_TRUE(ret == 0);
|
||||
}
|
||||
ASSERT_TRUE(heap_validate(&heap) == (j - k - 1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 5: {
|
||||
for (k = 0; k < j; k++) {
|
||||
ret = heap.get_any(r_node);
|
||||
if (0 != ret) {
|
||||
fprintf(stderr, "ERROR:ph_any ret error %d", ret);
|
||||
ASSERT_TRUE(ret == 0);
|
||||
}
|
||||
ASSERT_TRUE(heap_validate(&heap) == (j - k));
|
||||
ret = heap.remove(r_node);
|
||||
if (0 != ret) {
|
||||
fprintf(stderr, "ERROR:paring heap remove error %d", ret);
|
||||
ASSERT_TRUE(ret == 0);
|
||||
}
|
||||
ASSERT_TRUE(heap_validate(&heap) == (j - k - 1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ret = heap.get_first(r_node);
|
||||
ASSERT_TRUE(ret == 0);
|
||||
ASSERT_TRUE(heap.is_empty() == true);
|
||||
|
||||
ret = heap.get_any(r_node);
|
||||
ASSERT_TRUE(ret == 0);
|
||||
ASSERT_TRUE(r_node == NULL);
|
||||
ret = heap.get_any(r_node);
|
||||
ASSERT_TRUE(ret == 0);
|
||||
ASSERT_TRUE(r_node == NULL);
|
||||
}
|
||||
}
|
||||
#undef NNODES
|
||||
#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