Revert "[ORC-RT] Add IntervalMap and IntervalSet collections."
This reverts commit ab59185fbf.
It looks like this commit is missing interval_set_test.cpp.
This commit is contained in:
@@ -1,153 +0,0 @@
|
||||
//===--------- interval_map.h - A sorted interval map -----------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Implements a coalescing interval map.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef ORC_RT_INTERVAL_MAP_H
|
||||
#define ORC_RT_INTERVAL_MAP_H
|
||||
|
||||
#include "adt.h"
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
|
||||
namespace __orc_rt {
|
||||
|
||||
enum class IntervalCoalescing { Enabled, Disabled };
|
||||
|
||||
/// Maps intervals to keys with optional coalescing.
|
||||
///
|
||||
/// NOTE: The interface is kept mostly compatible with LLVM's IntervalMap
|
||||
/// collection to make it easy to swap over in the future if we choose
|
||||
/// to.
|
||||
template <typename KeyT, typename ValT, IntervalCoalescing Coalescing>
|
||||
class IntervalMap {
|
||||
private:
|
||||
using KeyPairT = std::pair<KeyT, KeyT>;
|
||||
|
||||
struct Compare {
|
||||
using is_transparent = std::true_type;
|
||||
bool operator()(const KeyPairT &LHS, const KeyPairT &RHS) const {
|
||||
return LHS < RHS;
|
||||
}
|
||||
bool operator()(const KeyPairT &LHS, const KeyT &RHS) const {
|
||||
return LHS.first < RHS;
|
||||
}
|
||||
bool operator()(const KeyT &LHS, const KeyPairT &RHS) const {
|
||||
return LHS < RHS.first;
|
||||
}
|
||||
};
|
||||
|
||||
using ImplMap = std::map<KeyPairT, ValT, Compare>;
|
||||
|
||||
public:
|
||||
using iterator = typename ImplMap::iterator;
|
||||
using const_iterator = typename ImplMap::const_iterator;
|
||||
using size_type = typename ImplMap::size_type;
|
||||
|
||||
bool empty() const { return Impl.empty(); }
|
||||
|
||||
void clear() { Impl.clear(); }
|
||||
|
||||
iterator begin() { return Impl.begin(); }
|
||||
iterator end() { return Impl.end(); }
|
||||
|
||||
const_iterator begin() const { return Impl.begin(); }
|
||||
const_iterator end() const { return Impl.end(); }
|
||||
|
||||
iterator find(KeyT K) {
|
||||
// Early out if the key is clearly outside the range.
|
||||
if (empty() || K < begin()->first.first ||
|
||||
K >= std::prev(end())->first.second)
|
||||
return end();
|
||||
|
||||
auto I = Impl.upper_bound(K);
|
||||
assert(I != begin() && "Should have hit early out above");
|
||||
I = std::prev(I);
|
||||
if (K < I->first.second)
|
||||
return I;
|
||||
return end();
|
||||
}
|
||||
|
||||
const_iterator find(KeyT K) const {
|
||||
return const_cast<IntervalMap<KeyT, ValT, Coalescing> *>(this)->find(K);
|
||||
}
|
||||
|
||||
ValT lookup(KeyT K, ValT NotFound = ValT()) const {
|
||||
auto I = find(K);
|
||||
if (I == end())
|
||||
return NotFound;
|
||||
return I->second;
|
||||
}
|
||||
|
||||
void insert(KeyT KS, KeyT KE, ValT V) {
|
||||
if (Coalescing == IntervalCoalescing::Enabled) {
|
||||
auto J = Impl.upper_bound(KS);
|
||||
|
||||
// Coalesce-right if possible. Either way, J points at our insertion
|
||||
// point.
|
||||
if (J != end() && KE == J->first.first && J->second == V) {
|
||||
KE = J->first.second;
|
||||
auto Tmp = J++;
|
||||
Impl.erase(Tmp);
|
||||
}
|
||||
|
||||
// Coalesce-left if possible.
|
||||
if (J != begin()) {
|
||||
auto I = std::prev(J);
|
||||
if (I->first.second == KS && I->second == V) {
|
||||
KS = I->first.first;
|
||||
Impl.erase(I);
|
||||
}
|
||||
}
|
||||
Impl.insert(J, std::make_pair(std::make_pair(KS, KE), std::move(V)));
|
||||
} else
|
||||
Impl.insert(std::make_pair(std::make_pair(KS, KE), std::move(V)));
|
||||
}
|
||||
|
||||
// Erase [KS, KE), which must be entirely containing within one existing
|
||||
// range in the map. Removal is allowed to split the range.
|
||||
void erase(KeyT KS, KeyT KE) {
|
||||
if (empty())
|
||||
return;
|
||||
|
||||
auto J = Impl.upper_bound(KS);
|
||||
|
||||
// Check previous range. Bail out if range to remove is entirely after
|
||||
// it.
|
||||
auto I = std::prev(J);
|
||||
if (KS >= I->first.second)
|
||||
return;
|
||||
|
||||
// Assert that range is wholly contained.
|
||||
assert(KE <= I->first.second);
|
||||
|
||||
auto Tmp = std::move(*I);
|
||||
Impl.erase(I);
|
||||
|
||||
// Split-right -- introduce right-split range.
|
||||
if (KE < Tmp.first.second) {
|
||||
Impl.insert(
|
||||
J, std::make_pair(std::make_pair(KE, Tmp.first.second), Tmp.second));
|
||||
J = std::prev(J);
|
||||
}
|
||||
|
||||
// Split-left -- introduce left-split range.
|
||||
if (KS > Tmp.first.first)
|
||||
Impl.insert(
|
||||
J, std::make_pair(std::make_pair(Tmp.first.first, KS), Tmp.second));
|
||||
}
|
||||
|
||||
private:
|
||||
ImplMap Impl;
|
||||
};
|
||||
|
||||
} // End namespace __orc_rt
|
||||
|
||||
#endif // ORC_RT_INTERVAL_MAP_H
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "common.h"
|
||||
#include "debug.h"
|
||||
#include "error.h"
|
||||
#include "interval_map.h"
|
||||
#include "wrapper_function_utils.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@@ -5,8 +5,6 @@ set(UNITTEST_SOURCES
|
||||
error_test.cpp
|
||||
executor_address_test.cpp
|
||||
extensible_rtti_test.cpp
|
||||
interval_map_test.cpp
|
||||
interval_set_test.cpp
|
||||
orc_unit_test_main.cpp
|
||||
wrapper_function_utils_test.cpp
|
||||
simple_packed_serialization_test.cpp
|
||||
|
||||
@@ -1,188 +0,0 @@
|
||||
//===-- interval_map_test.cpp ---------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file is a part of the ORC runtime.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "interval_map.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using namespace __orc_rt;
|
||||
|
||||
TEST(IntervalMapTest, DefaultConstructed) {
|
||||
// Check that a default-constructed IntervalMap behaves as expected.
|
||||
IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M;
|
||||
|
||||
EXPECT_TRUE(M.empty());
|
||||
EXPECT_TRUE(M.begin() == M.end());
|
||||
EXPECT_TRUE(M.find(0) == M.end());
|
||||
}
|
||||
|
||||
TEST(IntervalMapTest, InsertSingleElement) {
|
||||
// Check that a map with a single element inserted behaves as expected.
|
||||
IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M;
|
||||
|
||||
M.insert(7, 8, 42);
|
||||
|
||||
EXPECT_FALSE(M.empty());
|
||||
EXPECT_EQ(std::next(M.begin()), M.end());
|
||||
EXPECT_EQ(M.find(7), M.begin());
|
||||
EXPECT_EQ(M.find(8), M.end());
|
||||
EXPECT_EQ(M.lookup(7), 42U);
|
||||
EXPECT_EQ(M.lookup(8), 0U); // 8 not present, so should return unsigned().
|
||||
}
|
||||
|
||||
TEST(IntervalMapTest, InsertCoalesceWithPrevious) {
|
||||
// Check that insertions coalesce with previous ranges that share the same
|
||||
// value. Also check that they _don't_ coalesce if the values are different.
|
||||
|
||||
// Check that insertion coalesces with previous range when values are equal.
|
||||
IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M1;
|
||||
|
||||
M1.insert(7, 8, 42);
|
||||
M1.insert(8, 9, 42);
|
||||
|
||||
EXPECT_FALSE(M1.empty());
|
||||
EXPECT_EQ(std::next(M1.begin()), M1.end()); // Should see just one range.
|
||||
EXPECT_EQ(M1.find(7), M1.find(8)); // 7 and 8 should point to same range.
|
||||
EXPECT_EQ(M1.lookup(7), 42U); // Value should be preserved.
|
||||
|
||||
// Check that insertion does not coalesce with previous range when values are
|
||||
// not equal.
|
||||
IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M2;
|
||||
|
||||
M2.insert(7, 8, 42);
|
||||
M2.insert(8, 9, 7);
|
||||
|
||||
EXPECT_FALSE(M2.empty());
|
||||
EXPECT_EQ(std::next(std::next(M2.begin())), M2.end()); // Expect two ranges.
|
||||
EXPECT_NE(M2.find(7), M2.find(8)); // 7 and 8 should be different ranges.
|
||||
EXPECT_EQ(M2.lookup(7), 42U); // Keys 7 and 8 should map to different values.
|
||||
EXPECT_EQ(M2.lookup(8), 7U);
|
||||
}
|
||||
|
||||
TEST(IntervalMapTest, InsertCoalesceWithFollowing) {
|
||||
// Check that insertions coalesce with following ranges that share the same
|
||||
// value. Also check that they _don't_ coalesce if the values are different.
|
||||
|
||||
// Check that insertion coalesces with following range when values are equal.
|
||||
IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M1;
|
||||
|
||||
M1.insert(8, 9, 42);
|
||||
M1.insert(7, 8, 42);
|
||||
|
||||
EXPECT_FALSE(M1.empty());
|
||||
EXPECT_EQ(std::next(M1.begin()), M1.end()); // Should see just one range.
|
||||
EXPECT_EQ(M1.find(7), M1.find(8)); // 7 and 8 should point to same range.
|
||||
EXPECT_EQ(M1.lookup(7), 42U); // Value should be preserved.
|
||||
|
||||
// Check that insertion does not coalesce with previous range when values are
|
||||
// not equal.
|
||||
IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M2;
|
||||
|
||||
M2.insert(8, 9, 42);
|
||||
M2.insert(7, 8, 7);
|
||||
|
||||
EXPECT_FALSE(M2.empty());
|
||||
EXPECT_EQ(std::next(std::next(M2.begin())), M2.end()); // Expect two ranges.
|
||||
EXPECT_EQ(M2.lookup(7), 7U); // Keys 7 and 8 should map to different values.
|
||||
EXPECT_EQ(M2.lookup(8), 42U);
|
||||
}
|
||||
|
||||
TEST(IntervalMapTest, InsertCoalesceBoth) {
|
||||
// Check that insertions coalesce with ranges on both sides where posssible.
|
||||
// Also check that they _don't_ coalesce if the values are different.
|
||||
|
||||
// Check that insertion coalesces with both previous and following ranges
|
||||
// when values are equal.
|
||||
IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M1;
|
||||
|
||||
M1.insert(7, 8, 42);
|
||||
M1.insert(9, 10, 42);
|
||||
|
||||
// Check no coalescing yet.
|
||||
EXPECT_NE(M1.find(7), M1.find(9));
|
||||
|
||||
// Insert a 3rd range to trigger coalescing on both sides.
|
||||
M1.insert(8, 9, 42);
|
||||
|
||||
EXPECT_FALSE(M1.empty());
|
||||
EXPECT_EQ(std::next(M1.begin()), M1.end()); // Should see just one range.
|
||||
EXPECT_EQ(M1.find(7), M1.find(8)); // 7, 8, and 9 should point to same range.
|
||||
EXPECT_EQ(M1.find(8), M1.find(9));
|
||||
EXPECT_EQ(M1.lookup(7), 42U); // Value should be preserved.
|
||||
|
||||
// Check that insertion does not coalesce with previous range when values are
|
||||
// not equal.
|
||||
IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M2;
|
||||
|
||||
M2.insert(7, 8, 42);
|
||||
M2.insert(8, 9, 7);
|
||||
M2.insert(9, 10, 42);
|
||||
|
||||
EXPECT_FALSE(M2.empty());
|
||||
// Expect three ranges.
|
||||
EXPECT_EQ(std::next(std::next(std::next(M2.begin()))), M2.end());
|
||||
EXPECT_NE(M2.find(7), M2.find(8)); // All keys should map to different ranges.
|
||||
EXPECT_NE(M2.find(8), M2.find(9));
|
||||
EXPECT_EQ(M2.lookup(7), 42U); // Key 7, 8, and 9 should map to different vals.
|
||||
EXPECT_EQ(M2.lookup(8), 7U);
|
||||
EXPECT_EQ(M2.lookup(9), 42U);
|
||||
}
|
||||
|
||||
TEST(IntervalMapTest, EraseSingleElement) {
|
||||
// Check that we can insert and then remove a single range.
|
||||
IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M;
|
||||
|
||||
M.insert(7, 10, 42);
|
||||
EXPECT_FALSE(M.empty());
|
||||
M.erase(7, 10);
|
||||
EXPECT_TRUE(M.empty());
|
||||
}
|
||||
|
||||
TEST(IntervalMapTest, EraseSplittingLeft) {
|
||||
// Check that removal of a trailing subrange succeeds, but leaves the
|
||||
// residual range in-place.
|
||||
IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M;
|
||||
|
||||
M.insert(7, 10, 42);
|
||||
EXPECT_FALSE(M.empty());
|
||||
M.erase(9, 10);
|
||||
EXPECT_EQ(std::next(M.begin()), M.end());
|
||||
EXPECT_EQ(M.begin()->first.first, 7U);
|
||||
EXPECT_EQ(M.begin()->first.second, 9U);
|
||||
}
|
||||
|
||||
TEST(IntervalMapTest, EraseSplittingRight) {
|
||||
// Check that removal of a leading subrange succeeds, but leaves the
|
||||
// residual range in-place.
|
||||
IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M;
|
||||
|
||||
M.insert(7, 10, 42);
|
||||
EXPECT_FALSE(M.empty());
|
||||
M.erase(7, 8);
|
||||
EXPECT_EQ(std::next(M.begin()), M.end());
|
||||
EXPECT_EQ(M.begin()->first.first, 8U);
|
||||
EXPECT_EQ(M.begin()->first.second, 10U);
|
||||
}
|
||||
|
||||
TEST(IntervalMapTest, EraseSplittingBoth) {
|
||||
// Check that removal of an interior subrange leaves both the leading and
|
||||
// trailing residual subranges in-place.
|
||||
IntervalMap<unsigned, unsigned, IntervalCoalescing::Enabled> M;
|
||||
|
||||
M.insert(7, 10, 42);
|
||||
EXPECT_FALSE(M.empty());
|
||||
M.erase(8, 9);
|
||||
EXPECT_EQ(std::next(std::next(M.begin())), M.end());
|
||||
EXPECT_EQ(M.begin()->first.first, 7U);
|
||||
EXPECT_EQ(M.begin()->first.second, 8U);
|
||||
EXPECT_EQ(std::next(M.begin())->first.first, 9U);
|
||||
EXPECT_EQ(std::next(M.begin())->first.second, 10U);
|
||||
}
|
||||
Reference in New Issue
Block a user