1b0142cd9SVedant Kumar //=== CoalescingBitVectorTest.cpp - CoalescingBitVector unit tests --------===//
2b0142cd9SVedant Kumar //
3b0142cd9SVedant Kumar // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4b0142cd9SVedant Kumar // See https://llvm.org/LICENSE.txt for license information.
5b0142cd9SVedant Kumar // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6b0142cd9SVedant Kumar //
7b0142cd9SVedant Kumar //===----------------------------------------------------------------------===//
8b0142cd9SVedant Kumar
9b0142cd9SVedant Kumar #include "llvm/ADT/CoalescingBitVector.h"
10b0142cd9SVedant Kumar #include "gtest/gtest.h"
11b0142cd9SVedant Kumar
12b0142cd9SVedant Kumar using namespace llvm;
13b0142cd9SVedant Kumar
14b0142cd9SVedant Kumar namespace {
15b0142cd9SVedant Kumar
16b0142cd9SVedant Kumar using UBitVec = CoalescingBitVector<unsigned>;
17b0142cd9SVedant Kumar using U64BitVec = CoalescingBitVector<uint64_t>;
18b0142cd9SVedant Kumar
elementsMatch(const UBitVec & BV,std::initializer_list<unsigned> List)19b0142cd9SVedant Kumar bool elementsMatch(const UBitVec &BV, std::initializer_list<unsigned> List) {
20b0142cd9SVedant Kumar if (!std::equal(BV.begin(), BV.end(), List.begin(), List.end())) {
21b0142cd9SVedant Kumar UBitVec::Allocator Alloc;
22b0142cd9SVedant Kumar UBitVec Expected(Alloc);
23b0142cd9SVedant Kumar Expected.set(List);
24b0142cd9SVedant Kumar dbgs() << "elementsMatch:\n"
25b0142cd9SVedant Kumar << " Expected: ";
26b0142cd9SVedant Kumar Expected.print(dbgs());
27b0142cd9SVedant Kumar dbgs() << " Got: ";
28b0142cd9SVedant Kumar BV.print(dbgs());
29b0142cd9SVedant Kumar return false;
30b0142cd9SVedant Kumar }
31b0142cd9SVedant Kumar return true;
32b0142cd9SVedant Kumar }
33b0142cd9SVedant Kumar
rangesMatch(iterator_range<UBitVec::const_iterator> R,std::initializer_list<unsigned> List)34*2ecaf935SVedant Kumar bool rangesMatch(iterator_range<UBitVec::const_iterator> R,
35*2ecaf935SVedant Kumar std::initializer_list<unsigned> List) {
36*2ecaf935SVedant Kumar return std::equal(R.begin(), R.end(), List.begin(), List.end());
37*2ecaf935SVedant Kumar }
38*2ecaf935SVedant Kumar
TEST(CoalescingBitVectorTest,Set)39b0142cd9SVedant Kumar TEST(CoalescingBitVectorTest, Set) {
40b0142cd9SVedant Kumar UBitVec::Allocator Alloc;
41b0142cd9SVedant Kumar UBitVec BV1(Alloc);
42b0142cd9SVedant Kumar UBitVec BV2(Alloc);
43b0142cd9SVedant Kumar
44b0142cd9SVedant Kumar BV1.set(0);
45b0142cd9SVedant Kumar EXPECT_TRUE(BV1.test(0));
46b0142cd9SVedant Kumar EXPECT_FALSE(BV1.test(1));
47b0142cd9SVedant Kumar
48b0142cd9SVedant Kumar BV2.set(BV1);
49b0142cd9SVedant Kumar EXPECT_TRUE(BV2.test(0));
50b0142cd9SVedant Kumar }
51b0142cd9SVedant Kumar
TEST(CoalescingBitVectorTest,Count)52b0142cd9SVedant Kumar TEST(CoalescingBitVectorTest, Count) {
53b0142cd9SVedant Kumar UBitVec::Allocator Alloc;
54b0142cd9SVedant Kumar UBitVec BV(Alloc);
55b0142cd9SVedant Kumar EXPECT_EQ(BV.count(), 0u);
56b0142cd9SVedant Kumar BV.set(0);
57b0142cd9SVedant Kumar EXPECT_EQ(BV.count(), 1u);
58b0142cd9SVedant Kumar BV.set({11, 12, 13, 14, 15});
59b0142cd9SVedant Kumar EXPECT_EQ(BV.count(), 6u);
60b0142cd9SVedant Kumar }
61b0142cd9SVedant Kumar
TEST(CoalescingBitVectorTest,ClearAndEmpty)62b0142cd9SVedant Kumar TEST(CoalescingBitVectorTest, ClearAndEmpty) {
63b0142cd9SVedant Kumar UBitVec::Allocator Alloc;
64b0142cd9SVedant Kumar UBitVec BV(Alloc);
65b0142cd9SVedant Kumar EXPECT_TRUE(BV.empty());
66b0142cd9SVedant Kumar BV.set(1);
67b0142cd9SVedant Kumar EXPECT_FALSE(BV.empty());
68b0142cd9SVedant Kumar BV.clear();
69b0142cd9SVedant Kumar EXPECT_TRUE(BV.empty());
70b0142cd9SVedant Kumar }
71b0142cd9SVedant Kumar
TEST(CoalescingBitVector,Copy)72b0142cd9SVedant Kumar TEST(CoalescingBitVector, Copy) {
73b0142cd9SVedant Kumar UBitVec::Allocator Alloc;
74b0142cd9SVedant Kumar UBitVec BV1(Alloc);
75b0142cd9SVedant Kumar BV1.set(0);
76b0142cd9SVedant Kumar UBitVec BV2 = BV1;
77b0142cd9SVedant Kumar EXPECT_TRUE(elementsMatch(BV1, {0}));
78b0142cd9SVedant Kumar EXPECT_TRUE(elementsMatch(BV2, {0}));
79b0142cd9SVedant Kumar BV2.set(5);
80b0142cd9SVedant Kumar BV2 = BV1;
81b0142cd9SVedant Kumar EXPECT_TRUE(elementsMatch(BV1, {0}));
82b0142cd9SVedant Kumar EXPECT_TRUE(elementsMatch(BV2, {0}));
83b0142cd9SVedant Kumar }
84b0142cd9SVedant Kumar
TEST(CoalescingBitVectorTest,Iterators)85b0142cd9SVedant Kumar TEST(CoalescingBitVectorTest, Iterators) {
86b0142cd9SVedant Kumar UBitVec::Allocator Alloc;
87b0142cd9SVedant Kumar UBitVec BV(Alloc);
88b0142cd9SVedant Kumar
89b0142cd9SVedant Kumar BV.set({0, 1, 2});
90b0142cd9SVedant Kumar
91b0142cd9SVedant Kumar auto It = BV.begin();
9236789388SVedant Kumar EXPECT_TRUE(It == BV.begin());
93b0142cd9SVedant Kumar EXPECT_EQ(*It, 0u);
94b0142cd9SVedant Kumar ++It;
95b0142cd9SVedant Kumar EXPECT_EQ(*It, 1u);
96b0142cd9SVedant Kumar ++It;
97b0142cd9SVedant Kumar EXPECT_EQ(*It, 2u);
98b0142cd9SVedant Kumar ++It;
9936789388SVedant Kumar EXPECT_TRUE(It == BV.end());
10036789388SVedant Kumar EXPECT_TRUE(BV.end() == BV.end());
101b0142cd9SVedant Kumar
102b0142cd9SVedant Kumar It = BV.begin();
10336789388SVedant Kumar EXPECT_TRUE(It == BV.begin());
104b0142cd9SVedant Kumar auto ItCopy = It++;
10536789388SVedant Kumar EXPECT_TRUE(ItCopy == BV.begin());
106b0142cd9SVedant Kumar EXPECT_EQ(*ItCopy, 0u);
107b0142cd9SVedant Kumar EXPECT_EQ(*It, 1u);
108b0142cd9SVedant Kumar
109b0142cd9SVedant Kumar EXPECT_TRUE(elementsMatch(BV, {0, 1, 2}));
110b0142cd9SVedant Kumar
111b0142cd9SVedant Kumar BV.set({4, 5, 6});
112b0142cd9SVedant Kumar EXPECT_TRUE(elementsMatch(BV, {0, 1, 2, 4, 5, 6}));
113b0142cd9SVedant Kumar
114b0142cd9SVedant Kumar BV.set(3);
115b0142cd9SVedant Kumar EXPECT_TRUE(elementsMatch(BV, {0, 1, 2, 3, 4, 5, 6}));
116b0142cd9SVedant Kumar
117b0142cd9SVedant Kumar BV.set(10);
118b0142cd9SVedant Kumar EXPECT_TRUE(elementsMatch(BV, {0, 1, 2, 3, 4, 5, 6, 10}));
119b0142cd9SVedant Kumar
120b0142cd9SVedant Kumar // Should be able to reset unset bits.
121b0142cd9SVedant Kumar BV.reset(3);
122b0142cd9SVedant Kumar BV.reset(3);
123b0142cd9SVedant Kumar BV.reset(20000);
124b0142cd9SVedant Kumar BV.set({1000, 1001, 1002});
125b0142cd9SVedant Kumar EXPECT_TRUE(elementsMatch(BV, {0, 1, 2, 4, 5, 6, 10, 1000, 1001, 1002}));
126b0142cd9SVedant Kumar
127b0142cd9SVedant Kumar auto It1 = BV.begin();
12836789388SVedant Kumar EXPECT_TRUE(It1 == BV.begin());
12936789388SVedant Kumar EXPECT_TRUE(++It1 == ++BV.begin());
13036789388SVedant Kumar EXPECT_TRUE(It1 != BV.begin());
13136789388SVedant Kumar EXPECT_TRUE(It1 != BV.end());
132b0142cd9SVedant Kumar }
133b0142cd9SVedant Kumar
TEST(CoalescingBitVectorTest,Reset)134b0142cd9SVedant Kumar TEST(CoalescingBitVectorTest, Reset) {
135b0142cd9SVedant Kumar UBitVec::Allocator Alloc;
136b0142cd9SVedant Kumar UBitVec BV(Alloc);
137b0142cd9SVedant Kumar
138b0142cd9SVedant Kumar BV.set(0);
139b0142cd9SVedant Kumar EXPECT_TRUE(BV.test(0));
140b0142cd9SVedant Kumar BV.reset(0);
141b0142cd9SVedant Kumar EXPECT_FALSE(BV.test(0));
142b0142cd9SVedant Kumar
143b0142cd9SVedant Kumar BV.clear();
144b0142cd9SVedant Kumar BV.set({1, 2, 3});
145b0142cd9SVedant Kumar BV.reset(1);
146b0142cd9SVedant Kumar EXPECT_TRUE(elementsMatch(BV, {2, 3}));
147b0142cd9SVedant Kumar
148b0142cd9SVedant Kumar BV.clear();
149b0142cd9SVedant Kumar BV.set({1, 2, 3});
150b0142cd9SVedant Kumar BV.reset(2);
151b0142cd9SVedant Kumar EXPECT_TRUE(elementsMatch(BV, {1, 3}));
152b0142cd9SVedant Kumar
153b0142cd9SVedant Kumar BV.clear();
154b0142cd9SVedant Kumar BV.set({1, 2, 3});
155b0142cd9SVedant Kumar BV.reset(3);
156b0142cd9SVedant Kumar EXPECT_TRUE(elementsMatch(BV, {1, 2}));
157b0142cd9SVedant Kumar }
158b0142cd9SVedant Kumar
TEST(CoalescingBitVectorTest,Comparison)159b0142cd9SVedant Kumar TEST(CoalescingBitVectorTest, Comparison) {
160b0142cd9SVedant Kumar UBitVec::Allocator Alloc;
161b0142cd9SVedant Kumar UBitVec BV1(Alloc);
162b0142cd9SVedant Kumar UBitVec BV2(Alloc);
163b0142cd9SVedant Kumar
164b0142cd9SVedant Kumar // Single interval.
165b0142cd9SVedant Kumar BV1.set({1, 2, 3});
166b0142cd9SVedant Kumar BV2.set({1, 2, 3});
167b0142cd9SVedant Kumar EXPECT_EQ(BV1, BV2);
168b0142cd9SVedant Kumar EXPECT_FALSE(BV1 != BV2);
169b0142cd9SVedant Kumar
170b0142cd9SVedant Kumar // Different number of intervals.
171b0142cd9SVedant Kumar BV1.clear();
172b0142cd9SVedant Kumar BV2.clear();
173b0142cd9SVedant Kumar BV1.set({1, 2, 3});
174b0142cd9SVedant Kumar EXPECT_NE(BV1, BV2);
175b0142cd9SVedant Kumar
176b0142cd9SVedant Kumar // Multiple intervals.
177b0142cd9SVedant Kumar BV1.clear();
178b0142cd9SVedant Kumar BV2.clear();
179b0142cd9SVedant Kumar BV1.set({1, 2, 11, 12});
180b0142cd9SVedant Kumar BV2.set({1, 2, 11, 12});
181b0142cd9SVedant Kumar EXPECT_EQ(BV1, BV2);
182b0142cd9SVedant Kumar BV2.reset(1);
183b0142cd9SVedant Kumar EXPECT_NE(BV1, BV2);
184b0142cd9SVedant Kumar BV2.set(1);
185b0142cd9SVedant Kumar BV2.reset(11);
186b0142cd9SVedant Kumar EXPECT_NE(BV1, BV2);
187b0142cd9SVedant Kumar }
188b0142cd9SVedant Kumar
189b0142cd9SVedant Kumar // A simple implementation of set union, used to double-check the human
190b0142cd9SVedant Kumar // "expected" answer.
simpleUnion(UBitVec & Union,const UBitVec & LHS,const UBitVec & RHS)1917ec24448SVedant Kumar void simpleUnion(UBitVec &Union, const UBitVec &LHS,
192b0142cd9SVedant Kumar const UBitVec &RHS) {
193b0142cd9SVedant Kumar for (unsigned Bit : LHS)
194b0142cd9SVedant Kumar Union.test_and_set(Bit);
195b0142cd9SVedant Kumar for (unsigned Bit : RHS)
196b0142cd9SVedant Kumar Union.test_and_set(Bit);
197b0142cd9SVedant Kumar }
198b0142cd9SVedant Kumar
TEST(CoalescingBitVectorTest,Union)199b0142cd9SVedant Kumar TEST(CoalescingBitVectorTest, Union) {
200b0142cd9SVedant Kumar UBitVec::Allocator Alloc;
201b0142cd9SVedant Kumar
202b0142cd9SVedant Kumar // Check that after doing LHS |= RHS, LHS == Expected.
203b0142cd9SVedant Kumar auto unionIs = [&](std::initializer_list<unsigned> LHS,
204b0142cd9SVedant Kumar std::initializer_list<unsigned> RHS,
205b0142cd9SVedant Kumar std::initializer_list<unsigned> Expected) {
206b0142cd9SVedant Kumar UBitVec BV1(Alloc);
207b0142cd9SVedant Kumar BV1.set(LHS);
208b0142cd9SVedant Kumar UBitVec BV2(Alloc);
209b0142cd9SVedant Kumar BV2.set(RHS);
2107ec24448SVedant Kumar UBitVec DoubleCheckedExpected(Alloc);
2117ec24448SVedant Kumar simpleUnion(DoubleCheckedExpected, BV1, BV2);
212b0142cd9SVedant Kumar ASSERT_TRUE(elementsMatch(DoubleCheckedExpected, Expected));
213b0142cd9SVedant Kumar BV1 |= BV2;
214b0142cd9SVedant Kumar ASSERT_TRUE(elementsMatch(BV1, Expected));
215b0142cd9SVedant Kumar };
216b0142cd9SVedant Kumar
217b0142cd9SVedant Kumar // Check that "LHS |= RHS" and "RHS |= LHS" both produce the expected result.
218b0142cd9SVedant Kumar auto testUnionSymmetrically = [&](std::initializer_list<unsigned> LHS,
219b0142cd9SVedant Kumar std::initializer_list<unsigned> RHS,
220b0142cd9SVedant Kumar std::initializer_list<unsigned> Expected) {
221b0142cd9SVedant Kumar unionIs(LHS, RHS, Expected);
222b0142cd9SVedant Kumar unionIs(RHS, LHS, Expected);
223b0142cd9SVedant Kumar };
224b0142cd9SVedant Kumar
225b0142cd9SVedant Kumar // Empty LHS.
226b0142cd9SVedant Kumar testUnionSymmetrically({}, {1, 2, 3}, {1, 2, 3});
227b0142cd9SVedant Kumar
228b0142cd9SVedant Kumar // Empty RHS.
229b0142cd9SVedant Kumar testUnionSymmetrically({1, 2, 3}, {}, {1, 2, 3});
230b0142cd9SVedant Kumar
231b0142cd9SVedant Kumar // Full overlap.
232b0142cd9SVedant Kumar testUnionSymmetrically({1}, {1}, {1});
233b0142cd9SVedant Kumar testUnionSymmetrically({1, 2, 11, 12}, {1, 2, 11, 12}, {1, 2, 11, 12});
234b0142cd9SVedant Kumar
235b0142cd9SVedant Kumar // Sliding window: fix {2, 3, 4} as the LHS, and slide a window before/after
236b0142cd9SVedant Kumar // it. Repeat this swapping LHS and RHS.
237b0142cd9SVedant Kumar testUnionSymmetrically({2, 3, 4}, {1, 2, 3}, {1, 2, 3, 4});
238b0142cd9SVedant Kumar testUnionSymmetrically({2, 3, 4}, {2, 3, 4}, {2, 3, 4});
239b0142cd9SVedant Kumar testUnionSymmetrically({2, 3, 4}, {3, 4, 5}, {2, 3, 4, 5});
240b0142cd9SVedant Kumar testUnionSymmetrically({1, 2, 3}, {2, 3, 4}, {1, 2, 3, 4});
241b0142cd9SVedant Kumar testUnionSymmetrically({3, 4, 5}, {2, 3, 4}, {2, 3, 4, 5});
242b0142cd9SVedant Kumar
243b0142cd9SVedant Kumar // Multiple overlaps, but at least one of the overlaps forces us to split an
244b0142cd9SVedant Kumar // interval (and possibly both do). For ease of understanding, fix LHS to be
245b0142cd9SVedant Kumar // {1, 2, 11, 12}, but vary RHS.
246b0142cd9SVedant Kumar testUnionSymmetrically({1, 2, 11, 12}, {1}, {1, 2, 11, 12});
247b0142cd9SVedant Kumar testUnionSymmetrically({1, 2, 11, 12}, {2}, {1, 2, 11, 12});
248b0142cd9SVedant Kumar testUnionSymmetrically({1, 2, 11, 12}, {11}, {1, 2, 11, 12});
249b0142cd9SVedant Kumar testUnionSymmetrically({1, 2, 11, 12}, {12}, {1, 2, 11, 12});
250b0142cd9SVedant Kumar testUnionSymmetrically({1, 2, 11, 12}, {1, 11}, {1, 2, 11, 12});
251b0142cd9SVedant Kumar testUnionSymmetrically({1, 2, 11, 12}, {1, 12}, {1, 2, 11, 12});
252b0142cd9SVedant Kumar testUnionSymmetrically({1, 2, 11, 12}, {2, 11}, {1, 2, 11, 12});
253b0142cd9SVedant Kumar testUnionSymmetrically({1, 2, 11, 12}, {2, 12}, {1, 2, 11, 12});
254b0142cd9SVedant Kumar testUnionSymmetrically({1, 2, 11, 12}, {1, 2, 11}, {1, 2, 11, 12});
255b0142cd9SVedant Kumar testUnionSymmetrically({1, 2, 11, 12}, {1, 2, 12}, {1, 2, 11, 12});
256b0142cd9SVedant Kumar testUnionSymmetrically({1, 2, 11, 12}, {1, 11, 12}, {1, 2, 11, 12});
257b0142cd9SVedant Kumar testUnionSymmetrically({1, 2, 11, 12}, {2, 11, 12}, {1, 2, 11, 12});
258b0142cd9SVedant Kumar testUnionSymmetrically({1, 2, 11, 12}, {0, 11, 12}, {0, 1, 2, 11, 12});
259b0142cd9SVedant Kumar testUnionSymmetrically({1, 2, 11, 12}, {3, 11, 12}, {1, 2, 3, 11, 12});
260b0142cd9SVedant Kumar testUnionSymmetrically({1, 2, 11, 12}, {1, 11, 13}, {1, 2, 11, 12, 13});
261b0142cd9SVedant Kumar testUnionSymmetrically({1, 2, 11, 12}, {1, 10, 11}, {1, 2, 10, 11, 12});
262b0142cd9SVedant Kumar
263b0142cd9SVedant Kumar // Partial overlap, but the existing interval covers future overlaps.
264b0142cd9SVedant Kumar testUnionSymmetrically({1, 2, 3, 4, 5, 6, 7, 8}, {2, 3, 4, 6, 7},
265b0142cd9SVedant Kumar {1, 2, 3, 4, 5, 6, 7, 8});
266b0142cd9SVedant Kumar testUnionSymmetrically({1, 2, 3, 4, 5, 6, 7, 8}, {2, 3, 7, 8, 9},
267b0142cd9SVedant Kumar {1, 2, 3, 4, 5, 6, 7, 8, 9});
268b0142cd9SVedant Kumar
269b0142cd9SVedant Kumar // More partial overlaps.
270b0142cd9SVedant Kumar testUnionSymmetrically({1, 2, 3, 4, 5}, {0, 1, 2, 4, 5, 6},
271b0142cd9SVedant Kumar {0, 1, 2, 3, 4, 5, 6});
272b0142cd9SVedant Kumar testUnionSymmetrically({2, 3}, {1, 2, 3, 4}, {1, 2, 3, 4});
273b0142cd9SVedant Kumar testUnionSymmetrically({3, 4}, {1, 2, 3, 4}, {1, 2, 3, 4});
274b0142cd9SVedant Kumar testUnionSymmetrically({1, 2}, {1, 2, 3, 4}, {1, 2, 3, 4});
275b0142cd9SVedant Kumar testUnionSymmetrically({0, 1}, {1, 2, 3, 4}, {0, 1, 2, 3, 4});
276b0142cd9SVedant Kumar
277b0142cd9SVedant Kumar // Merge non-overlapping.
278b0142cd9SVedant Kumar testUnionSymmetrically({0, 1}, {2, 3}, {0, 1, 2, 3});
279b0142cd9SVedant Kumar testUnionSymmetrically({0, 3}, {1, 2}, {0, 1, 2, 3});
280b0142cd9SVedant Kumar }
281b0142cd9SVedant Kumar
282b0142cd9SVedant Kumar // A simple implementation of set intersection, used to double-check the
283b0142cd9SVedant Kumar // human "expected" answer.
simpleIntersection(UBitVec & Intersection,const UBitVec & LHS,const UBitVec & RHS)2847ec24448SVedant Kumar void simpleIntersection(UBitVec &Intersection, const UBitVec &LHS,
285b0142cd9SVedant Kumar const UBitVec &RHS) {
286b0142cd9SVedant Kumar for (unsigned Bit : LHS)
287b0142cd9SVedant Kumar if (RHS.test(Bit))
288b0142cd9SVedant Kumar Intersection.set(Bit);
289b0142cd9SVedant Kumar }
290b0142cd9SVedant Kumar
TEST(CoalescingBitVectorTest,Intersection)291b0142cd9SVedant Kumar TEST(CoalescingBitVectorTest, Intersection) {
292b0142cd9SVedant Kumar UBitVec::Allocator Alloc;
293b0142cd9SVedant Kumar
294b0142cd9SVedant Kumar // Check that after doing LHS &= RHS, LHS == Expected.
295b0142cd9SVedant Kumar auto intersectionIs = [&](std::initializer_list<unsigned> LHS,
296b0142cd9SVedant Kumar std::initializer_list<unsigned> RHS,
297b0142cd9SVedant Kumar std::initializer_list<unsigned> Expected) {
298b0142cd9SVedant Kumar UBitVec BV1(Alloc);
299b0142cd9SVedant Kumar BV1.set(LHS);
300b0142cd9SVedant Kumar UBitVec BV2(Alloc);
301b0142cd9SVedant Kumar BV2.set(RHS);
3027ec24448SVedant Kumar UBitVec DoubleCheckedExpected(Alloc);
3037ec24448SVedant Kumar simpleIntersection(DoubleCheckedExpected, BV1, BV2);
304b0142cd9SVedant Kumar ASSERT_TRUE(elementsMatch(DoubleCheckedExpected, Expected));
305b0142cd9SVedant Kumar BV1 &= BV2;
306b0142cd9SVedant Kumar ASSERT_TRUE(elementsMatch(BV1, Expected));
307b0142cd9SVedant Kumar };
308b0142cd9SVedant Kumar
309b0142cd9SVedant Kumar // Check that "LHS &= RHS" and "RHS &= LHS" both produce the expected result.
310b0142cd9SVedant Kumar auto testIntersectionSymmetrically = [&](std::initializer_list<unsigned> LHS,
311b0142cd9SVedant Kumar std::initializer_list<unsigned> RHS,
312b0142cd9SVedant Kumar std::initializer_list<unsigned> Expected) {
313b0142cd9SVedant Kumar intersectionIs(LHS, RHS, Expected);
314b0142cd9SVedant Kumar intersectionIs(RHS, LHS, Expected);
315b0142cd9SVedant Kumar };
316b0142cd9SVedant Kumar
317b0142cd9SVedant Kumar // Empty case, one-element case.
318b0142cd9SVedant Kumar testIntersectionSymmetrically({}, {}, {});
319b0142cd9SVedant Kumar testIntersectionSymmetrically({1}, {1}, {1});
320b0142cd9SVedant Kumar testIntersectionSymmetrically({1}, {2}, {});
321b0142cd9SVedant Kumar
322b0142cd9SVedant Kumar // Exact overlaps cases: single overlap and multiple overlaps.
323b0142cd9SVedant Kumar testIntersectionSymmetrically({1, 2}, {1, 2}, {1, 2});
324b0142cd9SVedant Kumar testIntersectionSymmetrically({1, 2, 11, 12}, {1, 2, 11, 12}, {1, 2, 11, 12});
325b0142cd9SVedant Kumar
326b0142cd9SVedant Kumar // Sliding window: fix {2, 3, 4} as the LHS, and slide a window before/after
327b0142cd9SVedant Kumar // it.
328b0142cd9SVedant Kumar testIntersectionSymmetrically({2, 3, 4}, {1, 2, 3}, {2, 3});
329b0142cd9SVedant Kumar testIntersectionSymmetrically({2, 3, 4}, {2, 3, 4}, {2, 3, 4});
330b0142cd9SVedant Kumar testIntersectionSymmetrically({2, 3, 4}, {3, 4, 5}, {3, 4});
331b0142cd9SVedant Kumar
332b0142cd9SVedant Kumar // No overlap, but we have multiple intervals.
333b0142cd9SVedant Kumar testIntersectionSymmetrically({1, 2, 11, 12}, {3, 4, 13, 14}, {});
334b0142cd9SVedant Kumar
335b0142cd9SVedant Kumar // Multiple overlaps, but at least one of the overlaps forces us to split an
336b0142cd9SVedant Kumar // interval (and possibly both do). For ease of understanding, fix LHS to be
337b0142cd9SVedant Kumar // {1, 2, 11, 12}, but vary RHS.
338b0142cd9SVedant Kumar testIntersectionSymmetrically({1, 2, 11, 12}, {1}, {1});
339b0142cd9SVedant Kumar testIntersectionSymmetrically({1, 2, 11, 12}, {2}, {2});
340b0142cd9SVedant Kumar testIntersectionSymmetrically({1, 2, 11, 12}, {11}, {11});
341b0142cd9SVedant Kumar testIntersectionSymmetrically({1, 2, 11, 12}, {12}, {12});
342b0142cd9SVedant Kumar testIntersectionSymmetrically({1, 2, 11, 12}, {1, 11}, {1, 11});
343b0142cd9SVedant Kumar testIntersectionSymmetrically({1, 2, 11, 12}, {1, 12}, {1, 12});
344b0142cd9SVedant Kumar testIntersectionSymmetrically({1, 2, 11, 12}, {2, 11}, {2, 11});
345b0142cd9SVedant Kumar testIntersectionSymmetrically({1, 2, 11, 12}, {2, 12}, {2, 12});
346b0142cd9SVedant Kumar testIntersectionSymmetrically({1, 2, 11, 12}, {1, 2, 11}, {1, 2, 11});
347b0142cd9SVedant Kumar testIntersectionSymmetrically({1, 2, 11, 12}, {1, 2, 12}, {1, 2, 12});
348b0142cd9SVedant Kumar testIntersectionSymmetrically({1, 2, 11, 12}, {1, 11, 12}, {1, 11, 12});
349b0142cd9SVedant Kumar testIntersectionSymmetrically({1, 2, 11, 12}, {2, 11, 12}, {2, 11, 12});
350b0142cd9SVedant Kumar testIntersectionSymmetrically({1, 2, 11, 12}, {0, 11, 12}, {11, 12});
351b0142cd9SVedant Kumar testIntersectionSymmetrically({1, 2, 11, 12}, {3, 11, 12}, {11, 12});
352b0142cd9SVedant Kumar testIntersectionSymmetrically({1, 2, 11, 12}, {1, 11, 13}, {1, 11});
353b0142cd9SVedant Kumar testIntersectionSymmetrically({1, 2, 11, 12}, {1, 10, 11}, {1, 11});
354b0142cd9SVedant Kumar
355b0142cd9SVedant Kumar // Partial overlap, but the existing interval covers future overlaps.
356b0142cd9SVedant Kumar testIntersectionSymmetrically({1, 2, 3, 4, 5, 6, 7, 8}, {2, 3, 4, 6, 7},
357b0142cd9SVedant Kumar {2, 3, 4, 6, 7});
358b0142cd9SVedant Kumar }
359b0142cd9SVedant Kumar
360b0142cd9SVedant Kumar // A simple implementation of set intersection-with-complement, used to
361b0142cd9SVedant Kumar // double-check the human "expected" answer.
simpleIntersectionWithComplement(UBitVec & Intersection,const UBitVec & LHS,const UBitVec & RHS)3627ec24448SVedant Kumar void simpleIntersectionWithComplement(UBitVec &Intersection, const UBitVec &LHS,
363b0142cd9SVedant Kumar const UBitVec &RHS) {
364b0142cd9SVedant Kumar for (unsigned Bit : LHS)
365b0142cd9SVedant Kumar if (!RHS.test(Bit))
366b0142cd9SVedant Kumar Intersection.set(Bit);
367b0142cd9SVedant Kumar }
368b0142cd9SVedant Kumar
TEST(CoalescingBitVectorTest,IntersectWithComplement)369b0142cd9SVedant Kumar TEST(CoalescingBitVectorTest, IntersectWithComplement) {
370b0142cd9SVedant Kumar UBitVec::Allocator Alloc;
371b0142cd9SVedant Kumar
372b0142cd9SVedant Kumar // Check that after doing LHS.intersectWithComplement(RHS), LHS == Expected.
373b0142cd9SVedant Kumar auto intersectionWithComplementIs =
374b0142cd9SVedant Kumar [&](std::initializer_list<unsigned> LHS,
375b0142cd9SVedant Kumar std::initializer_list<unsigned> RHS,
376b0142cd9SVedant Kumar std::initializer_list<unsigned> Expected) {
377b0142cd9SVedant Kumar UBitVec BV1(Alloc);
378b0142cd9SVedant Kumar BV1.set(LHS);
379b0142cd9SVedant Kumar UBitVec BV2(Alloc);
380b0142cd9SVedant Kumar BV2.set(RHS);
3817ec24448SVedant Kumar UBitVec DoubleCheckedExpected(Alloc);
3827ec24448SVedant Kumar simpleIntersectionWithComplement(DoubleCheckedExpected, BV1, BV2);
383b0142cd9SVedant Kumar ASSERT_TRUE(elementsMatch(DoubleCheckedExpected, Expected));
384b0142cd9SVedant Kumar BV1.intersectWithComplement(BV2);
385b0142cd9SVedant Kumar ASSERT_TRUE(elementsMatch(BV1, Expected));
386b0142cd9SVedant Kumar };
387b0142cd9SVedant Kumar
388b0142cd9SVedant Kumar // Empty case, one-element case.
389b0142cd9SVedant Kumar intersectionWithComplementIs({}, {}, {});
390b0142cd9SVedant Kumar intersectionWithComplementIs({1}, {1}, {});
391b0142cd9SVedant Kumar intersectionWithComplementIs({1}, {2}, {1});
392b0142cd9SVedant Kumar
393b0142cd9SVedant Kumar // Exact overlaps cases: single overlap and multiple overlaps.
394b0142cd9SVedant Kumar intersectionWithComplementIs({1, 2}, {1, 2}, {});
395b0142cd9SVedant Kumar intersectionWithComplementIs({1, 2, 11, 12}, {1, 2, 11, 12}, {});
396b0142cd9SVedant Kumar
397b0142cd9SVedant Kumar // Sliding window: fix {2, 3, 4} as the LHS, and slide a window before/after
398b0142cd9SVedant Kumar // it. Repeat this swapping LHS and RHS.
399b0142cd9SVedant Kumar intersectionWithComplementIs({2, 3, 4}, {1, 2, 3}, {4});
400b0142cd9SVedant Kumar intersectionWithComplementIs({2, 3, 4}, {2, 3, 4}, {});
401b0142cd9SVedant Kumar intersectionWithComplementIs({2, 3, 4}, {3, 4, 5}, {2});
402b0142cd9SVedant Kumar intersectionWithComplementIs({1, 2, 3}, {2, 3, 4}, {1});
403b0142cd9SVedant Kumar intersectionWithComplementIs({3, 4, 5}, {2, 3, 4}, {5});
404b0142cd9SVedant Kumar
405b0142cd9SVedant Kumar // No overlap, but we have multiple intervals.
406b0142cd9SVedant Kumar intersectionWithComplementIs({1, 2, 11, 12}, {3, 4, 13, 14}, {1, 2, 11, 12});
407b0142cd9SVedant Kumar
408b0142cd9SVedant Kumar // Multiple overlaps. For ease of understanding, fix LHS to be
409b0142cd9SVedant Kumar // {1, 2, 11, 12}, but vary RHS.
410b0142cd9SVedant Kumar intersectionWithComplementIs({1, 2, 11, 12}, {1}, {2, 11, 12});
411b0142cd9SVedant Kumar intersectionWithComplementIs({1, 2, 11, 12}, {2}, {1, 11, 12});
412b0142cd9SVedant Kumar intersectionWithComplementIs({1, 2, 11, 12}, {11}, {1, 2, 12});
413b0142cd9SVedant Kumar intersectionWithComplementIs({1, 2, 11, 12}, {12}, {1, 2, 11});
414b0142cd9SVedant Kumar intersectionWithComplementIs({1, 2, 11, 12}, {1, 11}, {2, 12});
415b0142cd9SVedant Kumar intersectionWithComplementIs({1, 2, 11, 12}, {1, 12}, {2, 11});
416b0142cd9SVedant Kumar intersectionWithComplementIs({1, 2, 11, 12}, {2, 11}, {1, 12});
417b0142cd9SVedant Kumar intersectionWithComplementIs({1, 2, 11, 12}, {2, 12}, {1, 11});
418b0142cd9SVedant Kumar intersectionWithComplementIs({1, 2, 11, 12}, {1, 2, 11}, {12});
419b0142cd9SVedant Kumar intersectionWithComplementIs({1, 2, 11, 12}, {1, 2, 12}, {11});
420b0142cd9SVedant Kumar intersectionWithComplementIs({1, 2, 11, 12}, {1, 11, 12}, {2});
421b0142cd9SVedant Kumar intersectionWithComplementIs({1, 2, 11, 12}, {2, 11, 12}, {1});
422b0142cd9SVedant Kumar intersectionWithComplementIs({1, 2, 11, 12}, {0, 11, 12}, {1, 2});
423b0142cd9SVedant Kumar intersectionWithComplementIs({1, 2, 11, 12}, {3, 11, 12}, {1, 2});
424b0142cd9SVedant Kumar intersectionWithComplementIs({1, 2, 11, 12}, {1, 11, 13}, {2, 12});
425b0142cd9SVedant Kumar intersectionWithComplementIs({1, 2, 11, 12}, {1, 10, 11}, {2, 12});
426b0142cd9SVedant Kumar
427b0142cd9SVedant Kumar // Partial overlap, but the existing interval covers future overlaps.
428b0142cd9SVedant Kumar intersectionWithComplementIs({1, 2, 3, 4, 5, 6, 7, 8}, {2, 3, 4, 6, 7},
429b0142cd9SVedant Kumar {1, 5, 8});
430b0142cd9SVedant Kumar }
431b0142cd9SVedant Kumar
TEST(CoalescingBitVectorTest,FindLowerBound)432b0142cd9SVedant Kumar TEST(CoalescingBitVectorTest, FindLowerBound) {
433b0142cd9SVedant Kumar U64BitVec::Allocator Alloc;
434b0142cd9SVedant Kumar U64BitVec BV(Alloc);
435b0142cd9SVedant Kumar uint64_t BigNum1 = uint64_t(1) << 32;
436b0142cd9SVedant Kumar uint64_t BigNum2 = (uint64_t(1) << 33) + 1;
43736789388SVedant Kumar EXPECT_TRUE(BV.find(BigNum1) == BV.end());
438b0142cd9SVedant Kumar BV.set(BigNum1);
439b0142cd9SVedant Kumar auto Find1 = BV.find(BigNum1);
440b0142cd9SVedant Kumar EXPECT_EQ(*Find1, BigNum1);
441b0142cd9SVedant Kumar BV.set(BigNum2);
442b0142cd9SVedant Kumar auto Find2 = BV.find(BigNum1);
443b0142cd9SVedant Kumar EXPECT_EQ(*Find2, BigNum1);
444b0142cd9SVedant Kumar auto Find3 = BV.find(BigNum2);
445b0142cd9SVedant Kumar EXPECT_EQ(*Find3, BigNum2);
446b0142cd9SVedant Kumar BV.reset(BigNum1);
447b0142cd9SVedant Kumar auto Find4 = BV.find(BigNum1);
448b0142cd9SVedant Kumar EXPECT_EQ(*Find4, BigNum2);
449b0142cd9SVedant Kumar
450b0142cd9SVedant Kumar BV.clear();
451b0142cd9SVedant Kumar BV.set({1, 2, 3});
452b0142cd9SVedant Kumar EXPECT_EQ(*BV.find(2), 2u);
453b0142cd9SVedant Kumar EXPECT_EQ(*BV.find(3), 3u);
454b0142cd9SVedant Kumar }
455b0142cd9SVedant Kumar
TEST(CoalescingBitVectorTest,AdvanceToLowerBound)456a3fd1a1cSVedant Kumar TEST(CoalescingBitVectorTest, AdvanceToLowerBound) {
457a3fd1a1cSVedant Kumar U64BitVec::Allocator Alloc;
458a3fd1a1cSVedant Kumar U64BitVec BV(Alloc);
459a3fd1a1cSVedant Kumar uint64_t BigNum1 = uint64_t(1) << 32;
460a3fd1a1cSVedant Kumar uint64_t BigNum2 = (uint64_t(1) << 33) + 1;
461a3fd1a1cSVedant Kumar
462a3fd1a1cSVedant Kumar auto advFromBegin = [&](uint64_t To) -> U64BitVec::const_iterator {
463a3fd1a1cSVedant Kumar auto It = BV.begin();
464a3fd1a1cSVedant Kumar It.advanceToLowerBound(To);
465a3fd1a1cSVedant Kumar return It;
466a3fd1a1cSVedant Kumar };
467a3fd1a1cSVedant Kumar
468a3fd1a1cSVedant Kumar EXPECT_TRUE(advFromBegin(BigNum1) == BV.end());
469a3fd1a1cSVedant Kumar BV.set(BigNum1);
470a3fd1a1cSVedant Kumar auto Find1 = advFromBegin(BigNum1);
471a3fd1a1cSVedant Kumar EXPECT_EQ(*Find1, BigNum1);
472a3fd1a1cSVedant Kumar BV.set(BigNum2);
473a3fd1a1cSVedant Kumar auto Find2 = advFromBegin(BigNum1);
474a3fd1a1cSVedant Kumar EXPECT_EQ(*Find2, BigNum1);
475a3fd1a1cSVedant Kumar auto Find3 = advFromBegin(BigNum2);
476a3fd1a1cSVedant Kumar EXPECT_EQ(*Find3, BigNum2);
477a3fd1a1cSVedant Kumar BV.reset(BigNum1);
478a3fd1a1cSVedant Kumar auto Find4 = advFromBegin(BigNum1);
479a3fd1a1cSVedant Kumar EXPECT_EQ(*Find4, BigNum2);
480a3fd1a1cSVedant Kumar
481a3fd1a1cSVedant Kumar BV.clear();
482a3fd1a1cSVedant Kumar BV.set({1, 2, 3});
483a3fd1a1cSVedant Kumar EXPECT_EQ(*advFromBegin(2), 2u);
484a3fd1a1cSVedant Kumar EXPECT_EQ(*advFromBegin(3), 3u);
485a3fd1a1cSVedant Kumar auto It = BV.begin();
486a3fd1a1cSVedant Kumar It.advanceToLowerBound(0);
487a3fd1a1cSVedant Kumar EXPECT_EQ(*It, 1u);
488a3fd1a1cSVedant Kumar It.advanceToLowerBound(100);
489a3fd1a1cSVedant Kumar EXPECT_TRUE(It == BV.end());
490a3fd1a1cSVedant Kumar It.advanceToLowerBound(100);
491a3fd1a1cSVedant Kumar EXPECT_TRUE(It == BV.end());
492a3fd1a1cSVedant Kumar }
493a3fd1a1cSVedant Kumar
TEST(CoalescingBitVectorTest,HalfOpenRange)494*2ecaf935SVedant Kumar TEST(CoalescingBitVectorTest, HalfOpenRange) {
495*2ecaf935SVedant Kumar UBitVec::Allocator Alloc;
496*2ecaf935SVedant Kumar
497*2ecaf935SVedant Kumar {
498*2ecaf935SVedant Kumar UBitVec BV(Alloc);
499*2ecaf935SVedant Kumar BV.set({1, 2, 3});
500*2ecaf935SVedant Kumar
501*2ecaf935SVedant Kumar EXPECT_EQ(*BV.find(0), 1U); // find(Start) > Start
502*2ecaf935SVedant Kumar EXPECT_TRUE(rangesMatch(BV.half_open_range(0, 5), {1, 2, 3}));
503*2ecaf935SVedant Kumar EXPECT_TRUE(rangesMatch(BV.half_open_range(1, 4), {1, 2, 3}));
504*2ecaf935SVedant Kumar EXPECT_TRUE(rangesMatch(BV.half_open_range(1, 3), {1, 2}));
505*2ecaf935SVedant Kumar EXPECT_TRUE(rangesMatch(BV.half_open_range(2, 3), {2}));
506*2ecaf935SVedant Kumar EXPECT_TRUE(rangesMatch(BV.half_open_range(2, 4), {2, 3}));
507*2ecaf935SVedant Kumar EXPECT_TRUE(rangesMatch(BV.half_open_range(4, 5), {}));
508*2ecaf935SVedant Kumar }
509*2ecaf935SVedant Kumar
510*2ecaf935SVedant Kumar {
511*2ecaf935SVedant Kumar UBitVec BV(Alloc);
512*2ecaf935SVedant Kumar BV.set({1, 2, 11, 12});
513*2ecaf935SVedant Kumar
514*2ecaf935SVedant Kumar EXPECT_TRUE(rangesMatch(BV.half_open_range(0, 15), {1, 2, 11, 12}));
515*2ecaf935SVedant Kumar EXPECT_TRUE(rangesMatch(BV.half_open_range(1, 13), {1, 2, 11, 12}));
516*2ecaf935SVedant Kumar EXPECT_TRUE(rangesMatch(BV.half_open_range(1, 12), {1, 2, 11}));
517*2ecaf935SVedant Kumar
518*2ecaf935SVedant Kumar EXPECT_TRUE(rangesMatch(BV.half_open_range(0, 5), {1, 2}));
519*2ecaf935SVedant Kumar EXPECT_TRUE(rangesMatch(BV.half_open_range(1, 5), {1, 2}));
520*2ecaf935SVedant Kumar EXPECT_TRUE(rangesMatch(BV.half_open_range(2, 5), {2}));
521*2ecaf935SVedant Kumar EXPECT_TRUE(rangesMatch(BV.half_open_range(1, 2), {1}));
522*2ecaf935SVedant Kumar EXPECT_TRUE(rangesMatch(BV.half_open_range(13, 14), {}));
523*2ecaf935SVedant Kumar
524*2ecaf935SVedant Kumar EXPECT_TRUE(rangesMatch(BV.half_open_range(2, 10), {2}));
525*2ecaf935SVedant Kumar }
526*2ecaf935SVedant Kumar
527*2ecaf935SVedant Kumar {
528*2ecaf935SVedant Kumar UBitVec BV(Alloc);
529*2ecaf935SVedant Kumar BV.set({1});
530*2ecaf935SVedant Kumar
531*2ecaf935SVedant Kumar EXPECT_EQ(*BV.find(0), 1U); // find(Start) == End
532*2ecaf935SVedant Kumar EXPECT_TRUE(rangesMatch(BV.half_open_range(0, 1), {}));
533*2ecaf935SVedant Kumar }
534*2ecaf935SVedant Kumar
535*2ecaf935SVedant Kumar {
536*2ecaf935SVedant Kumar UBitVec BV(Alloc);
537*2ecaf935SVedant Kumar BV.set({5});
538*2ecaf935SVedant Kumar
539*2ecaf935SVedant Kumar EXPECT_EQ(*BV.find(3), 5U); // find(Start) > End
540*2ecaf935SVedant Kumar EXPECT_TRUE(rangesMatch(BV.half_open_range(3, 4), {}));
541*2ecaf935SVedant Kumar }
542*2ecaf935SVedant Kumar }
543*2ecaf935SVedant Kumar
TEST(CoalescingBitVectorTest,Print)544b0142cd9SVedant Kumar TEST(CoalescingBitVectorTest, Print) {
545b0142cd9SVedant Kumar std::string S;
546b0142cd9SVedant Kumar {
547b0142cd9SVedant Kumar raw_string_ostream OS(S);
548b0142cd9SVedant Kumar UBitVec::Allocator Alloc;
549b0142cd9SVedant Kumar UBitVec BV(Alloc);
550b0142cd9SVedant Kumar BV.set({1});
551b0142cd9SVedant Kumar BV.print(OS);
552b0142cd9SVedant Kumar
553b0142cd9SVedant Kumar BV.clear();
554b0142cd9SVedant Kumar BV.set({1, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20});
555b0142cd9SVedant Kumar BV.print(OS);
556b0142cd9SVedant Kumar }
557b0142cd9SVedant Kumar EXPECT_EQ(S, "{[1]}"
558b0142cd9SVedant Kumar "{[1][11, 20]}");
559b0142cd9SVedant Kumar }
560b0142cd9SVedant Kumar
561b0142cd9SVedant Kumar } // namespace
562