1 // ============================================================================
7 // Bug_3332_Regression_Test.cpp
10 // This is a test to verify the node unbind/remove stability.
11 // Originally the deletion of a node from the rb_tree would cause some nodes
12 // to be "swapped" and the node being deleted to be reused to hold data still
13 // in the rb_tree, whilst the original "still in the tree" data node would be
14 // unbound instead. This caused externally held pointers to existing data that
15 // should still be in the tree to become invalidated unnecessarily. This test
16 // ensures that the node NOT being deleted always keep their original enteries
17 // (and thus only the deleted node is actually unbound and released).
20 // Simon Massey <sma@prismtech.com>
22 // ============================================================================
24 #include "test_config.h" /* Include first to enable ACE_TEST_ASSERT. */
25 #include "ace/RB_Tree.h"
26 #include "ace/Null_Mutex.h"
34 ACE_RB_Tree_Node
<char, int> *node
;
35 } nodes
[] = {{'a', 1, 0},
51 run_main (int, ACE_TCHAR
*[])
54 ACE_START_TEST (ACE_TEXT ("Bug_3332_Regression_Test"));
56 ACE_RB_Tree
<char, int, ACE_Less_Than
<char>, ACE_Null_Mutex
> tree
;
58 ACE_DEBUG ((LM_DEBUG
, "Creating Tree\n"));
59 {for (size_t i
= 0u; i
< sizeof(nodes
)/sizeof(Nodes
); ++i
)
61 if (0 != tree
.bind (nodes
[i
].key
, nodes
[i
].value
, nodes
[i
].node
))
63 ACE_DEBUG ((LM_ERROR
, ": Binding failed for %c=%d\n", nodes
[i
].key
, nodes
[i
].value
));
70 ACE_DEBUG ((LM_DEBUG
, "Validating Tree\n"));
71 {for (size_t i
= 0u; i
< sizeof(nodes
)/sizeof(Nodes
); ++i
)
73 ACE_RB_Tree_Node
<char, int> *node
= 0;
75 if (tree
.find (nodes
[i
].key
, node
))
77 ACE_DEBUG ((LM_ERROR
, ": Can't find key %c in tree\n", nodes
[i
].key
));
80 else if (nodes
[i
].node
!= node
)
82 ACE_DEBUG ((LM_ERROR
, ": entry %c=%d has ALREADY moved from %@ to %@\n", nodes
[i
].key
, nodes
[i
].value
, nodes
[i
].node
, node
));
85 else for (size_t j
= i
+1u; j
< sizeof(nodes
)/sizeof(Nodes
); ++j
)
87 if (nodes
[i
].node
== nodes
[j
].node
)
89 ACE_DEBUG ((LM_ERROR
, ": Duplicate Binding (%@) for %c=%d and %c=%d\n", nodes
[i
].node
, nodes
[i
].key
, nodes
[i
].value
, nodes
[j
].key
, nodes
[j
].value
));
97 {for (size_t i
= 0u; i
< sizeof(nodes
)/sizeof(Nodes
); ++i
)
99 ACE_DEBUG ((LM_DEBUG
, "Deleting node %c=%d @ %@\n", nodes
[i
].key
, nodes
[i
].value
, nodes
[i
].node
));
100 if (tree
.unbind (nodes
[i
].key
))
102 ACE_DEBUG ((LM_ERROR
, ": Can't unbind key %c from tree\n", nodes
[i
].key
));
107 ACE_RB_Tree_Node
<char, int> *node
= 0;
109 if (0 == tree
.find (nodes
[i
].key
, node
))
111 ACE_DEBUG ((LM_ERROR
, ": Found %c=%d @ %@ in tree\n", node
->key(), node
->item(), node
));
114 else {for (size_t j
= i
+1u; j
< sizeof(nodes
)/sizeof(Nodes
); ++j
)
116 if (tree
.find (nodes
[j
].key
, node
))
118 ACE_DEBUG ((LM_ERROR
, ": Can't find key %c in tree\n", nodes
[j
].key
));
121 else if (nodes
[j
].node
!= node
)
123 ACE_DEBUG ((LM_ERROR
, ": entry %c=%d has moved from %@ to %@\n", nodes
[j
].key
, nodes
[j
].value
, nodes
[j
].node
, node
));
124 nodes
[j
].node
= node
; // Don't keep reporting this same issue on further deletions.
127 else if (nodes
[j
].key
!= node
->key() || nodes
[j
].value
!= node
->item())
129 ACE_DEBUG ((LM_ERROR
, ": entry %c=%d has changed to %c=%d\n", nodes
[j
].key
, nodes
[j
].value
, node
->key(), node
->item()));
130 nodes
[j
].key
= node
->key(); // Don't keep reporting this problem on further deletions.
131 nodes
[j
].value
= node
->item();
140 ACE_DEBUG ((LM_DEBUG
, "Finished\n"));