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 
TEST(RangeVector,CombineConsecutiveRanges)1581d7ebafSPavel Labath TEST(RangeVector, CombineConsecutiveRanges) {
1681d7ebafSPavel Labath   using RangeVector = RangeVector<uint32_t, uint32_t>;
1781d7ebafSPavel Labath   using Entry = RangeVector::Entry;
1881d7ebafSPavel Labath 
1981d7ebafSPavel Labath   RangeVector V;
2081d7ebafSPavel Labath   V.Append(0, 1);
2181d7ebafSPavel Labath   V.Append(5, 1);
2281d7ebafSPavel Labath   V.Append(6, 1);
2381d7ebafSPavel Labath   V.Append(10, 9);
2481d7ebafSPavel Labath   V.Append(15, 1);
2581d7ebafSPavel Labath   V.Append(20, 9);
2681d7ebafSPavel Labath   V.Append(21, 9);
2781d7ebafSPavel Labath   V.Sort();
2881d7ebafSPavel Labath   V.CombineConsecutiveRanges();
2981d7ebafSPavel Labath   EXPECT_THAT(V, testing::ElementsAre(Entry(0, 1), Entry(5, 2), Entry(10, 9),
3081d7ebafSPavel Labath                                       Entry(20, 10)));
3181d7ebafSPavel Labath 
3281d7ebafSPavel Labath   V.Clear();
3381d7ebafSPavel Labath   V.Append(0, 20);
3481d7ebafSPavel Labath   V.Append(5, 1);
3581d7ebafSPavel Labath   V.Append(10, 1);
3681d7ebafSPavel Labath   V.Sort();
3781d7ebafSPavel Labath   V.CombineConsecutiveRanges();
3881d7ebafSPavel Labath   EXPECT_THAT(V, testing::ElementsAre(Entry(0, 20)));
3981d7ebafSPavel Labath }
4081d7ebafSPavel Labath 
TEST(RangeVector,GetOverlaps)41*5e9c9b32SZequan Wu TEST(RangeVector, GetOverlaps) {
42*5e9c9b32SZequan Wu   using RangeVector = RangeVector<uint32_t, uint32_t>;
43*5e9c9b32SZequan Wu 
44*5e9c9b32SZequan Wu   RangeVector V1;
45*5e9c9b32SZequan Wu   RangeVector V2;
46*5e9c9b32SZequan Wu   RangeVector Expected;
47*5e9c9b32SZequan Wu   // same range
48*5e9c9b32SZequan Wu   V1.Append(0, 1);
49*5e9c9b32SZequan Wu   V2.Append(0, 1);
50*5e9c9b32SZequan Wu   Expected.Append(0, 1);
51*5e9c9b32SZequan Wu 
52*5e9c9b32SZequan Wu   // no overlap
53*5e9c9b32SZequan Wu   V1.Append(2, 2);
54*5e9c9b32SZequan Wu   V2.Append(4, 1);
55*5e9c9b32SZequan Wu 
56*5e9c9b32SZequan Wu   // same base overlap
57*5e9c9b32SZequan Wu   V1.Append(10, 5);
58*5e9c9b32SZequan Wu   V2.Append(10, 3);
59*5e9c9b32SZequan Wu   Expected.Append(10, 3);
60*5e9c9b32SZequan Wu 
61*5e9c9b32SZequan Wu   // same end overlap
62*5e9c9b32SZequan Wu   V1.Append(27, 1);
63*5e9c9b32SZequan Wu   V2.Append(20, 8);
64*5e9c9b32SZequan Wu   Expected.Append(27, 1);
65*5e9c9b32SZequan Wu 
66*5e9c9b32SZequan Wu   // smaller base overlap
67*5e9c9b32SZequan Wu   V1.Append(33, 4);
68*5e9c9b32SZequan Wu   V2.Append(30, 5);
69*5e9c9b32SZequan Wu   Expected.Append(33, 2);
70*5e9c9b32SZequan Wu 
71*5e9c9b32SZequan Wu   // larger base overlap
72*5e9c9b32SZequan Wu   V1.Append(46, 3);
73*5e9c9b32SZequan Wu   V2.Append(40, 7);
74*5e9c9b32SZequan Wu   Expected.Append(46, 1);
75*5e9c9b32SZequan Wu 
76*5e9c9b32SZequan Wu   // encompass 1 range
77*5e9c9b32SZequan Wu   V1.Append(50, 9);
78*5e9c9b32SZequan Wu   V2.Append(51, 7);
79*5e9c9b32SZequan Wu   Expected.Append(51, 7);
80*5e9c9b32SZequan Wu 
81*5e9c9b32SZequan Wu   // encompass 2 ranges
82*5e9c9b32SZequan Wu   V1.Append(60, 9);
83*5e9c9b32SZequan Wu   V2.Append(60, 3);
84*5e9c9b32SZequan Wu   V2.Append(65, 3);
85*5e9c9b32SZequan Wu   Expected.Append(60, 3);
86*5e9c9b32SZequan Wu   Expected.Append(65, 3);
87*5e9c9b32SZequan Wu 
88*5e9c9b32SZequan Wu   V1.Sort();
89*5e9c9b32SZequan Wu   V2.Sort();
90*5e9c9b32SZequan Wu   Expected.Sort();
91*5e9c9b32SZequan Wu 
92*5e9c9b32SZequan Wu   EXPECT_EQ(RangeVector::GetOverlaps(V1, V2), Expected);
93*5e9c9b32SZequan Wu   EXPECT_EQ(RangeVector::GetOverlaps(V2, V1), Expected);
94*5e9c9b32SZequan Wu }
95*5e9c9b32SZequan Wu 
96b8093314SPavel Labath using RangeDataVectorT = RangeDataVector<uint32_t, uint32_t, uint32_t>;
97b8093314SPavel Labath using EntryT = RangeDataVectorT::Entry;
98b8093314SPavel Labath 
EntryIs(uint32_t ID)99b8093314SPavel Labath static testing::Matcher<const EntryT *> EntryIs(uint32_t ID) {
100b8093314SPavel Labath   return testing::Pointee(testing::Field(&EntryT::data, ID));
101b8093314SPavel Labath }
102b8093314SPavel Labath 
FindEntryIndexes(uint32_t address,RangeDataVectorT map)103594130dbSUnnar Freyr Erlendsson std::vector<uint32_t> FindEntryIndexes(uint32_t address, RangeDataVectorT map) {
104594130dbSUnnar Freyr Erlendsson   std::vector<uint32_t> result;
105594130dbSUnnar Freyr Erlendsson   map.FindEntryIndexesThatContain(address, result);
106594130dbSUnnar Freyr Erlendsson   return result;
107594130dbSUnnar Freyr Erlendsson }
108594130dbSUnnar Freyr Erlendsson 
TEST(RangeDataVector,FindEntryThatContains)109b8093314SPavel Labath TEST(RangeDataVector, FindEntryThatContains) {
110b8093314SPavel Labath   RangeDataVectorT Map;
111b8093314SPavel Labath   uint32_t NextID = 0;
112b8093314SPavel Labath   Map.Append(EntryT(0, 10, NextID++));
113b8093314SPavel Labath   Map.Append(EntryT(10, 10, NextID++));
114b8093314SPavel Labath   Map.Append(EntryT(20, 10, NextID++));
115b8093314SPavel Labath   Map.Sort();
116b8093314SPavel Labath 
117b8093314SPavel Labath   EXPECT_THAT(Map.FindEntryThatContains(0), EntryIs(0));
118b8093314SPavel Labath   EXPECT_THAT(Map.FindEntryThatContains(9), EntryIs(0));
119b8093314SPavel Labath   EXPECT_THAT(Map.FindEntryThatContains(10), EntryIs(1));
120b8093314SPavel Labath   EXPECT_THAT(Map.FindEntryThatContains(19), EntryIs(1));
121b8093314SPavel Labath   EXPECT_THAT(Map.FindEntryThatContains(20), EntryIs(2));
122b8093314SPavel Labath   EXPECT_THAT(Map.FindEntryThatContains(29), EntryIs(2));
123b8093314SPavel Labath   EXPECT_THAT(Map.FindEntryThatContains(30), nullptr);
124b8093314SPavel Labath }
125b8093314SPavel Labath 
TEST(RangeDataVector,FindEntryThatContains_Overlap)126b8093314SPavel Labath TEST(RangeDataVector, FindEntryThatContains_Overlap) {
127b8093314SPavel Labath   RangeDataVectorT Map;
128b8093314SPavel Labath   uint32_t NextID = 0;
129b8093314SPavel Labath   Map.Append(EntryT(0, 40, NextID++));
130b8093314SPavel Labath   Map.Append(EntryT(10, 20, NextID++));
131b8093314SPavel Labath   Map.Append(EntryT(20, 10, NextID++));
132b8093314SPavel Labath   Map.Sort();
133b8093314SPavel Labath 
134b8093314SPavel Labath   // With overlapping intervals, the intention seems to be to return the first
135b8093314SPavel Labath   // interval which contains the address.
136b8093314SPavel Labath   EXPECT_THAT(Map.FindEntryThatContains(25), EntryIs(0));
137b8093314SPavel Labath 
138b8093314SPavel Labath   // However, this does not always succeed.
139b8093314SPavel Labath   // TODO: This should probably return the range (0, 40) as well.
140b8093314SPavel Labath   EXPECT_THAT(Map.FindEntryThatContains(35), nullptr);
141b8093314SPavel Labath }
1422f2f41e1SJan Kratochvil 
TEST(RangeDataVector,CustomSort)1432f2f41e1SJan Kratochvil TEST(RangeDataVector, CustomSort) {
1442f2f41e1SJan Kratochvil   // First the default ascending order sorting of the data field.
1452f2f41e1SJan Kratochvil   auto Map = RangeDataVectorT();
1462f2f41e1SJan Kratochvil   Map.Append(EntryT(0, 10, 50));
1472f2f41e1SJan Kratochvil   Map.Append(EntryT(0, 10, 52));
1482f2f41e1SJan Kratochvil   Map.Append(EntryT(0, 10, 53));
1492f2f41e1SJan Kratochvil   Map.Append(EntryT(0, 10, 51));
1502f2f41e1SJan Kratochvil   Map.Sort();
1512f2f41e1SJan Kratochvil 
1522f2f41e1SJan Kratochvil   EXPECT_THAT(Map.GetSize(), 4);
1532f2f41e1SJan Kratochvil   EXPECT_THAT(Map.GetEntryRef(0).data, 50);
1542f2f41e1SJan Kratochvil   EXPECT_THAT(Map.GetEntryRef(1).data, 51);
1552f2f41e1SJan Kratochvil   EXPECT_THAT(Map.GetEntryRef(2).data, 52);
1562f2f41e1SJan Kratochvil   EXPECT_THAT(Map.GetEntryRef(3).data, 53);
1572f2f41e1SJan Kratochvil 
1582f2f41e1SJan Kratochvil   // And then a custom descending order sorting of the data field.
1592f2f41e1SJan Kratochvil   class CtorParam {};
1602f2f41e1SJan Kratochvil   class CustomSort {
1612f2f41e1SJan Kratochvil   public:
1622f2f41e1SJan Kratochvil     CustomSort(CtorParam) {}
1632f2f41e1SJan Kratochvil     bool operator()(const uint32_t a_data, const uint32_t b_data) {
1642f2f41e1SJan Kratochvil       return a_data > b_data;
1652f2f41e1SJan Kratochvil     }
1662f2f41e1SJan Kratochvil   };
1672f2f41e1SJan Kratochvil   using RangeDataVectorCustomSortT =
1682f2f41e1SJan Kratochvil       RangeDataVector<uint32_t, uint32_t, uint32_t, 0, CustomSort>;
1692f2f41e1SJan Kratochvil   using EntryT = RangeDataVectorT::Entry;
1702f2f41e1SJan Kratochvil 
1712f2f41e1SJan Kratochvil   auto MapC = RangeDataVectorCustomSortT(CtorParam());
1722f2f41e1SJan Kratochvil   MapC.Append(EntryT(0, 10, 50));
1732f2f41e1SJan Kratochvil   MapC.Append(EntryT(0, 10, 52));
1742f2f41e1SJan Kratochvil   MapC.Append(EntryT(0, 10, 53));
1752f2f41e1SJan Kratochvil   MapC.Append(EntryT(0, 10, 51));
1762f2f41e1SJan Kratochvil   MapC.Sort();
1772f2f41e1SJan Kratochvil 
1782f2f41e1SJan Kratochvil   EXPECT_THAT(MapC.GetSize(), 4);
1792f2f41e1SJan Kratochvil   EXPECT_THAT(MapC.GetEntryRef(0).data, 53);
1802f2f41e1SJan Kratochvil   EXPECT_THAT(MapC.GetEntryRef(1).data, 52);
1812f2f41e1SJan Kratochvil   EXPECT_THAT(MapC.GetEntryRef(2).data, 51);
1822f2f41e1SJan Kratochvil   EXPECT_THAT(MapC.GetEntryRef(3).data, 50);
1832f2f41e1SJan Kratochvil }
184594130dbSUnnar Freyr Erlendsson 
TEST(RangeDataVector,FindEntryIndexesThatContain)185594130dbSUnnar Freyr Erlendsson TEST(RangeDataVector, FindEntryIndexesThatContain) {
186594130dbSUnnar Freyr Erlendsson   RangeDataVectorT Map;
187594130dbSUnnar Freyr Erlendsson   Map.Append(EntryT(0, 10, 10));
188594130dbSUnnar Freyr Erlendsson   Map.Append(EntryT(10, 10, 11));
189594130dbSUnnar Freyr Erlendsson   Map.Append(EntryT(20, 10, 12));
190594130dbSUnnar Freyr Erlendsson   Map.Sort();
191594130dbSUnnar Freyr Erlendsson 
192594130dbSUnnar Freyr Erlendsson   EXPECT_THAT(FindEntryIndexes(0, Map), testing::ElementsAre(10));
193594130dbSUnnar Freyr Erlendsson   EXPECT_THAT(FindEntryIndexes(9, Map), testing::ElementsAre(10));
194594130dbSUnnar Freyr Erlendsson   EXPECT_THAT(FindEntryIndexes(10, Map), testing::ElementsAre(11));
195594130dbSUnnar Freyr Erlendsson   EXPECT_THAT(FindEntryIndexes(19, Map), testing::ElementsAre(11));
196594130dbSUnnar Freyr Erlendsson   EXPECT_THAT(FindEntryIndexes(20, Map), testing::ElementsAre(12));
197594130dbSUnnar Freyr Erlendsson   EXPECT_THAT(FindEntryIndexes(29, Map), testing::ElementsAre(12));
198594130dbSUnnar Freyr Erlendsson   EXPECT_THAT(FindEntryIndexes(30, Map), testing::ElementsAre());
199594130dbSUnnar Freyr Erlendsson }
200594130dbSUnnar Freyr Erlendsson 
TEST(RangeDataVector,FindEntryIndexesThatContain_Overlap)201594130dbSUnnar Freyr Erlendsson TEST(RangeDataVector, FindEntryIndexesThatContain_Overlap) {
202594130dbSUnnar Freyr Erlendsson   RangeDataVectorT Map;
203594130dbSUnnar Freyr Erlendsson   Map.Append(EntryT(0, 40, 10));
204594130dbSUnnar Freyr Erlendsson   Map.Append(EntryT(10, 20, 11));
205594130dbSUnnar Freyr Erlendsson   Map.Append(EntryT(20, 10, 12));
206594130dbSUnnar Freyr Erlendsson   Map.Sort();
207594130dbSUnnar Freyr Erlendsson 
208594130dbSUnnar Freyr Erlendsson   EXPECT_THAT(FindEntryIndexes(0, Map), testing::ElementsAre(10));
209594130dbSUnnar Freyr Erlendsson   EXPECT_THAT(FindEntryIndexes(9, Map), testing::ElementsAre(10));
210594130dbSUnnar Freyr Erlendsson   EXPECT_THAT(FindEntryIndexes(10, Map), testing::ElementsAre(10, 11));
211594130dbSUnnar Freyr Erlendsson   EXPECT_THAT(FindEntryIndexes(19, Map), testing::ElementsAre(10, 11));
212594130dbSUnnar Freyr Erlendsson   EXPECT_THAT(FindEntryIndexes(20, Map), testing::ElementsAre(10, 11, 12));
213594130dbSUnnar Freyr Erlendsson   EXPECT_THAT(FindEntryIndexes(29, Map), testing::ElementsAre(10, 11, 12));
214594130dbSUnnar Freyr Erlendsson   EXPECT_THAT(FindEntryIndexes(30, Map), testing::ElementsAre(10));
215594130dbSUnnar Freyr Erlendsson   EXPECT_THAT(FindEntryIndexes(39, Map), testing::ElementsAre(10));
216594130dbSUnnar Freyr Erlendsson   EXPECT_THAT(FindEntryIndexes(40, Map), testing::ElementsAre());
217594130dbSUnnar Freyr Erlendsson }
218