Skip to content

Commit a107ac4

Browse files
authored
[core] Vector search add offset back (#6984)
1 parent a426a42 commit a107ac4

File tree

4 files changed

+76
-3
lines changed

4 files changed

+76
-3
lines changed

paimon-common/src/main/java/org/apache/paimon/globalindex/OffsetGlobalIndexReader.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,12 @@ public class OffsetGlobalIndexReader implements GlobalIndexReader {
3333

3434
private final GlobalIndexReader wrapped;
3535
private final long offset;
36+
private final long to;
3637

37-
public OffsetGlobalIndexReader(GlobalIndexReader wrapped, long offset) {
38+
public OffsetGlobalIndexReader(GlobalIndexReader wrapped, long offset, long to) {
3839
this.wrapped = wrapped;
3940
this.offset = offset;
41+
this.to = to;
4042
}
4143

4244
@Override
@@ -111,7 +113,8 @@ public Optional<GlobalIndexResult> visitNotIn(FieldRef fieldRef, List<Object> li
111113

112114
@Override
113115
public Optional<GlobalIndexResult> visitVectorSearch(VectorSearch vectorSearch) {
114-
return applyOffset(wrapped.visitVectorSearch(vectorSearch));
116+
return applyOffset(
117+
wrapped.visitVectorSearch(vectorSearch.offsetRange(this.offset, this.to)));
115118
}
116119

117120
private Optional<GlobalIndexResult> applyOffset(Optional<GlobalIndexResult> result) {

paimon-common/src/main/java/org/apache/paimon/predicate/VectorSearch.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import org.apache.paimon.globalindex.GlobalIndexReader;
2222
import org.apache.paimon.globalindex.GlobalIndexResult;
23+
import org.apache.paimon.utils.Range;
2324
import org.apache.paimon.utils.RoaringNavigableMap64;
2425

2526
import javax.annotation.Nullable;
@@ -76,6 +77,22 @@ public VectorSearch withIncludeRowIds(RoaringNavigableMap64 includeRowIds) {
7677
return this;
7778
}
7879

80+
public VectorSearch offsetRange(long from, long to) {
81+
if (includeRowIds != null) {
82+
RoaringNavigableMap64 range = new RoaringNavigableMap64();
83+
range.addRange(new Range(from, to));
84+
RoaringNavigableMap64 and64 = RoaringNavigableMap64.and(range, includeRowIds);
85+
final RoaringNavigableMap64 roaringNavigableMap64Offset = new RoaringNavigableMap64();
86+
for (long rowId : and64) {
87+
roaringNavigableMap64Offset.add(rowId - from);
88+
}
89+
VectorSearch target = new VectorSearch(vector, limit, fieldName);
90+
target.withIncludeRowIds(roaringNavigableMap64Offset);
91+
return target;
92+
}
93+
return this;
94+
}
95+
7996
public Optional<GlobalIndexResult> visit(GlobalIndexReader visitor) {
8097
return visitor.visitVectorSearch(this);
8198
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package org.apache.paimon.predicate;
20+
21+
import org.apache.paimon.utils.Range;
22+
import org.apache.paimon.utils.RoaringNavigableMap64;
23+
24+
import org.junit.jupiter.api.Test;
25+
26+
import java.util.List;
27+
28+
import static org.assertj.core.api.Assertions.assertThat;
29+
30+
/** Test vector search. */
31+
public class VectorSearchTest {
32+
33+
@Test
34+
public void testVectorSearchOffset() {
35+
float[][] vectors =
36+
new float[][] {
37+
new float[] {1.0f, 0.0f}, new float[] {0.95f, 0.1f}, new float[] {0.1f, 0.95f},
38+
new float[] {0.98f, 0.05f}, new float[] {0.0f, 1.0f}, new float[] {0.05f, 0.98f}
39+
};
40+
41+
VectorSearch vectorSearch = new VectorSearch(vectors[0], 1, "test");
42+
43+
RoaringNavigableMap64 includeRowIds = new RoaringNavigableMap64();
44+
includeRowIds.addRange(new Range(100L, 200L));
45+
vectorSearch.withIncludeRowIds(includeRowIds);
46+
47+
vectorSearch = vectorSearch.offsetRange(60, 150);
48+
49+
List<Range> ranges = vectorSearch.includeRowIds().toRangeList();
50+
assertThat(ranges.get(0)).isEqualTo(new Range(40L, 90L));
51+
}
52+
}

paimon-core/src/main/java/org/apache/paimon/globalindex/RowRangeGlobalIndexScanner.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,8 @@ private Collection<GlobalIndexReader> createReaders(
137137
GlobalIndexReader innerReader =
138138
new OffsetGlobalIndexReader(
139139
globalIndexer.createReader(indexFileReadWrite, globalMetas),
140-
range.from);
140+
range.from,
141+
range.to);
141142
unionReader.add(innerReader);
142143
}
143144

0 commit comments

Comments
 (0)