180814287SRaphael Isemann //===-- RangeTest.cpp -----------------------------------------------------===// 2b8093314SPavel Labath // 3b8093314SPavel Labath // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4b8093314SPavel Labath // See https://llvm.org/LICENSE.txt for license information. 5b8093314SPavel Labath // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6b8093314SPavel Labath // 7b8093314SPavel Labath //===----------------------------------------------------------------------===// 8b8093314SPavel Labath 9b8093314SPavel Labath #include "lldb/Utility/RangeMap.h" 10b8093314SPavel Labath #include "gmock/gmock.h" 11b8093314SPavel Labath #include "gtest/gtest.h" 12b8093314SPavel Labath 13b8093314SPavel Labath using namespace lldb_private; 14b8093314SPavel Labath 15*a261eee6SPavel Labath TEST(RangeVector, SignedBaseType) { 16*a261eee6SPavel Labath using RangeVector = RangeVector<int32_t, uint32_t>; 17*a261eee6SPavel Labath using Entry = RangeVector::Entry; 18*a261eee6SPavel Labath 19*a261eee6SPavel Labath RangeVector V; 20*a261eee6SPavel Labath V.Append(10, 5); 21*a261eee6SPavel Labath V.Append(-3, 6); 22*a261eee6SPavel Labath V.Append(-10, 3); 23*a261eee6SPavel Labath V.Sort(); 24*a261eee6SPavel Labath EXPECT_THAT(V, 25*a261eee6SPavel Labath testing::ElementsAre(Entry(-10, 3), Entry(-3, 6), Entry(10, 5))); 26*a261eee6SPavel Labath Entry e = *V.begin(); 27*a261eee6SPavel Labath EXPECT_EQ(e.GetRangeBase(), -10); 28*a261eee6SPavel Labath EXPECT_EQ(e.GetByteSize(), 3u); 29*a261eee6SPavel Labath EXPECT_EQ(e.GetRangeEnd(), -7); 30*a261eee6SPavel Labath EXPECT_TRUE(e.Contains(-10)); 31*a261eee6SPavel Labath EXPECT_TRUE(e.Contains(-8)); 32*a261eee6SPavel Labath EXPECT_FALSE(e.Contains(-7)); 33*a261eee6SPavel Labath EXPECT_TRUE(e.Union(Entry(-8, 2))); 34*a261eee6SPavel Labath EXPECT_EQ(e, Entry(-10, 4)); 35*a261eee6SPavel Labath EXPECT_EQ(e.Intersect(Entry(-7, 3)), Entry(-7, 1)); 36*a261eee6SPavel Labath } 37*a261eee6SPavel Labath 3881d7ebafSPavel Labath TEST(RangeVector, CombineConsecutiveRanges) { 3981d7ebafSPavel Labath using RangeVector = RangeVector<uint32_t, uint32_t>; 4081d7ebafSPavel Labath using Entry = RangeVector::Entry; 4181d7ebafSPavel Labath 4281d7ebafSPavel Labath RangeVector V; 4381d7ebafSPavel Labath V.Append(0, 1); 4481d7ebafSPavel Labath V.Append(5, 1); 4581d7ebafSPavel Labath V.Append(6, 1); 4681d7ebafSPavel Labath V.Append(10, 9); 4781d7ebafSPavel Labath V.Append(15, 1); 4881d7ebafSPavel Labath V.Append(20, 9); 4981d7ebafSPavel Labath V.Append(21, 9); 5081d7ebafSPavel Labath V.Sort(); 5181d7ebafSPavel Labath V.CombineConsecutiveRanges(); 5281d7ebafSPavel Labath EXPECT_THAT(V, testing::ElementsAre(Entry(0, 1), Entry(5, 2), Entry(10, 9), 5381d7ebafSPavel Labath Entry(20, 10))); 5481d7ebafSPavel Labath 5581d7ebafSPavel Labath V.Clear(); 5681d7ebafSPavel Labath V.Append(0, 20); 5781d7ebafSPavel Labath V.Append(5, 1); 5881d7ebafSPavel Labath V.Append(10, 1); 5981d7ebafSPavel Labath V.Sort(); 6081d7ebafSPavel Labath V.CombineConsecutiveRanges(); 6181d7ebafSPavel Labath EXPECT_THAT(V, testing::ElementsAre(Entry(0, 20))); 6281d7ebafSPavel Labath } 6381d7ebafSPavel Labath 645e9c9b32SZequan Wu TEST(RangeVector, GetOverlaps) { 655e9c9b32SZequan Wu using RangeVector = RangeVector<uint32_t, uint32_t>; 665e9c9b32SZequan Wu 675e9c9b32SZequan Wu RangeVector V1; 685e9c9b32SZequan Wu RangeVector V2; 695e9c9b32SZequan Wu RangeVector Expected; 705e9c9b32SZequan Wu // same range 715e9c9b32SZequan Wu V1.Append(0, 1); 725e9c9b32SZequan Wu V2.Append(0, 1); 735e9c9b32SZequan Wu Expected.Append(0, 1); 745e9c9b32SZequan Wu 755e9c9b32SZequan Wu // no overlap 765e9c9b32SZequan Wu V1.Append(2, 2); 775e9c9b32SZequan Wu V2.Append(4, 1); 785e9c9b32SZequan Wu 795e9c9b32SZequan Wu // same base overlap 805e9c9b32SZequan Wu V1.Append(10, 5); 815e9c9b32SZequan Wu V2.Append(10, 3); 825e9c9b32SZequan Wu Expected.Append(10, 3); 835e9c9b32SZequan Wu 845e9c9b32SZequan Wu // same end overlap 855e9c9b32SZequan Wu V1.Append(27, 1); 865e9c9b32SZequan Wu V2.Append(20, 8); 875e9c9b32SZequan Wu Expected.Append(27, 1); 885e9c9b32SZequan Wu 895e9c9b32SZequan Wu // smaller base overlap 905e9c9b32SZequan Wu V1.Append(33, 4); 915e9c9b32SZequan Wu V2.Append(30, 5); 925e9c9b32SZequan Wu Expected.Append(33, 2); 935e9c9b32SZequan Wu 945e9c9b32SZequan Wu // larger base overlap 955e9c9b32SZequan Wu V1.Append(46, 3); 965e9c9b32SZequan Wu V2.Append(40, 7); 975e9c9b32SZequan Wu Expected.Append(46, 1); 985e9c9b32SZequan Wu 995e9c9b32SZequan Wu // encompass 1 range 1005e9c9b32SZequan Wu V1.Append(50, 9); 1015e9c9b32SZequan Wu V2.Append(51, 7); 1025e9c9b32SZequan Wu Expected.Append(51, 7); 1035e9c9b32SZequan Wu 1045e9c9b32SZequan Wu // encompass 2 ranges 1055e9c9b32SZequan Wu V1.Append(60, 9); 1065e9c9b32SZequan Wu V2.Append(60, 3); 1075e9c9b32SZequan Wu V2.Append(65, 3); 1085e9c9b32SZequan Wu Expected.Append(60, 3); 1095e9c9b32SZequan Wu Expected.Append(65, 3); 1105e9c9b32SZequan Wu 1115e9c9b32SZequan Wu V1.Sort(); 1125e9c9b32SZequan Wu V2.Sort(); 1135e9c9b32SZequan Wu Expected.Sort(); 1145e9c9b32SZequan Wu 1155e9c9b32SZequan Wu EXPECT_EQ(RangeVector::GetOverlaps(V1, V2), Expected); 1165e9c9b32SZequan Wu EXPECT_EQ(RangeVector::GetOverlaps(V2, V1), Expected); 1175e9c9b32SZequan Wu } 1185e9c9b32SZequan Wu 119b8093314SPavel Labath using RangeDataVectorT = RangeDataVector<uint32_t, uint32_t, uint32_t>; 120b8093314SPavel Labath using EntryT = RangeDataVectorT::Entry; 121b8093314SPavel Labath 122b8093314SPavel Labath static testing::Matcher<const EntryT *> EntryIs(uint32_t ID) { 123b8093314SPavel Labath return testing::Pointee(testing::Field(&EntryT::data, ID)); 124b8093314SPavel Labath } 125b8093314SPavel Labath 126594130dbSUnnar Freyr Erlendsson std::vector<uint32_t> FindEntryIndexes(uint32_t address, RangeDataVectorT map) { 127594130dbSUnnar Freyr Erlendsson std::vector<uint32_t> result; 128594130dbSUnnar Freyr Erlendsson map.FindEntryIndexesThatContain(address, result); 129594130dbSUnnar Freyr Erlendsson return result; 130594130dbSUnnar Freyr Erlendsson } 131594130dbSUnnar Freyr Erlendsson 132b8093314SPavel Labath TEST(RangeDataVector, FindEntryThatContains) { 133b8093314SPavel Labath RangeDataVectorT Map; 134b8093314SPavel Labath uint32_t NextID = 0; 135b8093314SPavel Labath Map.Append(EntryT(0, 10, NextID++)); 136b8093314SPavel Labath Map.Append(EntryT(10, 10, NextID++)); 137b8093314SPavel Labath Map.Append(EntryT(20, 10, NextID++)); 138b8093314SPavel Labath Map.Sort(); 139b8093314SPavel Labath 140b8093314SPavel Labath EXPECT_THAT(Map.FindEntryThatContains(0), EntryIs(0)); 141b8093314SPavel Labath EXPECT_THAT(Map.FindEntryThatContains(9), EntryIs(0)); 142b8093314SPavel Labath EXPECT_THAT(Map.FindEntryThatContains(10), EntryIs(1)); 143b8093314SPavel Labath EXPECT_THAT(Map.FindEntryThatContains(19), EntryIs(1)); 144b8093314SPavel Labath EXPECT_THAT(Map.FindEntryThatContains(20), EntryIs(2)); 145b8093314SPavel Labath EXPECT_THAT(Map.FindEntryThatContains(29), EntryIs(2)); 146b8093314SPavel Labath EXPECT_THAT(Map.FindEntryThatContains(30), nullptr); 147b8093314SPavel Labath } 148b8093314SPavel Labath 149b8093314SPavel Labath TEST(RangeDataVector, FindEntryThatContains_Overlap) { 150b8093314SPavel Labath RangeDataVectorT Map; 151b8093314SPavel Labath uint32_t NextID = 0; 152b8093314SPavel Labath Map.Append(EntryT(0, 40, NextID++)); 153b8093314SPavel Labath Map.Append(EntryT(10, 20, NextID++)); 154b8093314SPavel Labath Map.Append(EntryT(20, 10, NextID++)); 155b8093314SPavel Labath Map.Sort(); 156b8093314SPavel Labath 157b8093314SPavel Labath // With overlapping intervals, the intention seems to be to return the first 158b8093314SPavel Labath // interval which contains the address. 159b8093314SPavel Labath EXPECT_THAT(Map.FindEntryThatContains(25), EntryIs(0)); 160b8093314SPavel Labath 161b8093314SPavel Labath // However, this does not always succeed. 162b8093314SPavel Labath // TODO: This should probably return the range (0, 40) as well. 163b8093314SPavel Labath EXPECT_THAT(Map.FindEntryThatContains(35), nullptr); 164b8093314SPavel Labath } 1652f2f41e1SJan Kratochvil 1662f2f41e1SJan Kratochvil TEST(RangeDataVector, CustomSort) { 1672f2f41e1SJan Kratochvil // First the default ascending order sorting of the data field. 1682f2f41e1SJan Kratochvil auto Map = RangeDataVectorT(); 1692f2f41e1SJan Kratochvil Map.Append(EntryT(0, 10, 50)); 1702f2f41e1SJan Kratochvil Map.Append(EntryT(0, 10, 52)); 1712f2f41e1SJan Kratochvil Map.Append(EntryT(0, 10, 53)); 1722f2f41e1SJan Kratochvil Map.Append(EntryT(0, 10, 51)); 1732f2f41e1SJan Kratochvil Map.Sort(); 1742f2f41e1SJan Kratochvil 1752f2f41e1SJan Kratochvil EXPECT_THAT(Map.GetSize(), 4); 1762f2f41e1SJan Kratochvil EXPECT_THAT(Map.GetEntryRef(0).data, 50); 1772f2f41e1SJan Kratochvil EXPECT_THAT(Map.GetEntryRef(1).data, 51); 1782f2f41e1SJan Kratochvil EXPECT_THAT(Map.GetEntryRef(2).data, 52); 1792f2f41e1SJan Kratochvil EXPECT_THAT(Map.GetEntryRef(3).data, 53); 1802f2f41e1SJan Kratochvil 1812f2f41e1SJan Kratochvil // And then a custom descending order sorting of the data field. 1822f2f41e1SJan Kratochvil class CtorParam {}; 1832f2f41e1SJan Kratochvil class CustomSort { 1842f2f41e1SJan Kratochvil public: 1852f2f41e1SJan Kratochvil CustomSort(CtorParam) {} 1862f2f41e1SJan Kratochvil bool operator()(const uint32_t a_data, const uint32_t b_data) { 1872f2f41e1SJan Kratochvil return a_data > b_data; 1882f2f41e1SJan Kratochvil } 1892f2f41e1SJan Kratochvil }; 1902f2f41e1SJan Kratochvil using RangeDataVectorCustomSortT = 1912f2f41e1SJan Kratochvil RangeDataVector<uint32_t, uint32_t, uint32_t, 0, CustomSort>; 1922f2f41e1SJan Kratochvil using EntryT = RangeDataVectorT::Entry; 1932f2f41e1SJan Kratochvil 1942f2f41e1SJan Kratochvil auto MapC = RangeDataVectorCustomSortT(CtorParam()); 1952f2f41e1SJan Kratochvil MapC.Append(EntryT(0, 10, 50)); 1962f2f41e1SJan Kratochvil MapC.Append(EntryT(0, 10, 52)); 1972f2f41e1SJan Kratochvil MapC.Append(EntryT(0, 10, 53)); 1982f2f41e1SJan Kratochvil MapC.Append(EntryT(0, 10, 51)); 1992f2f41e1SJan Kratochvil MapC.Sort(); 2002f2f41e1SJan Kratochvil 2012f2f41e1SJan Kratochvil EXPECT_THAT(MapC.GetSize(), 4); 2022f2f41e1SJan Kratochvil EXPECT_THAT(MapC.GetEntryRef(0).data, 53); 2032f2f41e1SJan Kratochvil EXPECT_THAT(MapC.GetEntryRef(1).data, 52); 2042f2f41e1SJan Kratochvil EXPECT_THAT(MapC.GetEntryRef(2).data, 51); 2052f2f41e1SJan Kratochvil EXPECT_THAT(MapC.GetEntryRef(3).data, 50); 2062f2f41e1SJan Kratochvil } 207594130dbSUnnar Freyr Erlendsson 208594130dbSUnnar Freyr Erlendsson TEST(RangeDataVector, FindEntryIndexesThatContain) { 209594130dbSUnnar Freyr Erlendsson RangeDataVectorT Map; 210594130dbSUnnar Freyr Erlendsson Map.Append(EntryT(0, 10, 10)); 211594130dbSUnnar Freyr Erlendsson Map.Append(EntryT(10, 10, 11)); 212594130dbSUnnar Freyr Erlendsson Map.Append(EntryT(20, 10, 12)); 213594130dbSUnnar Freyr Erlendsson Map.Sort(); 214594130dbSUnnar Freyr Erlendsson 215594130dbSUnnar Freyr Erlendsson EXPECT_THAT(FindEntryIndexes(0, Map), testing::ElementsAre(10)); 216594130dbSUnnar Freyr Erlendsson EXPECT_THAT(FindEntryIndexes(9, Map), testing::ElementsAre(10)); 217594130dbSUnnar Freyr Erlendsson EXPECT_THAT(FindEntryIndexes(10, Map), testing::ElementsAre(11)); 218594130dbSUnnar Freyr Erlendsson EXPECT_THAT(FindEntryIndexes(19, Map), testing::ElementsAre(11)); 219594130dbSUnnar Freyr Erlendsson EXPECT_THAT(FindEntryIndexes(20, Map), testing::ElementsAre(12)); 220594130dbSUnnar Freyr Erlendsson EXPECT_THAT(FindEntryIndexes(29, Map), testing::ElementsAre(12)); 221594130dbSUnnar Freyr Erlendsson EXPECT_THAT(FindEntryIndexes(30, Map), testing::ElementsAre()); 222594130dbSUnnar Freyr Erlendsson } 223594130dbSUnnar Freyr Erlendsson 224594130dbSUnnar Freyr Erlendsson TEST(RangeDataVector, FindEntryIndexesThatContain_Overlap) { 225594130dbSUnnar Freyr Erlendsson RangeDataVectorT Map; 226594130dbSUnnar Freyr Erlendsson Map.Append(EntryT(0, 40, 10)); 227594130dbSUnnar Freyr Erlendsson Map.Append(EntryT(10, 20, 11)); 228594130dbSUnnar Freyr Erlendsson Map.Append(EntryT(20, 10, 12)); 229594130dbSUnnar Freyr Erlendsson Map.Sort(); 230594130dbSUnnar Freyr Erlendsson 231594130dbSUnnar Freyr Erlendsson EXPECT_THAT(FindEntryIndexes(0, Map), testing::ElementsAre(10)); 232594130dbSUnnar Freyr Erlendsson EXPECT_THAT(FindEntryIndexes(9, Map), testing::ElementsAre(10)); 233594130dbSUnnar Freyr Erlendsson EXPECT_THAT(FindEntryIndexes(10, Map), testing::ElementsAre(10, 11)); 234594130dbSUnnar Freyr Erlendsson EXPECT_THAT(FindEntryIndexes(19, Map), testing::ElementsAre(10, 11)); 235594130dbSUnnar Freyr Erlendsson EXPECT_THAT(FindEntryIndexes(20, Map), testing::ElementsAre(10, 11, 12)); 236594130dbSUnnar Freyr Erlendsson EXPECT_THAT(FindEntryIndexes(29, Map), testing::ElementsAre(10, 11, 12)); 237594130dbSUnnar Freyr Erlendsson EXPECT_THAT(FindEntryIndexes(30, Map), testing::ElementsAre(10)); 238594130dbSUnnar Freyr Erlendsson EXPECT_THAT(FindEntryIndexes(39, Map), testing::ElementsAre(10)); 239594130dbSUnnar Freyr Erlendsson EXPECT_THAT(FindEntryIndexes(40, Map), testing::ElementsAre()); 240594130dbSUnnar Freyr Erlendsson } 241