mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-11-03 14:21:30 +00:00 
			
		
		
		
	monotonic keys. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122093 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			717 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			717 lines
		
	
	
		
			17 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, 4> UUMap;
 | 
						|
 | 
						|
// 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());
 | 
						|
 | 
						|
  // Default constructor and cross-constness compares.
 | 
						|
  UUMap::const_iterator CI;
 | 
						|
  CI = map.begin();
 | 
						|
  EXPECT_TRUE(CI == I);
 | 
						|
  UUMap::iterator I2;
 | 
						|
  I2 = map.end();
 | 
						|
  EXPECT_TRUE(I2 == CI);
 | 
						|
}
 | 
						|
 | 
						|
// 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());
 | 
						|
 | 
						|
  // Change the value.
 | 
						|
  I.setValue(2);
 | 
						|
  ASSERT_TRUE(I.valid());
 | 
						|
  EXPECT_EQ(100u, I.start());
 | 
						|
  EXPECT_EQ(150u, I.stop());
 | 
						|
  EXPECT_EQ(2u, I.value());
 | 
						|
 | 
						|
  // Grow the bounds.
 | 
						|
  I.setStart(0);
 | 
						|
  ASSERT_TRUE(I.valid());
 | 
						|
  EXPECT_EQ(0u, I.start());
 | 
						|
  EXPECT_EQ(150u, I.stop());
 | 
						|
  EXPECT_EQ(2u, I.value());
 | 
						|
 | 
						|
  I.setStop(200);
 | 
						|
  ASSERT_TRUE(I.valid());
 | 
						|
  EXPECT_EQ(0u, I.start());
 | 
						|
  EXPECT_EQ(200u, I.stop());
 | 
						|
  EXPECT_EQ(2u, I.value());
 | 
						|
 | 
						|
  // Shrink the bounds.
 | 
						|
  I.setStart(150);
 | 
						|
  ASSERT_TRUE(I.valid());
 | 
						|
  EXPECT_EQ(150u, I.start());
 | 
						|
  EXPECT_EQ(200u, I.stop());
 | 
						|
  EXPECT_EQ(2u, I.value());
 | 
						|
 | 
						|
  I.setStop(160);
 | 
						|
  ASSERT_TRUE(I.valid());
 | 
						|
  EXPECT_EQ(150u, I.start());
 | 
						|
  EXPECT_EQ(160u, I.stop());
 | 
						|
  EXPECT_EQ(2u, I.value());
 | 
						|
 | 
						|
  // Erase last elem.
 | 
						|
  I.erase();
 | 
						|
  EXPECT_TRUE(map.empty());
 | 
						|
  EXPECT_EQ(0, std::distance(map.begin(), 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());
 | 
						|
 | 
						|
  // Coalesce from the right.
 | 
						|
  map.insert(151, 200, 1);
 | 
						|
  EXPECT_EQ(1, std::distance(map.begin(), map.end()));
 | 
						|
  EXPECT_EQ(90u, map.start());
 | 
						|
  EXPECT_EQ(200u, map.stop());
 | 
						|
 | 
						|
  // Non-coalesce from the left.
 | 
						|
  map.insert(60, 89, 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(89));
 | 
						|
  EXPECT_EQ(1u, map.lookup(90));
 | 
						|
 | 
						|
  UUMap::iterator I = map.begin();
 | 
						|
  EXPECT_EQ(60u, I.start());
 | 
						|
  EXPECT_EQ(89u, I.stop());
 | 
						|
  EXPECT_EQ(2u, I.value());
 | 
						|
  ++I;
 | 
						|
  EXPECT_EQ(90u, 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));
 | 
						|
 | 
						|
  // Erase from the left.
 | 
						|
  map.begin().erase();
 | 
						|
  EXPECT_EQ(2, std::distance(map.begin(), map.end()));
 | 
						|
  EXPECT_EQ(90u, map.start());
 | 
						|
  EXPECT_EQ(210u, map.stop());
 | 
						|
 | 
						|
  // Erase from the right.
 | 
						|
  (--map.end()).erase();
 | 
						|
  EXPECT_EQ(1, std::distance(map.begin(), map.end()));
 | 
						|
  EXPECT_EQ(90u, map.start());
 | 
						|
  EXPECT_EQ(200u, map.stop());
 | 
						|
 | 
						|
  // Add non-coalescing, then trigger coalescing with setValue.
 | 
						|
  map.insert(80, 89, 2);
 | 
						|
  map.insert(201, 210, 2);
 | 
						|
  EXPECT_EQ(3, std::distance(map.begin(), map.end()));
 | 
						|
  (++map.begin()).setValue(2);
 | 
						|
  EXPECT_EQ(1, std::distance(map.begin(), map.end()));
 | 
						|
  I = map.begin();
 | 
						|
  ASSERT_TRUE(I.valid());
 | 
						|
  EXPECT_EQ(80u, I.start());
 | 
						|
  EXPECT_EQ(210u, I.stop());
 | 
						|
  EXPECT_EQ(2u, I.value());
 | 
						|
}
 | 
						|
 | 
						|
