xref: /llvm-project/lldb/unittests/Utility/RangeMapTest.cpp (revision a261eee61200cb6aa3eac0e7dc03940a6afd7d54)
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