2 * Copyright (C) 2010 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // Tests for the red-black tree class.
29 #include "platform/PODRedBlackTree.h"
31 #include "platform/testing/ArenaTestHelpers.h"
32 #include "platform/testing/TreeTestHelpers.h"
33 #include "wtf/Vector.h"
35 #include <gtest/gtest.h>
39 using ArenaTestHelpers::TrackedAllocator
;
40 using TreeTestHelpers::initRandom
;
41 using TreeTestHelpers::nextRandom
;
43 TEST(PODRedBlackTreeTest
, TestTreeAllocatesFromArena
)
45 RefPtr
<TrackedAllocator
> allocator
= TrackedAllocator::create();
47 typedef PODFreeListArena
<PODRedBlackTree
<int>::Node
> PODIntegerArena
;
48 RefPtr
<PODIntegerArena
> arena
= PODIntegerArena::create(allocator
);
49 PODRedBlackTree
<int> tree(arena
);
50 int numAdditions
= 2 * PODArena::DefaultChunkSize
/ sizeof(int);
51 for (int i
= 0; i
< numAdditions
; ++i
)
53 EXPECT_GT(allocator
->numRegions(), 1);
55 EXPECT_EQ(allocator
->numRegions(), 0);
58 TEST(PODRedBlackTreeTest
, TestSingleElementInsertion
)
60 PODRedBlackTree
<int> tree
;
62 ASSERT_TRUE(tree
.checkInvariants());
63 EXPECT_TRUE(tree
.contains(5));
66 TEST(PODRedBlackTreeTest
, TestMultipleElementInsertion
)
68 PODRedBlackTree
<int> tree
;
70 ASSERT_TRUE(tree
.checkInvariants());
71 EXPECT_TRUE(tree
.contains(4));
73 ASSERT_TRUE(tree
.checkInvariants());
74 EXPECT_TRUE(tree
.contains(3));
76 ASSERT_TRUE(tree
.checkInvariants());
77 EXPECT_TRUE(tree
.contains(5));
78 EXPECT_TRUE(tree
.contains(4));
79 EXPECT_TRUE(tree
.contains(3));
82 TEST(PODRedBlackTreeTest
, TestDuplicateElementInsertion
)
84 PODRedBlackTree
<int> tree
;
86 ASSERT_TRUE(tree
.checkInvariants());
88 ASSERT_TRUE(tree
.checkInvariants());
90 ASSERT_TRUE(tree
.checkInvariants());
91 EXPECT_EQ(3, tree
.size());
92 EXPECT_TRUE(tree
.contains(3));
95 TEST(PODRedBlackTreeTest
, TestSingleElementInsertionAndDeletion
)
97 PODRedBlackTree
<int> tree
;
99 ASSERT_TRUE(tree
.checkInvariants());
100 EXPECT_TRUE(tree
.contains(5));
102 ASSERT_TRUE(tree
.checkInvariants());
103 EXPECT_FALSE(tree
.contains(5));
106 TEST(PODRedBlackTreeTest
, TestMultipleElementInsertionAndDeletion
)
108 PODRedBlackTree
<int> tree
;
110 ASSERT_TRUE(tree
.checkInvariants());
111 EXPECT_TRUE(tree
.contains(4));
113 ASSERT_TRUE(tree
.checkInvariants());
114 EXPECT_TRUE(tree
.contains(3));
116 ASSERT_TRUE(tree
.checkInvariants());
117 EXPECT_TRUE(tree
.contains(5));
118 EXPECT_TRUE(tree
.contains(4));
119 EXPECT_TRUE(tree
.contains(3));
121 ASSERT_TRUE(tree
.checkInvariants());
122 EXPECT_TRUE(tree
.contains(3));
123 EXPECT_FALSE(tree
.contains(4));
124 EXPECT_TRUE(tree
.contains(5));
126 ASSERT_TRUE(tree
.checkInvariants());
127 EXPECT_TRUE(tree
.contains(3));
128 EXPECT_FALSE(tree
.contains(4));
129 EXPECT_FALSE(tree
.contains(5));
130 EXPECT_EQ(1, tree
.size());
133 TEST(PODRedBlackTreeTest
, TestDuplicateElementInsertionAndDeletion
)
135 PODRedBlackTree
<int> tree
;
137 ASSERT_TRUE(tree
.checkInvariants());
139 ASSERT_TRUE(tree
.checkInvariants());
141 ASSERT_TRUE(tree
.checkInvariants());
142 EXPECT_EQ(3, tree
.size());
143 EXPECT_TRUE(tree
.contains(3));
145 ASSERT_TRUE(tree
.checkInvariants());
147 ASSERT_TRUE(tree
.checkInvariants());
148 EXPECT_EQ(1, tree
.size());
149 EXPECT_TRUE(tree
.contains(3));
151 ASSERT_TRUE(tree
.checkInvariants());
152 EXPECT_EQ(0, tree
.size());
153 EXPECT_FALSE(tree
.contains(3));
156 TEST(PODRedBlackTreeTest
, FailingInsertionRegressionTest1
)
158 // These numbers came from a previously-failing randomized test run.
159 PODRedBlackTree
<int> tree
;
161 ASSERT_TRUE(tree
.checkInvariants());
163 ASSERT_TRUE(tree
.checkInvariants());
165 ASSERT_TRUE(tree
.checkInvariants());
167 ASSERT_TRUE(tree
.checkInvariants());
169 ASSERT_TRUE(tree
.checkInvariants());
173 void InsertionAndDeletionTest(const int32_t seed
, const int treeSize
)
176 const int maximumValue
= treeSize
;
178 PODRedBlackTree
<int> tree
;
180 for (int i
= 0; i
< treeSize
; i
++) {
181 int value
= nextRandom(maximumValue
);
183 ASSERT_TRUE(tree
.checkInvariants()) << "Test failed for seed " << seed
;
184 values
.append(value
);
186 // Churn the tree's contents.
187 for (int i
= 0; i
< treeSize
; i
++) {
188 // Pick a random value to remove.
189 int index
= nextRandom(treeSize
);
190 int value
= values
[index
];
191 // Remove this value.
193 ASSERT_TRUE(tree
.checkInvariants()) << "Test failed for seed " << seed
;
194 // Replace it with a new one.
195 value
= nextRandom(maximumValue
);
196 values
[index
] = value
;
198 ASSERT_TRUE(tree
.checkInvariants()) << "Test failed for seed " << seed
;
201 } // anonymous namespace
203 TEST(PODRedBlackTreeTest
, RandomDeletionAndInsertionRegressionTest1
)
205 InsertionAndDeletionTest(12311, 100);