// 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());
 | 
						|
 | 
						|
  // Test advanceTo on flat tree.
 | 
						|
  I = map.begin();
 | 
						|
  I.advanceTo(135);
 | 
						|
  ASSERT_TRUE(I.valid());
 | 
						|
  EXPECT_EQ(140u, I.start());
 | 
						|
  EXPECT_EQ(150u, I.stop());
 | 
						|
 | 
						|
  I.advanceTo(145);
 | 
						|
  ASSERT_TRUE(I.valid());
 | 
						|
  EXPECT_EQ(140u, I.start());
 | 
						|
  EXPECT_EQ(150u, I.stop());
 | 
						|
 | 
						|
  I.advanceTo(200);
 | 
						|
  EXPECT_FALSE(I.valid());
 | 
						|
 | 
						|
  I.advanceTo(300);
 | 
						|
  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());
 | 
						|
 | 
						|
  // 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);
 | 
						|
    EXPECT_EQ(10u, map.start());
 | 
						|
    EXPECT_EQ(10*i+5, map.stop());
 | 
						|
  }
 | 
						|
 | 
						|
  // 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 advanceTo in same node.
 | 
						|
  I.advanceTo(20);
 | 
						|
  ASSERT_TRUE(I.valid());
 | 
						|
  EXPECT_EQ(20u, I.start());
 | 
						|
  EXPECT_EQ(25u, I.stop());
 | 
						|
 | 
						|
  // Change value, no coalescing.
 | 
						|
  I.setValue(0);
 | 
						|
  ASSERT_TRUE(I.valid());
 | 
						|
  EXPECT_EQ(20u, I.start());
 | 
						|
  EXPECT_EQ(25u, I.stop());
 | 
						|
  EXPECT_EQ(0u, I.value());
 | 
						|
 | 
						|
  // Close the gap right, no coalescing.
 | 
						|
  I.setStop(29);
 | 
						|
  ASSERT_TRUE(I.valid());
 | 
						|
  EXPECT_EQ(20u, I.start());
 | 
						|
  EXPECT_EQ(29u, I.stop());
 | 
						|
  EXPECT_EQ(0u, I.value());
 | 
						|
 | 
						|
  // Change value, no coalescing.
 | 
						|
  I.setValue(2);
 | 
						|
  ASSERT_TRUE(I.valid());
 | 
						|
  EXPECT_EQ(20u, I.start());
 | 
						|
  EXPECT_EQ(29u, I.stop());
 | 
						|
  EXPECT_EQ(2u, I.value());
 | 
						|
 | 
						|
  // Change value, now coalescing.
 | 
						|
  I.setValue(3);
 | 
						|
  ASSERT_TRUE(I.valid());
 | 
						|
  EXPECT_EQ(20u, I.start());
 | 
						|
  EXPECT_EQ(35u, I.stop());
 | 
						|
  EXPECT_EQ(3u, I.value());
 | 
						|
 | 
						|
  // Close the gap, now coalescing.
 | 
						|
  I.setValue(4);
 | 
						|
  ASSERT_TRUE(I.valid());
 | 
						|
  I.setStop(39);
 | 
						|
  ASSERT_TRUE(I.valid());
 | 
						|
  EXPECT_EQ(20u, I.start());
 | 
						|
  EXPECT_EQ(45u, I.stop());
 | 
						|
  EXPECT_EQ(4u, I.value());
 | 
						|
 | 
						|
  // advanceTo another node.
 | 
						|
  I.advanceTo(200);
 | 
						|
  ASSERT_TRUE(I.valid());
 | 
						|
  EXPECT_EQ(200u, I.start());
 | 
						|
  EXPECT_EQ(205u, I.stop());
 | 
						|
 | 
						|
  // Close the gap left, no coalescing.
 | 
						|
  I.setStart(196);
 | 
						|
  ASSERT_TRUE(I.valid());
 | 
						|
  EXPECT_EQ(196u, I.start());
 | 
						|
  EXPECT_EQ(205u, I.stop());
 | 
						|
  EXPECT_EQ(20u, I.value());
 | 
						|
 | 
						|
  // Change value, no coalescing.
 | 
						|
  I.setValue(0);
 | 
						|
  ASSERT_TRUE(I.valid());
 | 
						|
  EXPECT_EQ(196u, I.start());
 | 
						|
  EXPECT_EQ(205u, I.stop());
 | 
						|
  EXPECT_EQ(0u, I.value());
 | 
						|
 | 
						|
  // Change value, now coalescing.
 | 
						|
  I.setValue(19);
 | 
						|
  ASSERT_TRUE(I.valid());
 | 
						|
  EXPECT_EQ(190u, I.start());
 | 
						|
  EXPECT_EQ(205u, I.stop());
 | 
						|
  EXPECT_EQ(19u, I.value());
 | 
						|
 | 
						|
  // Close the gap, now coalescing.
 | 
						|
  I.setValue(18);
 | 
						|
  ASSERT_TRUE(I.valid());
 | 
						|
  I.setStart(186);
 | 
						|
  ASSERT_TRUE(I.valid());
 | 
						|
  EXPECT_EQ(180u, I.start());
 | 
						|
  EXPECT_EQ(205u, I.stop());
 | 
						|
  EXPECT_EQ(18u, I.value());
 | 
						|
 | 
						|
  // Erase from the front.
 | 
						|
  I = map.begin();
 | 
						|
  for (unsigned i = 0; i != 20; ++i) {
 | 
						|
    I.erase();
 | 
						|
    EXPECT_TRUE(I == map.begin());
 | 
						|
    EXPECT_FALSE(map.empty());
 | 
						|
    EXPECT_EQ(I.start(), map.start());
 | 
						|
    EXPECT_EQ(995u, map.stop());
 | 
						|
  }
 | 
						|
 | 
						|
  // 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) {
 | 
						|
  UUMap::Allocator allocator;
 | 
						|
  UUMap 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.
 | 
						|
  UUMap::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 advanceTo in same node.
 | 
						|
  I.advanceTo(20);
 | 
						|
  ASSERT_TRUE(I.valid());
 | 
						|
  EXPECT_EQ(20u, I.start());
 | 
						|
  EXPECT_EQ(25u, I.stop());
 | 
						|
 | 
						|
  // advanceTo sibling leaf node.
 | 
						|
  I.advanceTo(200);
 | 
						|
  ASSERT_TRUE(I.valid());
 | 
						|
  EXPECT_EQ(200u, I.start());
 | 
						|
  EXPECT_EQ(205u, I.stop());
 | 
						|
 | 
						|
  // advanceTo further.
 | 
						|
  I.advanceTo(2000);
 | 
						|
  ASSERT_TRUE(I.valid());
 | 
						|
  EXPECT_EQ(2000u, I.start());
 | 
						|
  EXPECT_EQ(2005u, I.stop());
 | 
						|
 | 
						|
  // advanceTo beyond end()
 | 
						|
  I.advanceTo(20000);
 | 
						|
  EXPECT_FALSE(I.valid());
 | 
						|
 | 
						|
  // end().advanceTo() is valid as long as x > map.stop()
 | 
						|
  I.advanceTo(30000);
 | 
						|
  EXPECT_FALSE(I.valid());
 | 
						|
 | 
						|
  // Test clear() on branched map.
 | 
						|
  map.clear();
 | 
						|
  EXPECT_TRUE(map.empty());
 | 
						|
  EXPECT_TRUE(map.begin() == map.end());
 | 
						|
}
 | 
						|
 | 
						|
