428 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			428 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===---- ADT/IntervalMapTest.cpp - IntervalMap unit tests ------*- C++ -*-===//
 | |
| //
 | |
| //                     The LLVM Compiler Infrastructure
 | |
| //
 | |
| // This file is distributed under the University of Illinois Open Source
 | |
| // License. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #include "llvm/ADT/IntervalMap.h"
 | |
| #include "gtest/gtest.h"
 | |
| 
 | |
| using namespace llvm;
 | |
| 
 | |
| namespace {
 | |
| 
 | |
| typedef IntervalMap<unsigned, unsigned> UUMap;
 | |
| typedef IntervalMap<unsigned, unsigned, 4> UU4Map;
 | |
| 
 | |
| // Empty map tests
 | |
| TEST(IntervalMapTest, EmptyMap) {
 | |
|   UUMap::Allocator allocator;
 | |
|   UUMap map(allocator);
 | |
|   EXPECT_TRUE(map.empty());
 | |
| 
 | |
|   // Lookup on empty map.
 | |
|   EXPECT_EQ(0u, map.lookup(0));
 | |
|   EXPECT_EQ(7u, map.lookup(0, 7));
 | |
|   EXPECT_EQ(0u, map.lookup(~0u-1));
 | |
|   EXPECT_EQ(7u, map.lookup(~0u-1, 7));
 | |
| 
 | |
|   // Iterators.
 | |
|   EXPECT_TRUE(map.begin() == map.begin());
 | |
|   EXPECT_TRUE(map.begin() == map.end());
 | |
|   EXPECT_TRUE(map.end() == map.end());
 | |
|   EXPECT_FALSE(map.begin() != map.begin());
 | |
|   EXPECT_FALSE(map.begin() != map.end());
 | |
|   EXPECT_FALSE(map.end() != map.end());
 | |
|   EXPECT_FALSE(map.begin().valid());
 | |
|   EXPECT_FALSE(map.end().valid());
 | |
|   UUMap::iterator I = map.begin();
 | |
|   EXPECT_FALSE(I.valid());
 | |
|   EXPECT_TRUE(I == map.end());
 | |
| }
 | |
| 
 | |
| // Single entry map tests
 | |
| TEST(IntervalMapTest, SingleEntryMap) {
 | |
|   UUMap::Allocator allocator;
 | |
|   UUMap map(allocator);
 | |
|   map.insert(100, 150, 1);
 | |
|   EXPECT_FALSE(map.empty());
 | |
| 
 | |
|   // Lookup around interval.
 | |
|   EXPECT_EQ(0u, map.lookup(0));
 | |
|   EXPECT_EQ(0u, map.lookup(99));
 | |
|   EXPECT_EQ(1u, map.lookup(100));
 | |
|   EXPECT_EQ(1u, map.lookup(101));
 | |
|   EXPECT_EQ(1u, map.lookup(125));
 | |
|   EXPECT_EQ(1u, map.lookup(149));
 | |
|   EXPECT_EQ(1u, map.lookup(150));
 | |
|   EXPECT_EQ(0u, map.lookup(151));
 | |
|   EXPECT_EQ(0u, map.lookup(200));
 | |
|   EXPECT_EQ(0u, map.lookup(~0u-1));
 | |
| 
 | |
|   // Iterators.
 | |
|   EXPECT_TRUE(map.begin() == map.begin());
 | |
|   EXPECT_FALSE(map.begin() == map.end());
 | |
|   EXPECT_TRUE(map.end() == map.end());
 | |
|   EXPECT_TRUE(map.begin().valid());
 | |
|   EXPECT_FALSE(map.end().valid());
 | |
| 
 | |
|   // Iter deref.
 | |
|   UUMap::iterator I = map.begin();
 | |
|   ASSERT_TRUE(I.valid());
 | |
|   EXPECT_EQ(100u, I.start());
 | |
|   EXPECT_EQ(150u, I.stop());
 | |
|   EXPECT_EQ(1u, I.value());
 | |
| 
 | |
|   // Preincrement.
 | |
|   ++I;
 | |
|   EXPECT_FALSE(I.valid());
 | |
|   EXPECT_FALSE(I == map.begin());
 | |
|   EXPECT_TRUE(I == map.end());
 | |
| 
 | |
|   // PreDecrement.
 | |
|   --I;
 | |
|   ASSERT_TRUE(I.valid());
 | |
|   EXPECT_EQ(100u, I.start());
 | |
|   EXPECT_EQ(150u, I.stop());
 | |
|   EXPECT_EQ(1u, I.value());
 | |
|   EXPECT_TRUE(I == map.begin());
 | |
|   EXPECT_FALSE(I == map.end());
 | |
| }
 | |
| 
 | |
| // Flat coalescing tests.
 | |
| TEST(IntervalMapTest, RootCoalescing) {
 | |
|   UUMap::Allocator allocator;
 | |
|   UUMap map(allocator);
 | |
|   map.insert(100, 150, 1);
 | |
| 
 | |
|   // Coalesce from the left.
 | |
|   map.insert(90, 99, 1);
 | |
|   EXPECT_EQ(1, std::distance(map.begin(), map.end()));
 | |
|   EXPECT_EQ(90u, map.start());
 | |
|   EXPECT_EQ(150u, map.stop());
 | |
| 
 | |
|   // Overlap left.
 | |
|   map.insert(80, 100, 1);
 | |
|   EXPECT_EQ(1, std::distance(map.begin(), map.end()));
 | |
|   EXPECT_EQ(80u, map.start());
 | |
|   EXPECT_EQ(150u, map.stop());
 | |
| 
 | |
|   // Inside.
 | |
|   map.insert(100, 130, 1);
 | |
|   EXPECT_EQ(1, std::distance(map.begin(), map.end()));
 | |
|   EXPECT_EQ(80u, map.start());
 | |
|   EXPECT_EQ(150u, map.stop());
 | |
| 
 | |
|   // Overlap both.
 | |
|   map.insert(70, 160, 1);
 | |
|   EXPECT_EQ(1, std::distance(map.begin(), map.end()));
 | |
|   EXPECT_EQ(70u, map.start());
 | |
|   EXPECT_EQ(160u, map.stop());
 | |
| 
 | |
|   // Overlap right.
 | |
|   map.insert(80, 170, 1);
 | |
|   EXPECT_EQ(1, std::distance(map.begin(), map.end()));
 | |
|   EXPECT_EQ(70u, map.start());
 | |
|   EXPECT_EQ(170u, map.stop());
 | |
| 
 | |
|   // Coalesce from the right.
 | |
|   map.insert(170, 200, 1);
 | |
|   EXPECT_EQ(1, std::distance(map.begin(), map.end()));
 | |
|   EXPECT_EQ(70u, map.start());
 | |
|   EXPECT_EQ(200u, map.stop());
 | |
| 
 | |
|   // Non-coalesce from the left.
 | |
|   map.insert(60, 69, 2);
 | |
|   EXPECT_EQ(2, std::distance(map.begin(), map.end()));
 | |
|   EXPECT_EQ(60u, map.start());
 | |
|   EXPECT_EQ(200u, map.stop());
 | |
|   EXPECT_EQ(2u, map.lookup(69));
 | |
|   EXPECT_EQ(1u, map.lookup(70));
 | |
| 
 | |
|   UUMap::iterator I = map.begin();
 | |
|   EXPECT_EQ(60u, I.start());
 | |
|   EXPECT_EQ(69u, I.stop());
 | |
|   EXPECT_EQ(2u, I.value());
 | |
|   ++I;
 | |
|   EXPECT_EQ(70u, I.start());
 | |
|   EXPECT_EQ(200u, I.stop());
 | |
|   EXPECT_EQ(1u, I.value());
 | |
|   ++I;
 | |
|   EXPECT_FALSE(I.valid());
 | |
| 
 | |
|   // Non-coalesce from the right.
 | |
|   map.insert(201, 210, 2);
 | |
|   EXPECT_EQ(3, std::distance(map.begin(), map.end()));
 | |
|   EXPECT_EQ(60u, map.start());
 | |
|   EXPECT_EQ(210u, map.stop());
 | |
|   EXPECT_EQ(2u, map.lookup(201));
 | |
|   EXPECT_EQ(1u, map.lookup(200));
 | |
| }
 | |
| 
 | |
| // Flat multi-coalescing tests.
 | |
| TEST(IntervalMapTest, RootMultiCoalescing) {
 | |
|   UUMap::Allocator allocator;
 | |
|   UUMap map(allocator);
 | |
|   map.insert(140, 150, 1);
 | |
|   map.insert(160, 170, 1);
 | |
|   map.insert(100, 110, 1);
 | |
|   map.insert(120, 130, 1);
 | |
|   EXPECT_EQ(4, std::distance(map.begin(), map.end()));
 | |
|   EXPECT_EQ(100u, map.start());
 | |
|   EXPECT_EQ(170u, map.stop());
 | |
| 
 | |
|   // Verify inserts.
 | |
|   UUMap::iterator I = map.begin();
 | |
|   EXPECT_EQ(100u, I.start());
 | |
|   EXPECT_EQ(110u, I.stop());
 | |
|   ++I;
 | |
|   EXPECT_EQ(120u, I.start());
 | |
|   EXPECT_EQ(130u, I.stop());
 | |
|   ++I;
 | |
|   EXPECT_EQ(140u, I.start());
 | |
|   EXPECT_EQ(150u, I.stop());
 | |
|   ++I;
 | |
|   EXPECT_EQ(160u, I.start());
 | |
|   EXPECT_EQ(170u, I.stop());
 | |
|   ++I;
 | |
|   EXPECT_FALSE(I.valid());
 | |
| 
 | |
| 
 | |
|   // Coalesce left with followers.
 | |
|   // [100;110] [120;130] [140;150] [160;170]
 | |
|   map.insert(111, 115, 1);
 | |
|   I = map.begin();
 | |
|   ASSERT_TRUE(I.valid());
 | |
|   EXPECT_EQ(100u, I.start());
 | |
|   EXPECT_EQ(115u, I.stop());
 | |
|   ++I;
 | |
|   ASSERT_TRUE(I.valid());
 | |
|   EXPECT_EQ(120u, I.start());
 | |
|   EXPECT_EQ(130u, I.stop());
 | |
|   ++I;
 | |
|   ASSERT_TRUE(I.valid());
 | |
|   EXPECT_EQ(140u, I.start());
 | |
|   EXPECT_EQ(150u, I.stop());
 | |
|   ++I;
 | |
|   ASSERT_TRUE(I.valid());
 | |
|   EXPECT_EQ(160u, I.start());
 | |
|   EXPECT_EQ(170u, I.stop());
 | |
|   ++I;
 | |
|   EXPECT_FALSE(I.valid());
 | |
| 
 | |
|   // Coalesce right with followers.
 | |
|   // [100;115] [120;130] [140;150] [160;170]
 | |
|   map.insert(135, 139, 1);
 | |
|   I = map.begin();
 | |
|   ASSERT_TRUE(I.valid());
 | |
|   EXPECT_EQ(100u, I.start());
 | |
|   EXPECT_EQ(115u, I.stop());
 | |
|   ++I;
 | |
|   ASSERT_TRUE(I.valid());
 | |
|   EXPECT_EQ(120u, I.start());
 | |
|   EXPECT_EQ(130u, I.stop());
 | |
|   ++I;
 | |
|   ASSERT_TRUE(I.valid());
 | |
|   EXPECT_EQ(135u, I.start());
 | |
|   EXPECT_EQ(150u, I.stop());
 | |
|   ++I;
 | |
|   ASSERT_TRUE(I.valid());
 | |
|   EXPECT_EQ(160u, I.start());
 | |
|   EXPECT_EQ(170u, I.stop());
 | |
|   ++I;
 | |
|   EXPECT_FALSE(I.valid());
 | |
| 
 | |
|   // Coalesce left and right with followers.
 | |
|   // [100;115] [120;130] [135;150] [160;170]
 | |
|   map.insert(131, 134, 1);
 | |
|   I = map.begin();
 | |
|   ASSERT_TRUE(I.valid());
 | |
|   EXPECT_EQ(100u, I.start());
 | |
|   EXPECT_EQ(115u, I.stop());
 | |
|   ++I;
 | |
|   ASSERT_TRUE(I.valid());
 | |
|   EXPECT_EQ(120u, I.start());
 | |
|   EXPECT_EQ(150u, I.stop());
 | |
|   ++I;
 | |
|   ASSERT_TRUE(I.valid());
 | |
|   EXPECT_EQ(160u, I.start());
 | |
|   EXPECT_EQ(170u, I.stop());
 | |
|   ++I;
 | |
|   EXPECT_FALSE(I.valid());
 | |
| 
 | |
|   // Coalesce multiple with overlap right.
 | |
|   // [100;115] [120;150] [160;170]
 | |
|   map.insert(116, 165, 1);
 | |
|   I = map.begin();
 | |
|   ASSERT_TRUE(I.valid());
 | |
|   EXPECT_EQ(100u, I.start());
 | |
|   EXPECT_EQ(170u, I.stop());
 | |
|   ++I;
 | |
|   EXPECT_FALSE(I.valid());
 | |
| 
 | |
|   // Coalesce multiple with overlap left
 | |
|   // [100;170]
 | |
|   map.insert(180, 190, 1);
 | |
|   map.insert(200, 210, 1);
 | |
|   map.insert(220, 230, 1);
 | |
|   // [100;170] [180;190] [200;210] [220;230]
 | |
|   map.insert(160, 199, 1);
 | |
|   I = map.begin();
 | |
|   ASSERT_TRUE(I.valid());
 | |
|   EXPECT_EQ(100u, I.start());
 | |
|   EXPECT_EQ(210u, I.stop());
 | |
|   ++I;
 | |
|   ASSERT_TRUE(I.valid());
 | |
|   EXPECT_EQ(220u, I.start());
 | |
|   EXPECT_EQ(230u, I.stop());
 | |
|   ++I;
 | |
|   EXPECT_FALSE(I.valid());
 | |
| 
 | |
|   // Overwrite 2 from gap to gap.
 | |
|   // [100;210] [220;230]
 | |
|   map.insert(50, 250, 1);
 | |
|   I = map.begin();
 | |
|   ASSERT_TRUE(I.valid());
 | |
|   EXPECT_EQ(50u, I.start());
 | |
|   EXPECT_EQ(250u, I.stop());
 | |
|   ++I;
 | |
|   EXPECT_FALSE(I.valid());
 | |
| 
 | |
|   // Coalesce at end of full root.
 | |
|   // [50;250]
 | |
|   map.insert(260, 270, 1);
 | |
|   map.insert(280, 290, 1);
 | |
|   map.insert(300, 310, 1);
 | |
|   // [50;250] [260;270] [280;290] [300;310]
 | |
|   map.insert(311, 320, 1);
 | |
|   I = map.begin();
 | |
|   ASSERT_TRUE(I.valid());
 | |
|   EXPECT_EQ(50u, I.start());
 | |
|   EXPECT_EQ(250u, I.stop());
 | |
|   ++I;
 | |
|   ASSERT_TRUE(I.valid());
 | |
|   EXPECT_EQ(260u, I.start());
 | |
|   EXPECT_EQ(270u, I.stop());
 | |
|   ++I;
 | |
|   ASSERT_TRUE(I.valid());
 | |
|   EXPECT_EQ(280u, I.start());
 | |
|   EXPECT_EQ(290u, I.stop());
 | |
|   ++I;
 | |
|   ASSERT_TRUE(I.valid());
 | |
|   EXPECT_EQ(300u, I.start());
 | |
|   EXPECT_EQ(320u, I.stop());
 | |
|   ++I;
 | |
|   EXPECT_FALSE(I.valid());
 | |
| 
 | |
|   // Test clear() on non-branched map.
 | |
|   map.clear();
 | |
|   EXPECT_TRUE(map.empty());
 | |
|   EXPECT_TRUE(map.begin() == map.end());
 | |
| }
 | |
| 
 | |
| // Branched, non-coalescing tests.
 | |
| TEST(IntervalMapTest, Branched) {
 | |
|   UUMap::Allocator allocator;
 | |
|   UUMap map(allocator);
 | |
| 
 | |
|   // Insert enough intervals to force a branched tree.
 | |
|   // This creates 9 leaf nodes with 11 elements each, tree height = 1.
 | |
|   for (unsigned i = 1; i < 100; ++i)
 | |
|     map.insert(10*i, 10*i+5, i);
 | |
| 
 | |
|   // Tree limits.
 | |
|   EXPECT_FALSE(map.empty());
 | |
|   EXPECT_EQ(10u, map.start());
 | |
|   EXPECT_EQ(995u, map.stop());
 | |
| 
 | |
|   // Tree lookup.
 | |
|   for (unsigned i = 1; i < 100; ++i) {
 | |
|     EXPECT_EQ(0u, map.lookup(10*i-1));
 | |
|     EXPECT_EQ(i, map.lookup(10*i));
 | |
|     EXPECT_EQ(i, map.lookup(10*i+5));
 | |
|     EXPECT_EQ(0u, map.lookup(10*i+6));
 | |
|   }
 | |
| 
 | |
|   // Forward iteration.
 | |
|   UUMap::iterator I = map.begin();
 | |
|   for (unsigned i = 1; i < 100; ++i) {
 | |
|     ASSERT_TRUE(I.valid());
 | |
|     EXPECT_EQ(10*i, I.start());
 | |
|     EXPECT_EQ(10*i+5, I.stop());
 | |
|     EXPECT_EQ(i, *I);
 | |
|     ++I;
 | |
|   }
 | |
|   EXPECT_FALSE(I.valid());
 | |
|   EXPECT_TRUE(I == map.end());
 | |
| 
 | |
|   // Backwards iteration.
 | |
|   for (unsigned i = 99; i; --i) {
 | |
|     --I;
 | |
|     ASSERT_TRUE(I.valid());
 | |
|     EXPECT_EQ(10*i, I.start());
 | |
|     EXPECT_EQ(10*i+5, I.stop());
 | |
|     EXPECT_EQ(i, *I);
 | |
|   }
 | |
|   EXPECT_TRUE(I == map.begin());
 | |
| 
 | |
|   // Test clear() on branched map.
 | |
|   map.clear();
 | |
|   EXPECT_TRUE(map.empty());
 | |
|   EXPECT_TRUE(map.begin() == map.end());
 | |
| }
 | |
| 
 | |
| // Branched, high, non-coalescing tests.
 | |
| TEST(IntervalMapTest, Branched2) {
 | |
|   UU4Map::Allocator allocator;
 | |
|   UU4Map map(allocator);
 | |
| 
 | |
|   // Insert enough intervals to force a height >= 2 tree.
 | |
|   for (unsigned i = 1; i < 1000; ++i)
 | |
|     map.insert(10*i, 10*i+5, i);
 | |
| 
 | |
|   // Tree limits.
 | |
|   EXPECT_FALSE(map.empty());
 | |
|   EXPECT_EQ(10u, map.start());
 | |
|   EXPECT_EQ(9995u, map.stop());
 | |
| 
 | |
|   // Tree lookup.
 | |
|   for (unsigned i = 1; i < 1000; ++i) {
 | |
|     EXPECT_EQ(0u, map.lookup(10*i-1));
 | |
|     EXPECT_EQ(i, map.lookup(10*i));
 | |
|     EXPECT_EQ(i, map.lookup(10*i+5));
 | |
|     EXPECT_EQ(0u, map.lookup(10*i+6));
 | |
|   }
 | |
| 
 | |
|   // Forward iteration.
 | |
|   UU4Map::iterator I = map.begin();
 | |
|   for (unsigned i = 1; i < 1000; ++i) {
 | |
|     ASSERT_TRUE(I.valid());
 | |
|     EXPECT_EQ(10*i, I.start());
 | |
|     EXPECT_EQ(10*i+5, I.stop());
 | |
|     EXPECT_EQ(i, *I);
 | |
|     ++I;
 | |
|   }
 | |
|   EXPECT_FALSE(I.valid());
 | |
|   EXPECT_TRUE(I == map.end());
 | |
| 
 | |
|   // Backwards iteration.
 | |
|   for (unsigned i = 999; i; --i) {
 | |
|     --I;
 | |
|     ASSERT_TRUE(I.valid());
 | |
|     EXPECT_EQ(10*i, I.start());
 | |
|     EXPECT_EQ(10*i+5, I.stop());
 | |
|     EXPECT_EQ(i, *I);
 | |
|   }
 | |
|   EXPECT_TRUE(I == map.begin());
 | |
| 
 | |
|   // Test clear() on branched map.
 | |
|   map.clear();
 | |
|   EXPECT_TRUE(map.empty());
 | |
|   EXPECT_TRUE(map.begin() == map.end());
 | |
| }
 | |
| 
 | |
| } // namespace
 |