blob: 445afcaf7a2bc91ae86a2173b4f45eab9a12217b [file] [log] [blame]
Jakob Stoklund Olesen8dc92672010-11-19 04:47:19 +00001//===---- ADT/IntervalMapTest.cpp - IntervalMap unit tests ------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "llvm/ADT/IntervalMap.h"
11#include "gtest/gtest.h"
12
13using namespace llvm;
14
15namespace {
16
17typedef IntervalMap<unsigned, unsigned> UUMap;
Jakob Stoklund Olesen53bb5c02010-11-26 06:54:20 +000018typedef IntervalMap<unsigned, unsigned, 4> UU4Map;
Jakob Stoklund Olesen8dc92672010-11-19 04:47:19 +000019
20// Empty map tests
21TEST(IntervalMapTest, EmptyMap) {
22 UUMap::Allocator allocator;
23 UUMap map(allocator);
24 EXPECT_TRUE(map.empty());
25
26 // Lookup on empty map.
27 EXPECT_EQ(0u, map.lookup(0));
28 EXPECT_EQ(7u, map.lookup(0, 7));
29 EXPECT_EQ(0u, map.lookup(~0u-1));
30 EXPECT_EQ(7u, map.lookup(~0u-1, 7));
31
32 // Iterators.
33 EXPECT_TRUE(map.begin() == map.begin());
34 EXPECT_TRUE(map.begin() == map.end());
35 EXPECT_TRUE(map.end() == map.end());
36 EXPECT_FALSE(map.begin() != map.begin());
37 EXPECT_FALSE(map.begin() != map.end());
38 EXPECT_FALSE(map.end() != map.end());
39 EXPECT_FALSE(map.begin().valid());
40 EXPECT_FALSE(map.end().valid());
41 UUMap::iterator I = map.begin();
42 EXPECT_FALSE(I.valid());
43 EXPECT_TRUE(I == map.end());
Jakob Stoklund Olesen9a08ca32010-11-28 07:21:48 +000044
45 // Default constructor and cross-constness compares.
46 UUMap::const_iterator CI;
47 CI = map.begin();
48 EXPECT_TRUE(CI == I);
49 UUMap::iterator I2;
50 I2 = map.end();
51 EXPECT_TRUE(I2 == CI);
Jakob Stoklund Olesen8dc92672010-11-19 04:47:19 +000052}
53
54// Single entry map tests
55TEST(IntervalMapTest, SingleEntryMap) {
56 UUMap::Allocator allocator;
57 UUMap map(allocator);
58 map.insert(100, 150, 1);
59 EXPECT_FALSE(map.empty());
60
61 // Lookup around interval.
62 EXPECT_EQ(0u, map.lookup(0));
63 EXPECT_EQ(0u, map.lookup(99));
64 EXPECT_EQ(1u, map.lookup(100));
65 EXPECT_EQ(1u, map.lookup(101));
66 EXPECT_EQ(1u, map.lookup(125));
67 EXPECT_EQ(1u, map.lookup(149));
68 EXPECT_EQ(1u, map.lookup(150));
69 EXPECT_EQ(0u, map.lookup(151));
70 EXPECT_EQ(0u, map.lookup(200));
71 EXPECT_EQ(0u, map.lookup(~0u-1));
72
73 // Iterators.
74 EXPECT_TRUE(map.begin() == map.begin());
75 EXPECT_FALSE(map.begin() == map.end());
76 EXPECT_TRUE(map.end() == map.end());
77 EXPECT_TRUE(map.begin().valid());
78 EXPECT_FALSE(map.end().valid());
79
80 // Iter deref.
81 UUMap::iterator I = map.begin();
82 ASSERT_TRUE(I.valid());
83 EXPECT_EQ(100u, I.start());
84 EXPECT_EQ(150u, I.stop());
85 EXPECT_EQ(1u, I.value());
86
87 // Preincrement.
88 ++I;
89 EXPECT_FALSE(I.valid());
90 EXPECT_FALSE(I == map.begin());
91 EXPECT_TRUE(I == map.end());
92
93 // PreDecrement.
94 --I;
95 ASSERT_TRUE(I.valid());
96 EXPECT_EQ(100u, I.start());
97 EXPECT_EQ(150u, I.stop());
98 EXPECT_EQ(1u, I.value());
99 EXPECT_TRUE(I == map.begin());
100 EXPECT_FALSE(I == map.end());
Jakob Stoklund Olesen05594252010-11-27 22:56:53 +0000101
102 I.erase();
103 EXPECT_TRUE(map.empty());
104 EXPECT_EQ(0, std::distance(map.begin(), map.end()));
Jakob Stoklund Olesen8dc92672010-11-19 04:47:19 +0000105}
106
107// Flat coalescing tests.
108TEST(IntervalMapTest, RootCoalescing) {
109 UUMap::Allocator allocator;
110 UUMap map(allocator);
111 map.insert(100, 150, 1);
112
113 // Coalesce from the left.
114 map.insert(90, 99, 1);
115 EXPECT_EQ(1, std::distance(map.begin(), map.end()));
116 EXPECT_EQ(90u, map.start());
117 EXPECT_EQ(150u, map.stop());
118
Jakob Stoklund Olesen8dc92672010-11-19 04:47:19 +0000119 // Coalesce from the right.
Jakob Stoklund Olesen5f456cd2010-11-28 22:17:11 +0000120 map.insert(151, 200, 1);
Jakob Stoklund Olesen8dc92672010-11-19 04:47:19 +0000121 EXPECT_EQ(1, std::distance(map.begin(), map.end()));
Jakob Stoklund Olesen5f456cd2010-11-28 22:17:11 +0000122 EXPECT_EQ(90u, map.start());
Jakob Stoklund Olesen8dc92672010-11-19 04:47:19 +0000123 EXPECT_EQ(200u, map.stop());
124
125 // Non-coalesce from the left.
Jakob Stoklund Olesen5f456cd2010-11-28 22:17:11 +0000126 map.insert(60, 89, 2);
Jakob Stoklund Olesen8dc92672010-11-19 04:47:19 +0000127 EXPECT_EQ(2, std::distance(map.begin(), map.end()));
128 EXPECT_EQ(60u, map.start());
129 EXPECT_EQ(200u, map.stop());
Jakob Stoklund Olesen5f456cd2010-11-28 22:17:11 +0000130 EXPECT_EQ(2u, map.lookup(89));
131 EXPECT_EQ(1u, map.lookup(90));
Jakob Stoklund Olesen8dc92672010-11-19 04:47:19 +0000132
133 UUMap::iterator I = map.begin();
134 EXPECT_EQ(60u, I.start());
Jakob Stoklund Olesen5f456cd2010-11-28 22:17:11 +0000135 EXPECT_EQ(89u, I.stop());
Jakob Stoklund Olesen8dc92672010-11-19 04:47:19 +0000136 EXPECT_EQ(2u, I.value());
137 ++I;
Jakob Stoklund Olesen5f456cd2010-11-28 22:17:11 +0000138 EXPECT_EQ(90u, I.start());
Jakob Stoklund Olesen8dc92672010-11-19 04:47:19 +0000139 EXPECT_EQ(200u, I.stop());
140 EXPECT_EQ(1u, I.value());
141 ++I;
142 EXPECT_FALSE(I.valid());
143
144 // Non-coalesce from the right.
145 map.insert(201, 210, 2);
146 EXPECT_EQ(3, std::distance(map.begin(), map.end()));
147 EXPECT_EQ(60u, map.start());
148 EXPECT_EQ(210u, map.stop());
149 EXPECT_EQ(2u, map.lookup(201));
150 EXPECT_EQ(1u, map.lookup(200));
Jakob Stoklund Olesen05594252010-11-27 22:56:53 +0000151
152 // Erase from the left.
153 map.begin().erase();
154 EXPECT_EQ(2, std::distance(map.begin(), map.end()));
Jakob Stoklund Olesen5f456cd2010-11-28 22:17:11 +0000155 EXPECT_EQ(90u, map.start());
Jakob Stoklund Olesen05594252010-11-27 22:56:53 +0000156 EXPECT_EQ(210u, map.stop());
157
158 // Erase from the right.
159 (--map.end()).erase();
160 EXPECT_EQ(1, std::distance(map.begin(), map.end()));
Jakob Stoklund Olesen5f456cd2010-11-28 22:17:11 +0000161 EXPECT_EQ(90u, map.start());
Jakob Stoklund Olesen05594252010-11-27 22:56:53 +0000162 EXPECT_EQ(200u, map.stop());
Jakob Stoklund Olesen8dc92672010-11-19 04:47:19 +0000163}
164
165// Flat multi-coalescing tests.
166TEST(IntervalMapTest, RootMultiCoalescing) {
167 UUMap::Allocator allocator;
168 UUMap map(allocator);
169 map.insert(140, 150, 1);
170 map.insert(160, 170, 1);
171 map.insert(100, 110, 1);
172 map.insert(120, 130, 1);
173 EXPECT_EQ(4, std::distance(map.begin(), map.end()));
174 EXPECT_EQ(100u, map.start());
175 EXPECT_EQ(170u, map.stop());
176
177 // Verify inserts.
178 UUMap::iterator I = map.begin();
179 EXPECT_EQ(100u, I.start());
180 EXPECT_EQ(110u, I.stop());
181 ++I;
182 EXPECT_EQ(120u, I.start());
183 EXPECT_EQ(130u, I.stop());
184 ++I;
185 EXPECT_EQ(140u, I.start());
186 EXPECT_EQ(150u, I.stop());
187 ++I;
188 EXPECT_EQ(160u, I.start());
189 EXPECT_EQ(170u, I.stop());
190 ++I;
191 EXPECT_FALSE(I.valid());
192
Jakob Stoklund Olesen180e1242010-11-28 07:00:46 +0000193 // Test advanceTo on flat tree.
194 I = map.begin();
195 I.advanceTo(135);
196 ASSERT_TRUE(I.valid());
197 EXPECT_EQ(140u, I.start());
198 EXPECT_EQ(150u, I.stop());
199
200 I.advanceTo(145);
201 ASSERT_TRUE(I.valid());
202 EXPECT_EQ(140u, I.start());
203 EXPECT_EQ(150u, I.stop());
Jakob Stoklund Olesen8dc92672010-11-19 04:47:19 +0000204
205 // Coalesce left with followers.
206 // [100;110] [120;130] [140;150] [160;170]
207 map.insert(111, 115, 1);
208 I = map.begin();
209 ASSERT_TRUE(I.valid());
210 EXPECT_EQ(100u, I.start());
211 EXPECT_EQ(115u, I.stop());
212 ++I;
213 ASSERT_TRUE(I.valid());
214 EXPECT_EQ(120u, I.start());
215 EXPECT_EQ(130u, I.stop());
216 ++I;
217 ASSERT_TRUE(I.valid());
218 EXPECT_EQ(140u, I.start());
219 EXPECT_EQ(150u, I.stop());
220 ++I;
221 ASSERT_TRUE(I.valid());
222 EXPECT_EQ(160u, I.start());
223 EXPECT_EQ(170u, I.stop());
224 ++I;
225 EXPECT_FALSE(I.valid());
226
227 // Coalesce right with followers.
228 // [100;115] [120;130] [140;150] [160;170]
229 map.insert(135, 139, 1);
230 I = map.begin();
231 ASSERT_TRUE(I.valid());
232 EXPECT_EQ(100u, I.start());
233 EXPECT_EQ(115u, I.stop());
234 ++I;
235 ASSERT_TRUE(I.valid());
236 EXPECT_EQ(120u, I.start());
237 EXPECT_EQ(130u, I.stop());
238 ++I;
239 ASSERT_TRUE(I.valid());
240 EXPECT_EQ(135u, I.start());
241 EXPECT_EQ(150u, I.stop());
242 ++I;
243 ASSERT_TRUE(I.valid());
244 EXPECT_EQ(160u, I.start());
245 EXPECT_EQ(170u, I.stop());
246 ++I;
247 EXPECT_FALSE(I.valid());
248
249 // Coalesce left and right with followers.
250 // [100;115] [120;130] [135;150] [160;170]
251 map.insert(131, 134, 1);
252 I = map.begin();
253 ASSERT_TRUE(I.valid());
254 EXPECT_EQ(100u, I.start());
255 EXPECT_EQ(115u, I.stop());
256 ++I;
257 ASSERT_TRUE(I.valid());
258 EXPECT_EQ(120u, I.start());
259 EXPECT_EQ(150u, I.stop());
260 ++I;
261 ASSERT_TRUE(I.valid());
262 EXPECT_EQ(160u, I.start());
263 EXPECT_EQ(170u, I.stop());
264 ++I;
265 EXPECT_FALSE(I.valid());
266
Jakob Stoklund Olesen655fbb42010-11-19 23:28:57 +0000267 // Test clear() on non-branched map.
268 map.clear();
269 EXPECT_TRUE(map.empty());
270 EXPECT_TRUE(map.begin() == map.end());
Jakob Stoklund Olesen8dc92672010-11-19 04:47:19 +0000271}
272
273// Branched, non-coalescing tests.
274TEST(IntervalMapTest, Branched) {
275 UUMap::Allocator allocator;
276 UUMap map(allocator);
277
278 // Insert enough intervals to force a branched tree.
279 // This creates 9 leaf nodes with 11 elements each, tree height = 1.
Jakob Stoklund Olesen05594252010-11-27 22:56:53 +0000280 for (unsigned i = 1; i < 100; ++i) {
Jakob Stoklund Olesen8dc92672010-11-19 04:47:19 +0000281 map.insert(10*i, 10*i+5, i);
Jakob Stoklund Olesen05594252010-11-27 22:56:53 +0000282 EXPECT_EQ(10u, map.start());
283 EXPECT_EQ(10*i+5, map.stop());
284 }
Jakob Stoklund Olesen8dc92672010-11-19 04:47:19 +0000285
286 // Tree limits.
287 EXPECT_FALSE(map.empty());
288 EXPECT_EQ(10u, map.start());
289 EXPECT_EQ(995u, map.stop());
290
291 // Tree lookup.
292 for (unsigned i = 1; i < 100; ++i) {
293 EXPECT_EQ(0u, map.lookup(10*i-1));
294 EXPECT_EQ(i, map.lookup(10*i));
295 EXPECT_EQ(i, map.lookup(10*i+5));
296 EXPECT_EQ(0u, map.lookup(10*i+6));
297 }
298
299 // Forward iteration.
300 UUMap::iterator I = map.begin();
301 for (unsigned i = 1; i < 100; ++i) {
302 ASSERT_TRUE(I.valid());
303 EXPECT_EQ(10*i, I.start());
304 EXPECT_EQ(10*i+5, I.stop());
305 EXPECT_EQ(i, *I);
306 ++I;
307 }
308 EXPECT_FALSE(I.valid());
309 EXPECT_TRUE(I == map.end());
310
Jakob Stoklund Olesendb525662010-11-19 23:28:53 +0000311 // Backwards iteration.
312 for (unsigned i = 99; i; --i) {
313 --I;
314 ASSERT_TRUE(I.valid());
315 EXPECT_EQ(10*i, I.start());
316 EXPECT_EQ(10*i+5, I.stop());
317 EXPECT_EQ(i, *I);
318 }
319 EXPECT_TRUE(I == map.begin());
320
Jakob Stoklund Olesen180e1242010-11-28 07:00:46 +0000321 // Test advanceTo in same node.
322 I.advanceTo(20);
323 ASSERT_TRUE(I.valid());
324 EXPECT_EQ(20u, I.start());
325 EXPECT_EQ(25u, I.stop());
326
327 // advanceTo another node.
328 I.advanceTo(200);
329 ASSERT_TRUE(I.valid());
330 EXPECT_EQ(200u, I.start());
331 EXPECT_EQ(205u, I.stop());
332
Jakob Stoklund Olesen05594252010-11-27 22:56:53 +0000333 // Erase from the front.
Jakob Stoklund Olesen180e1242010-11-28 07:00:46 +0000334 I = map.begin();
Jakob Stoklund Olesen05594252010-11-27 22:56:53 +0000335 for (unsigned i = 0; i != 20; ++i) {
336 I.erase();
337 EXPECT_TRUE(I == map.begin());
338 EXPECT_FALSE(map.empty());
339 EXPECT_EQ(I.start(), map.start());
340 EXPECT_EQ(995u, map.stop());
341 }
342
Jakob Stoklund Olesen655fbb42010-11-19 23:28:57 +0000343 // Test clear() on branched map.
344 map.clear();
345 EXPECT_TRUE(map.empty());
346 EXPECT_TRUE(map.begin() == map.end());
Jakob Stoklund Olesen8dc92672010-11-19 04:47:19 +0000347}
348
Jakob Stoklund Olesen53bb5c02010-11-26 06:54:20 +0000349// Branched, high, non-coalescing tests.
350TEST(IntervalMapTest, Branched2) {
351 UU4Map::Allocator allocator;
352 UU4Map map(allocator);
353
354 // Insert enough intervals to force a height >= 2 tree.
355 for (unsigned i = 1; i < 1000; ++i)
356 map.insert(10*i, 10*i+5, i);
357
358 // Tree limits.
359 EXPECT_FALSE(map.empty());
360 EXPECT_EQ(10u, map.start());
361 EXPECT_EQ(9995u, map.stop());
362
363 // Tree lookup.
364 for (unsigned i = 1; i < 1000; ++i) {
365 EXPECT_EQ(0u, map.lookup(10*i-1));
366 EXPECT_EQ(i, map.lookup(10*i));
367 EXPECT_EQ(i, map.lookup(10*i+5));
368 EXPECT_EQ(0u, map.lookup(10*i+6));
369 }
370
371 // Forward iteration.
372 UU4Map::iterator I = map.begin();
373 for (unsigned i = 1; i < 1000; ++i) {
374 ASSERT_TRUE(I.valid());
375 EXPECT_EQ(10*i, I.start());
376 EXPECT_EQ(10*i+5, I.stop());
377 EXPECT_EQ(i, *I);
378 ++I;
379 }
380 EXPECT_FALSE(I.valid());
381 EXPECT_TRUE(I == map.end());
382
383 // Backwards iteration.
384 for (unsigned i = 999; i; --i) {
385 --I;
386 ASSERT_TRUE(I.valid());
387 EXPECT_EQ(10*i, I.start());
388 EXPECT_EQ(10*i+5, I.stop());
389 EXPECT_EQ(i, *I);
390 }
391 EXPECT_TRUE(I == map.begin());
392
Jakob Stoklund Olesen180e1242010-11-28 07:00:46 +0000393 // Test advanceTo in same node.
394 I.advanceTo(20);
395 ASSERT_TRUE(I.valid());
396 EXPECT_EQ(20u, I.start());
397 EXPECT_EQ(25u, I.stop());
398
399 // advanceTo sibling leaf node.
400 I.advanceTo(200);
401 ASSERT_TRUE(I.valid());
402 EXPECT_EQ(200u, I.start());
403 EXPECT_EQ(205u, I.stop());
404
405 // advanceTo further.
406 I.advanceTo(2000);
407 ASSERT_TRUE(I.valid());
408 EXPECT_EQ(2000u, I.start());
409 EXPECT_EQ(2005u, I.stop());
410
Jakob Stoklund Olesen53bb5c02010-11-26 06:54:20 +0000411 // Test clear() on branched map.
412 map.clear();
413 EXPECT_TRUE(map.empty());
414 EXPECT_TRUE(map.begin() == map.end());
415}
416
Jakob Stoklund Olesenb0b72142010-11-27 21:12:36 +0000417// Random insertions, coalescing to a single interval.
418TEST(IntervalMapTest, RandomCoalescing) {
419 UU4Map::Allocator allocator;
420 UU4Map map(allocator);
421
422 // This is a poor PRNG with maximal period:
423 // x_n = 5 x_{n-1} + 1 mod 2^N
424
425 unsigned x = 100;
426 for (unsigned i = 0; i != 4096; ++i) {
427 map.insert(10*x, 10*x+9, 1);
428 EXPECT_GE(10*x, map.start());
429 EXPECT_LE(10*x+9, map.stop());
430 x = (5*x+1)%4096;
431 }
432
433 // Map should be fully coalesced after that exercise.
434 EXPECT_FALSE(map.empty());
435 EXPECT_EQ(0u, map.start());
436 EXPECT_EQ(40959u, map.stop());
437 EXPECT_EQ(1, std::distance(map.begin(), map.end()));
438
439}
440
Jakob Stoklund Olesen8dc92672010-11-19 04:47:19 +0000441} // namespace