blob: e9095f645bac27a676b4be752f19b9d51b7886c7 [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include "paimon/utils/row_range_index.h"
#include "paimon/testing/utils/testharness.h"
namespace paimon::test {
// ======================== Create ========================
TEST(RowRangeIndexTest, CreateWithEmptyRangesReturnsError) {
ASSERT_NOK_WITH_MSG(RowRangeIndex::Create({}), "Ranges cannot be empty in RowRangeIndex");
}
TEST(RowRangeIndexTest, CreateWithSingleRange) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 20)}));
ASSERT_EQ(index.Ranges().size(), 1);
ASSERT_EQ(index.Ranges()[0], Range(10, 20));
}
TEST(RowRangeIndexTest, CreateSortsAndMergesOverlappingRanges) {
ASSERT_OK_AND_ASSIGN(auto index,
RowRangeIndex::Create({Range(20, 30), Range(0, 10), Range(5, 15)}));
std::vector<Range> expected = {Range(0, 15), Range(20, 30)};
ASSERT_EQ(index.Ranges(), expected);
}
TEST(RowRangeIndexTest, CreateMergesAdjacentRanges) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(0, 10), Range(11, 20)}));
std::vector<Range> expected = {Range(0, 20)};
ASSERT_EQ(index.Ranges(), expected);
}
TEST(RowRangeIndexTest, CreateMergesDuplicateRanges) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(0, 10), Range(0, 10)}));
std::vector<Range> expected = {Range(0, 10)};
ASSERT_EQ(index.Ranges(), expected);
}
TEST(RowRangeIndexTest, CreateWithMultipleDisjointRanges) {
ASSERT_OK_AND_ASSIGN(auto index,
RowRangeIndex::Create({Range(0, 5), Range(10, 15), Range(20, 25)}));
std::vector<Range> expected = {Range(0, 5), Range(10, 15), Range(20, 25)};
ASSERT_EQ(index.Ranges(), expected);
}
// ======================== Ranges ========================
TEST(RowRangeIndexTest, RangesReturnsUnmodifiableReference) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(0, 10), Range(20, 30)}));
const auto& ranges1 = index.Ranges();
const auto& ranges2 = index.Ranges();
ASSERT_EQ(&ranges1, &ranges2);
}
// ======================== Intersects ========================
TEST(RowRangeIndexTest, IntersectsExactMatch) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 20)}));
ASSERT_TRUE(index.Intersects(10, 20));
}
TEST(RowRangeIndexTest, IntersectsPartialOverlapFromLeft) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 20)}));
ASSERT_TRUE(index.Intersects(5, 15));
}
TEST(RowRangeIndexTest, IntersectsPartialOverlapFromRight) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 20)}));
ASSERT_TRUE(index.Intersects(15, 25));
}
TEST(RowRangeIndexTest, IntersectsContainedRange) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 20)}));
ASSERT_TRUE(index.Intersects(12, 18));
}
TEST(RowRangeIndexTest, IntersectsContainingRange) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 20)}));
ASSERT_TRUE(index.Intersects(0, 30));
}
TEST(RowRangeIndexTest, IntersectsTouchingLeftBoundary) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 20)}));
ASSERT_TRUE(index.Intersects(5, 10));
}
TEST(RowRangeIndexTest, IntersectsTouchingRightBoundary) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 20)}));
ASSERT_TRUE(index.Intersects(20, 25));
}
TEST(RowRangeIndexTest, IntersectsNoOverlapBefore) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 20)}));
ASSERT_FALSE(index.Intersects(0, 9));
}
TEST(RowRangeIndexTest, IntersectsNoOverlapAfter) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 20)}));
ASSERT_FALSE(index.Intersects(21, 30));
}
TEST(RowRangeIndexTest, IntersectsMultipleRangesHitsFirst) {
ASSERT_OK_AND_ASSIGN(auto index,
RowRangeIndex::Create({Range(0, 10), Range(20, 30), Range(40, 50)}));
ASSERT_TRUE(index.Intersects(5, 8));
}
TEST(RowRangeIndexTest, IntersectsMultipleRangesHitsMiddle) {
ASSERT_OK_AND_ASSIGN(auto index,
RowRangeIndex::Create({Range(0, 10), Range(20, 30), Range(40, 50)}));
ASSERT_TRUE(index.Intersects(22, 28));
}
TEST(RowRangeIndexTest, IntersectsMultipleRangesHitsLast) {
ASSERT_OK_AND_ASSIGN(auto index,
RowRangeIndex::Create({Range(0, 10), Range(20, 30), Range(40, 50)}));
ASSERT_TRUE(index.Intersects(42, 48));
}
TEST(RowRangeIndexTest, IntersectsMultipleRangesSpansGap) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(0, 10), Range(20, 30)}));
ASSERT_TRUE(index.Intersects(8, 22));
}
TEST(RowRangeIndexTest, IntersectsMultipleRangesFallsInGap) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(0, 10), Range(20, 30)}));
ASSERT_FALSE(index.Intersects(11, 19));
}
TEST(RowRangeIndexTest, IntersectsMultipleRangesBeforeAll) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 20), Range(30, 40)}));
ASSERT_FALSE(index.Intersects(0, 5));
}
TEST(RowRangeIndexTest, IntersectsMultipleRangesAfterAll) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 20), Range(30, 40)}));
ASSERT_FALSE(index.Intersects(50, 60));
}
TEST(RowRangeIndexTest, IntersectsSinglePointMatch) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 10)}));
ASSERT_TRUE(index.Intersects(10, 10));
}
TEST(RowRangeIndexTest, IntersectsSinglePointNoMatch) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 10)}));
ASSERT_FALSE(index.Intersects(11, 11));
}
// ======================== IntersectedRanges ========================
TEST(RowRangeIndexTest, IntersectedRangesExactMatch) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 20)}));
auto intersected = index.IntersectedRanges(10, 20);
std::vector<Range> expected = {Range(10, 20)};
ASSERT_EQ(intersected, expected);
}
TEST(RowRangeIndexTest, IntersectedRangesClippedFromLeft) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 20)}));
auto intersected = index.IntersectedRanges(5, 15);
std::vector<Range> expected = {Range(10, 15)};
ASSERT_EQ(intersected, expected);
}
TEST(RowRangeIndexTest, IntersectedRangesClippedFromRight) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 20)}));
auto intersected = index.IntersectedRanges(15, 25);
std::vector<Range> expected = {Range(15, 20)};
ASSERT_EQ(intersected, expected);
}
TEST(RowRangeIndexTest, IntersectedRangesClippedBothSides) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 20)}));
auto intersected = index.IntersectedRanges(12, 18);
std::vector<Range> expected = {Range(12, 18)};
ASSERT_EQ(intersected, expected);
}
TEST(RowRangeIndexTest, IntersectedRangesContainingRange) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 20)}));
auto intersected = index.IntersectedRanges(0, 30);
std::vector<Range> expected = {Range(10, 20)};
ASSERT_EQ(intersected, expected);
}
TEST(RowRangeIndexTest, IntersectedRangesNoOverlapBefore) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 20)}));
auto intersected = index.IntersectedRanges(0, 9);
ASSERT_TRUE(intersected.empty());
}
TEST(RowRangeIndexTest, IntersectedRangesNoOverlapAfter) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 20)}));
auto intersected = index.IntersectedRanges(21, 30);
ASSERT_TRUE(intersected.empty());
}
TEST(RowRangeIndexTest, IntersectedRangesTouchingLeftBoundary) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 20)}));
auto intersected = index.IntersectedRanges(5, 10);
std::vector<Range> expected = {Range(10, 10)};
ASSERT_EQ(intersected, expected);
}
TEST(RowRangeIndexTest, IntersectedRangesTouchingRightBoundary) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 20)}));
auto intersected = index.IntersectedRanges(20, 25);
std::vector<Range> expected = {Range(20, 20)};
ASSERT_EQ(intersected, expected);
}
TEST(RowRangeIndexTest, IntersectedRangesMultipleRangesHitsFirst) {
ASSERT_OK_AND_ASSIGN(auto index,
RowRangeIndex::Create({Range(0, 10), Range(20, 30), Range(40, 50)}));
auto intersected = index.IntersectedRanges(3, 8);
std::vector<Range> expected = {Range(3, 8)};
ASSERT_EQ(intersected, expected);
}
TEST(RowRangeIndexTest, IntersectedRangesMultipleRangesHitsLast) {
ASSERT_OK_AND_ASSIGN(auto index,
RowRangeIndex::Create({Range(0, 10), Range(20, 30), Range(40, 50)}));
auto intersected = index.IntersectedRanges(42, 48);
std::vector<Range> expected = {Range(42, 48)};
ASSERT_EQ(intersected, expected);
}
TEST(RowRangeIndexTest, IntersectedRangesSpansTwoRanges) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(0, 10), Range(20, 30)}));
auto intersected = index.IntersectedRanges(5, 25);
std::vector<Range> expected = {Range(5, 10), Range(20, 25)};
ASSERT_EQ(intersected, expected);
}
TEST(RowRangeIndexTest, IntersectedRangesSpansThreeRangesMiddleFullyContained) {
ASSERT_OK_AND_ASSIGN(auto index,
RowRangeIndex::Create({Range(0, 10), Range(20, 30), Range(40, 50)}));
auto intersected = index.IntersectedRanges(5, 45);
std::vector<Range> expected = {Range(5, 10), Range(20, 30), Range(40, 45)};
ASSERT_EQ(intersected, expected);
}
TEST(RowRangeIndexTest, IntersectedRangesSpansAllRanges) {
ASSERT_OK_AND_ASSIGN(auto index,
RowRangeIndex::Create({Range(0, 10), Range(20, 30), Range(40, 50)}));
auto intersected = index.IntersectedRanges(0, 50);
std::vector<Range> expected = {Range(0, 10), Range(20, 30), Range(40, 50)};
ASSERT_EQ(intersected, expected);
}
TEST(RowRangeIndexTest, IntersectedRangesSpansAllRangesWider) {
ASSERT_OK_AND_ASSIGN(auto index,
RowRangeIndex::Create({Range(10, 20), Range(30, 40), Range(50, 60)}));
auto intersected = index.IntersectedRanges(0, 100);
std::vector<Range> expected = {Range(10, 20), Range(30, 40), Range(50, 60)};
ASSERT_EQ(intersected, expected);
}
TEST(RowRangeIndexTest, IntersectedRangesFallsInGap) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(0, 10), Range(20, 30)}));
auto intersected = index.IntersectedRanges(11, 19);
ASSERT_TRUE(intersected.empty());
}
TEST(RowRangeIndexTest, IntersectedRangesBeforeAll) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 20), Range(30, 40)}));
auto intersected = index.IntersectedRanges(0, 5);
ASSERT_TRUE(intersected.empty());
}
TEST(RowRangeIndexTest, IntersectedRangesAfterAll) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 20), Range(30, 40)}));
auto intersected = index.IntersectedRanges(50, 60);
ASSERT_TRUE(intersected.empty());
}
TEST(RowRangeIndexTest, IntersectedRangesSinglePointMatch) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 20)}));
auto intersected = index.IntersectedRanges(15, 15);
std::vector<Range> expected = {Range(15, 15)};
ASSERT_EQ(intersected, expected);
}
TEST(RowRangeIndexTest, IntersectedRangesSinglePointRangeMatch) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 10)}));
auto intersected = index.IntersectedRanges(10, 10);
std::vector<Range> expected = {Range(10, 10)};
ASSERT_EQ(intersected, expected);
}
TEST(RowRangeIndexTest, IntersectedRangesSinglePointRangeNoMatch) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(10, 10)}));
auto intersected = index.IntersectedRanges(11, 11);
ASSERT_TRUE(intersected.empty());
}
TEST(RowRangeIndexTest, IntersectedRangesLastRangeStartsBeyondEnd) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(0, 10), Range(30, 40)}));
auto intersected = index.IntersectedRanges(5, 25);
std::vector<Range> expected = {Range(5, 10)};
ASSERT_EQ(intersected, expected);
}
TEST(RowRangeIndexTest, IntersectedRangesFourRangesClipBothEnds) {
ASSERT_OK_AND_ASSIGN(auto index, RowRangeIndex::Create({Range(0, 10), Range(20, 30),
Range(40, 50), Range(60, 70)}));
auto intersected = index.IntersectedRanges(5, 65);
std::vector<Range> expected = {Range(5, 10), Range(20, 30), Range(40, 50), Range(60, 65)};
ASSERT_EQ(intersected, expected);
}
TEST(RowRangeIndexTest, IntersectedRangesFiveRangesThreeMiddleFullyContained) {
ASSERT_OK_AND_ASSIGN(auto index,
RowRangeIndex::Create({Range(0, 10), Range(20, 30), Range(40, 50),
Range(60, 70), Range(80, 90)}));
auto intersected = index.IntersectedRanges(5, 85);
std::vector<Range> expected = {Range(5, 10), Range(20, 30), Range(40, 50), Range(60, 70),
Range(80, 85)};
ASSERT_EQ(intersected, expected);
}
} // namespace paimon::test