1 //===---- 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 13 using namespace llvm; 14 15 namespace { 16 17 typedef IntervalMap<unsigned, unsigned> UUMap; 18 typedef IntervalMap<unsigned, unsigned, 4> UU4Map; 19 20 // Empty map tests 21 TEST(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()); 44 } 45 46 // Single entry map tests 47 TEST(IntervalMapTest, SingleEntryMap) { 48 UUMap::Allocator allocator; 49 UUMap map(allocator); 50 map.insert(100, 150, 1); 51 EXPECT_FALSE(map.empty()); 52 53 // Lookup around interval. 54 EXPECT_EQ(0u, map.lookup(0)); 55 EXPECT_EQ(0u, map.lookup(99)); 56 EXPECT_EQ(1u, map.lookup(100)); 57 EXPECT_EQ(1u, map.lookup(101)); 58 EXPECT_EQ(1u, map.lookup(125)); 59 EXPECT_EQ(1u, map.lookup(149)); 60 EXPECT_EQ(1u, map.lookup(150)); 61 EXPECT_EQ(0u, map.lookup(151)); 62 EXPECT_EQ(0u, map.lookup(200)); 63 EXPECT_EQ(0u, map.lookup(~0u-1)); 64 65 // Iterators. 66 EXPECT_TRUE(map.begin() == map.begin()); 67 EXPECT_FALSE(map.begin() == map.end()); 68 EXPECT_TRUE(map.end() == map.end()); 69 EXPECT_TRUE(map.begin().valid()); 70 EXPECT_FALSE(map.end().valid()); 71 72 // Iter deref. 73 UUMap::iterator I = map.begin(); 74 ASSERT_TRUE(I.valid()); 75 EXPECT_EQ(100u, I.start()); 76 EXPECT_EQ(150u, I.stop()); 77 EXPECT_EQ(1u, I.value()); 78 79 // Preincrement. 80 ++I; 81 EXPECT_FALSE(I.valid()); 82 EXPECT_FALSE(I == map.begin()); 83 EXPECT_TRUE(I == map.end()); 84 85 // PreDecrement. 86 --I; 87 ASSERT_TRUE(I.valid()); 88 EXPECT_EQ(100u, I.start()); 89 EXPECT_EQ(150u, I.stop()); 90 EXPECT_EQ(1u, I.value()); 91 EXPECT_TRUE(I == map.begin()); 92 EXPECT_FALSE(I == map.end()); 93 } 94 95 // Flat coalescing tests. 96 TEST(IntervalMapTest, RootCoalescing) { 97 UUMap::Allocator allocator; 98 UUMap map(allocator); 99 map.insert(100, 150, 1); 100 101 // Coalesce from the left. 102 map.insert(90, 99, 1); 103 EXPECT_EQ(1, std::distance(map.begin(), map.end())); 104 EXPECT_EQ(90u, map.start()); 105 EXPECT_EQ(150u, map.stop()); 106 107 // Overlap left. 108 map.insert(80, 100, 1); 109 EXPECT_EQ(1, std::distance(map.begin(), map.end())); 110 EXPECT_EQ(80u, map.start()); 111 EXPECT_EQ(150u, map.stop()); 112 113 // Inside. 114 map.insert(100, 130, 1); 115 EXPECT_EQ(1, std::distance(map.begin(), map.end())); 116 EXPECT_EQ(80u, map.start()); 117 EXPECT_EQ(150u, map.stop()); 118 119 // Overlap both. 120 map.insert(70, 160, 1); 121 EXPECT_EQ(1, std::distance(map.begin(), map.end())); 122 EXPECT_EQ(70u, map.start()); 123 EXPECT_EQ(160u, map.stop()); 124 125 // Overlap right. 126 map.insert(80, 170, 1); 127 EXPECT_EQ(1, std::distance(map.begin(), map.end())); 128 EXPECT_EQ(70u, map.start()); 129 EXPECT_EQ(170u, map.stop()); 130 131 // Coalesce from the right. 132 map.insert(170, 200, 1); 133 EXPECT_EQ(1, std::distance(map.begin(), map.end())); 134 EXPECT_EQ(70u, map.start()); 135 EXPECT_EQ(200u, map.stop()); 136 137 // Non-coalesce from the left. 138 map.insert(60, 69, 2); 139 EXPECT_EQ(2, std::distance(map.begin(), map.end())); 140 EXPECT_EQ(60u, map.start()); 141 EXPECT_EQ(200u, map.stop()); 142 EXPECT_EQ(2u, map.lookup(69)); 143 EXPECT_EQ(1u, map.lookup(70)); 144 145 UUMap::iterator I = map.begin(); 146 EXPECT_EQ(60u, I.start()); 147 EXPECT_EQ(69u, I.stop()); 148 EXPECT_EQ(2u, I.value()); 149 ++I; 150 EXPECT_EQ(70u, I.start()); 151 EXPECT_EQ(200u, I.stop()); 152 EXPECT_EQ(1u, I.value()); 153 ++I; 154 EXPECT_FALSE(I.valid()); 155 156 // Non-coalesce from the right. 157 map.insert(201, 210, 2); 158 EXPECT_EQ(3, std::distance(map.begin(), map.end())); 159 EXPECT_EQ(60u, map.start()); 160 EXPECT_EQ(210u, map.stop()); 161 EXPECT_EQ(2u, map.lookup(201)); 162 EXPECT_EQ(1u, map.lookup(200)); 163 } 164 165 // Flat multi-coalescing tests. 166 TEST(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 193 194 // Coalesce left with followers. 195 // [100;110] [120;130] [140;150] [160;170] 196 map.insert(111, 115, 1); 197 I = map.begin(); 198 ASSERT_TRUE(I.valid()); 199 EXPECT_EQ(100u, I.start()); 200 EXPECT_EQ(115u, I.stop()); 201 ++I; 202 ASSERT_TRUE(I.valid()); 203 EXPECT_EQ(120u, I.start()); 204 EXPECT_EQ(130u, I.stop()); 205 ++I; 206 ASSERT_TRUE(I.valid()); 207 EXPECT_EQ(140u, I.start()); 208 EXPECT_EQ(150u, I.stop()); 209 ++I; 210 ASSERT_TRUE(I.valid()); 211 EXPECT_EQ(160u, I.start()); 212 EXPECT_EQ(170u, I.stop()); 213 ++I; 214 EXPECT_FALSE(I.valid()); 215 216 // Coalesce right with followers. 217 // [100;115] [120;130] [140;150] [160;170] 218 map.insert(135, 139, 1); 219 I = map.begin(); 220 ASSERT_TRUE(I.valid()); 221 EXPECT_EQ(100u, I.start()); 222 EXPECT_EQ(115u, I.stop()); 223 ++I; 224 ASSERT_TRUE(I.valid()); 225 EXPECT_EQ(120u, I.start()); 226 EXPECT_EQ(130u, I.stop()); 227 ++I; 228 ASSERT_TRUE(I.valid()); 229 EXPECT_EQ(135u, I.start()); 230 EXPECT_EQ(150u, I.stop()); 231 ++I; 232 ASSERT_TRUE(I.valid()); 233 EXPECT_EQ(160u, I.start()); 234 EXPECT_EQ(170u, I.stop()); 235 ++I; 236 EXPECT_FALSE(I.valid()); 237 238 // Coalesce left and right with followers. 239 // [100;115] [120;130] [135;150] [160;170] 240 map.insert(131, 134, 1); 241 I = map.begin(); 242 ASSERT_TRUE(I.valid()); 243 EXPECT_EQ(100u, I.start()); 244 EXPECT_EQ(115u, I.stop()); 245 ++I; 246 ASSERT_TRUE(I.valid()); 247 EXPECT_EQ(120u, I.start()); 248 EXPECT_EQ(150u, I.stop()); 249 ++I; 250 ASSERT_TRUE(I.valid()); 251 EXPECT_EQ(160u, I.start()); 252 EXPECT_EQ(170u, I.stop()); 253 ++I; 254 EXPECT_FALSE(I.valid()); 255 256 // Coalesce multiple with overlap right. 257 // [100;115] [120;150] [160;170] 258 map.insert(116, 165, 1); 259 I = map.begin(); 260 ASSERT_TRUE(I.valid()); 261 EXPECT_EQ(100u, I.start()); 262 EXPECT_EQ(170u, I.stop()); 263 ++I; 264 EXPECT_FALSE(I.valid()); 265 266 // Coalesce multiple with overlap left 267 // [100;170] 268 map.insert(180, 190, 1); 269 map.insert(200, 210, 1); 270 map.insert(220, 230, 1); 271 // [100;170] [180;190] [200;210] [220;230] 272 map.insert(160, 199, 1); 273 I = map.begin(); 274 ASSERT_TRUE(I.valid()); 275 EXPECT_EQ(100u, I.start()); 276 EXPECT_EQ(210u, I.stop()); 277 ++I; 278 ASSERT_TRUE(I.valid()); 279 EXPECT_EQ(220u, I.start()); 280 EXPECT_EQ(230u, I.stop()); 281 ++I; 282 EXPECT_FALSE(I.valid()); 283 284 // Overwrite 2 from gap to gap. 285 // [100;210] [220;230] 286 map.insert(50, 250, 1); 287 I = map.begin(); 288 ASSERT_TRUE(I.valid()); 289 EXPECT_EQ(50u, I.start()); 290 EXPECT_EQ(250u, I.stop()); 291 ++I; 292 EXPECT_FALSE(I.valid()); 293 294 // Coalesce at end of full root. 295 // [50;250] 296 map.insert(260, 270, 1); 297 map.insert(280, 290, 1); 298 map.insert(300, 310, 1); 299 // [50;250] [260;270] [280;290] [300;310] 300 map.insert(311, 320, 1); 301 I = map.begin(); 302 ASSERT_TRUE(I.valid()); 303 EXPECT_EQ(50u, I.start()); 304 EXPECT_EQ(250u, I.stop()); 305 ++I; 306 ASSERT_TRUE(I.valid()); 307 EXPECT_EQ(260u, I.start()); 308 EXPECT_EQ(270u, I.stop()); 309 ++I; 310 ASSERT_TRUE(I.valid()); 311 EXPECT_EQ(280u, I.start()); 312 EXPECT_EQ(290u, I.stop()); 313 ++I; 314 ASSERT_TRUE(I.valid()); 315 EXPECT_EQ(300u, I.start()); 316 EXPECT_EQ(320u, I.stop()); 317 ++I; 318 EXPECT_FALSE(I.valid()); 319 320 // Test clear() on non-branched map. 321 map.clear(); 322 EXPECT_TRUE(map.empty()); 323 EXPECT_TRUE(map.begin() == map.end()); 324 } 325 326 // Branched, non-coalescing tests. 327 TEST(IntervalMapTest, Branched) { 328 UUMap::Allocator allocator; 329 UUMap map(allocator); 330 331 // Insert enough intervals to force a branched tree. 332 // This creates 9 leaf nodes with 11 elements each, tree height = 1. 333 for (unsigned i = 1; i < 100; ++i) 334 map.insert(10*i, 10*i+5, i); 335 336 // Tree limits. 337 EXPECT_FALSE(map.empty()); 338 EXPECT_EQ(10u, map.start()); 339 EXPECT_EQ(995u, map.stop()); 340 341 // Tree lookup. 342 for (unsigned i = 1; i < 100; ++i) { 343 EXPECT_EQ(0u, map.lookup(10*i-1)); 344 EXPECT_EQ(i, map.lookup(10*i)); 345 EXPECT_EQ(i, map.lookup(10*i+5)); 346 EXPECT_EQ(0u, map.lookup(10*i+6)); 347 } 348 349 // Forward iteration. 350 UUMap::iterator I = map.begin(); 351 for (unsigned i = 1; i < 100; ++i) { 352 ASSERT_TRUE(I.valid()); 353 EXPECT_EQ(10*i, I.start()); 354 EXPECT_EQ(10*i+5, I.stop()); 355 EXPECT_EQ(i, *I); 356 ++I; 357 } 358 EXPECT_FALSE(I.valid()); 359 EXPECT_TRUE(I == map.end()); 360 361 // Backwards iteration. 362 for (unsigned i = 99; i; --i) { 363 --I; 364 ASSERT_TRUE(I.valid()); 365 EXPECT_EQ(10*i, I.start()); 366 EXPECT_EQ(10*i+5, I.stop()); 367 EXPECT_EQ(i, *I); 368 } 369 EXPECT_TRUE(I == map.begin()); 370 371 // Test clear() on branched map. 372 map.clear(); 373 EXPECT_TRUE(map.empty()); 374 EXPECT_TRUE(map.begin() == map.end()); 375 } 376 377 // Branched, high, non-coalescing tests. 378 TEST(IntervalMapTest, Branched2) { 379 UU4Map::Allocator allocator; 380 UU4Map map(allocator); 381 382 // Insert enough intervals to force a height >= 2 tree. 383 for (unsigned i = 1; i < 1000; ++i) 384 map.insert(10*i, 10*i+5, i); 385 386 // Tree limits. 387 EXPECT_FALSE(map.empty()); 388 EXPECT_EQ(10u, map.start()); 389 EXPECT_EQ(9995u, map.stop()); 390 391 // Tree lookup. 392 for (unsigned i = 1; i < 1000; ++i) { 393 EXPECT_EQ(0u, map.lookup(10*i-1)); 394 EXPECT_EQ(i, map.lookup(10*i)); 395 EXPECT_EQ(i, map.lookup(10*i+5)); 396 EXPECT_EQ(0u, map.lookup(10*i+6)); 397 } 398 399 // Forward iteration. 400 UU4Map::iterator I = map.begin(); 401 for (unsigned i = 1; i < 1000; ++i) { 402 ASSERT_TRUE(I.valid()); 403 EXPECT_EQ(10*i, I.start()); 404 EXPECT_EQ(10*i+5, I.stop()); 405 EXPECT_EQ(i, *I); 406 ++I; 407 } 408 EXPECT_FALSE(I.valid()); 409 EXPECT_TRUE(I == map.end()); 410 411 // Backwards iteration. 412 for (unsigned i = 999; i; --i) { 413 --I; 414 ASSERT_TRUE(I.valid()); 415 EXPECT_EQ(10*i, I.start()); 416 EXPECT_EQ(10*i+5, I.stop()); 417 EXPECT_EQ(i, *I); 418 } 419 EXPECT_TRUE(I == map.begin()); 420 421 // Test clear() on branched map. 422 map.clear(); 423 EXPECT_TRUE(map.empty()); 424 EXPECT_TRUE(map.begin() == map.end()); 425 } 426 427 // Random insertions, coalescing to a single interval. 428 TEST(IntervalMapTest, RandomCoalescing) { 429 UU4Map::Allocator allocator; 430 UU4Map map(allocator); 431 432 // This is a poor PRNG with maximal period: 433 // x_n = 5 x_{n-1} + 1 mod 2^N 434 435 unsigned x = 100; 436 for (unsigned i = 0; i != 4096; ++i) { 437 map.insert(10*x, 10*x+9, 1); 438 EXPECT_GE(10*x, map.start()); 439 EXPECT_LE(10*x+9, map.stop()); 440 x = (5*x+1)%4096; 441 } 442 443 // Map should be fully coalesced after that exercise. 444 EXPECT_FALSE(map.empty()); 445 EXPECT_EQ(0u, map.start()); 446 EXPECT_EQ(40959u, map.stop()); 447 EXPECT_EQ(1, std::distance(map.begin(), map.end())); 448 449 } 450 451 } // namespace 452