// Random insertions, coalescing to a single interval.
 | 
						|
TEST(IntervalMapTest, RandomCoalescing) {
 | 
						|
  UUMap::Allocator allocator;
 | 
						|
  UUMap map(allocator);
 | 
						|
 | 
						|
  // This is a poor PRNG with maximal period:
 | 
						|
  // x_n = 5 x_{n-1} + 1 mod 2^N
 | 
						|
 | 
						|
  unsigned x = 100;
 | 
						|
  for (unsigned i = 0; i != 4096; ++i) {
 | 
						|
    map.insert(10*x, 10*x+9, 1);
 | 
						|
    EXPECT_GE(10*x, map.start());
 | 
						|
    EXPECT_LE(10*x+9, map.stop());
 | 
						|
    x = (5*x+1)%4096;
 | 
						|
  }
 | 
						|
 | 
						|
  // Map should be fully coalesced after that exercise.
 | 
						|
  EXPECT_FALSE(map.empty());
 | 
						|
  EXPECT_EQ(0u, map.start());
 | 
						|
  EXPECT_EQ(40959u, map.stop());
 | 
						|
  EXPECT_EQ(1, std::distance(map.begin(), map.end()));
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
TEST(IntervalMapOverlapsTest, SmallMaps) {
 | 
						|
  typedef IntervalMapOverlaps<UUMap,UUMap> UUOverlaps;
 | 
						|
  UUMap::Allocator allocator;
 | 
						|
  UUMap mapA(allocator);
 | 
						|
  UUMap mapB(allocator);
 | 
						|
 | 
						|
  // empty, empty.
 | 
						|
  EXPECT_FALSE(UUOverlaps(mapA, mapB).valid());
 | 
						|
 | 
						|
  mapA.insert(1, 2, 3);
 | 
						|
 | 
						|
  // full, empty
 | 
						|
  EXPECT_FALSE(UUOverlaps(mapA, mapB).valid());
 | 
						|
  // empty, full
 | 
						|
  EXPECT_FALSE(UUOverlaps(mapB, mapA).valid());
 | 
						|
 | 
						|
  mapB.insert(3, 4, 5);
 | 
						|
 | 
						|
  // full, full, non-overlapping
 | 
						|
  EXPECT_FALSE(UUOverlaps(mapA, mapB).valid());
 | 
						|
  EXPECT_FALSE(UUOverlaps(mapB, mapA).valid());
 | 
						|
 | 
						|
  // Add an overlapping segment.
 | 
						|
  mapA.insert(4, 5, 6);
 | 
						|
 | 
						|
  UUOverlaps AB(mapA, mapB);
 | 
						|
  ASSERT_TRUE(AB.valid());
 | 
						|
  EXPECT_EQ(4u, AB.a().start());
 | 
						|
  EXPECT_EQ(3u, AB.b().start());
 | 
						|
  ++AB;
 | 
						|
  EXPECT_FALSE(AB.valid());
 | 
						|
 | 
						|
  UUOverlaps BA(mapB, mapA);
 | 
						|
  ASSERT_TRUE(BA.valid());
 | 
						|
  EXPECT_EQ(3u, BA.a().start());
 | 
						|
  EXPECT_EQ(4u, BA.b().start());
 | 
						|
  // advance past end.
 | 
						|
  BA.advanceTo(6);
 | 
						|
  EXPECT_FALSE(BA.valid());
 | 
						|
  // advance an invalid iterator.
 | 
						|
  BA.advanceTo(7);
 | 
						|
  EXPECT_FALSE(BA.valid());
 | 
						|
}
 | 
						|
 | 
						|
TEST(IntervalMapOverlapsTest, BigMaps) {
 | 
						|
  typedef IntervalMapOverlaps<UUMap,UUMap> UUOverlaps;
 | 
						|
  UUMap::Allocator allocator;
 | 
						|
  UUMap mapA(allocator);
 | 
						|
  UUMap mapB(allocator);
 | 
						|
 | 
						|
  // [0;4] [10;14] [20;24] ...
 | 
						|
  for (unsigned n = 0; n != 100; ++n)
 | 
						|
    mapA.insert(10*n, 10*n+4, n);
 | 
						|
 | 
						|
  // [5;6] [15;16] [25;26] ...
 | 
						|
  for (unsigned n = 10; n != 20; ++n)
 | 
						|
    mapB.insert(10*n+5, 10*n+6, n);
 | 
						|
 | 
						|
  // [208;209] [218;219] ...
 | 
						|
  for (unsigned n = 20; n != 30; ++n)
 | 
						|
    mapB.insert(10*n+8, 10*n+9, n);
 | 
						|
 | 
						|
  // insert some overlapping segments.
 | 
						|
  mapB.insert(400, 400, 400);
 | 
						|
  mapB.insert(401, 401, 401);
 | 
						|
  mapB.insert(402, 500, 402);
 | 
						|
  mapB.insert(600, 601, 402);
 | 
						|
 | 
						|
  UUOverlaps AB(mapA, mapB);
 | 
						|
  ASSERT_TRUE(AB.valid());
 | 
						|
  EXPECT_EQ(400u, AB.a().start());
 | 
						|
  EXPECT_EQ(400u, AB.b().start());
 | 
						|
  ++AB;
 | 
						|
  ASSERT_TRUE(AB.valid());
 | 
						|
  EXPECT_EQ(400u, AB.a().start());
 | 
						|
  EXPECT_EQ(401u, AB.b().start());
 | 
						|
  ++AB;
 | 
						|
  ASSERT_TRUE(AB.valid());
 | 
						|
  EXPECT_EQ(400u, AB.a().start());
 | 
						|
  EXPECT_EQ(402u, AB.b().start());
 | 
						|
  ++AB;
 | 
						|
  ASSERT_TRUE(AB.valid());
 | 
						|
  EXPECT_EQ(410u, AB.a().start());
 | 
						|
  EXPECT_EQ(402u, AB.b().start());
 | 
						|
  ++AB;
 | 
						|
  ASSERT_TRUE(AB.valid());
 | 
						|
  EXPECT_EQ(420u, AB.a().start());
 | 
						|
  EXPECT_EQ(402u, AB.b().start());
 | 
						|
  AB.skipB();
 | 
						|
  ASSERT_TRUE(AB.valid());
 | 
						|
  EXPECT_EQ(600u, AB.a().start());
 | 
						|
  EXPECT_EQ(600u, AB.b().start());
 | 
						|
  ++AB;
 | 
						|
  EXPECT_FALSE(AB.valid());
 | 
						|
 | 
						|
  // Test advanceTo.
 | 
						|
  UUOverlaps AB2(mapA, mapB);
 | 
						|
  AB2.advanceTo(410);
 | 
						|
  ASSERT_TRUE(AB2.valid());
 | 
						|
  EXPECT_EQ(410u, AB2.a().start());
 | 
						|
  EXPECT_EQ(402u, AB2.b().start());
 | 
						|
 | 
						|
  // It is valid to advanceTo with any monotonic sequence.
 | 
						|
  AB2.advanceTo(411);
 | 
						|
  ASSERT_TRUE(AB2.valid());
 | 
						|
  EXPECT_EQ(410u, AB2.a().start());
 | 
						|
  EXPECT_EQ(402u, AB2.b().start());
 | 
						|
 | 
						|
  // Check reversed maps.
 | 
						|
  UUOverlaps BA(mapB, mapA);
 | 
						|
  ASSERT_TRUE(BA.valid());
 | 
						|
  EXPECT_EQ(400u, BA.b().start());
 | 
						|
  EXPECT_EQ(400u, BA.a().start());
 | 
						|
  ++BA;
 | 
						|
  ASSERT_TRUE(BA.valid());
 | 
						|
  EXPECT_EQ(400u, BA.b().start());
 | 
						|
  EXPECT_EQ(401u, BA.a().start());
 | 
						|
  ++BA;
 | 
						|
  ASSERT_TRUE(BA.valid());
 | 
						|
  EXPECT_EQ(400u, BA.b().start());
 | 
						|
  EXPECT_EQ(402u, BA.a().start());
 | 
						|
  ++BA;
 | 
						|
  ASSERT_TRUE(BA.valid());
 | 
						|
  EXPECT_EQ(410u, BA.b().start());
 | 
						|
  EXPECT_EQ(402u, BA.a().start());
 | 
						|
  ++BA;
 | 
						|
  ASSERT_TRUE(BA.valid());
 | 
						|
  EXPECT_EQ(420u, BA.b().start());
 | 
						|
  EXPECT_EQ(402u, BA.a().start());
 | 
						|
  BA.skipA();
 | 
						|
  ASSERT_TRUE(BA.valid());
 | 
						|
  EXPECT_EQ(600u, BA.b().start());
 | 
						|
  EXPECT_EQ(600u, BA.a().start());
 | 
						|
  ++BA;
 | 
						|
  EXPECT_FALSE(BA.valid());
 | 
						|
 | 
						|
  // Test advanceTo.
 | 
						|
  UUOverlaps BA2(mapB, mapA);
 | 
						|
  BA2.advanceTo(410);
 | 
						|
  ASSERT_TRUE(BA2.valid());
 | 
						|
  EXPECT_EQ(410u, BA2.b().start());
 | 
						|
  EXPECT_EQ(402u, BA2.a().start());
 | 
						|
 | 
						|
  BA2.advanceTo(411);
 | 
						|
  ASSERT_TRUE(BA2.valid());
 | 
						|
  EXPECT_EQ(410u, BA2.b().start());
 | 
						|
  EXPECT_EQ(402u, BA2.a().start());
 | 
						|
}
 | 
						|
 | 
						|
} // namespace
 |