Skip to content

Commit 9385d84

Browse files
committed
Hook up an index option
1 parent 58de862 commit 9385d84

File tree

3 files changed

+50
-15
lines changed

3 files changed

+50
-15
lines changed

server/src/internalClusterTest/java/org/elasticsearch/index/store/DirectIOIT.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ private void indexVectors() {
8686
"index": true,
8787
"similarity": "l2_norm",
8888
"index_options": {
89-
"type": "%type%"
89+
"type": "%type%",
90+
"direct_raw_vector_reads": true
9091
}
9192
}
9293
}

server/src/main/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldMapper.java

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,8 @@ private DenseVectorIndexOptions defaultIndexOptions(boolean defaultInt8Hnsw, boo
388388
return new BBQHnswIndexOptions(
389389
Lucene99HnswVectorsFormat.DEFAULT_MAX_CONN,
390390
Lucene99HnswVectorsFormat.DEFAULT_BEAM_WIDTH,
391-
new RescoreVector(DEFAULT_OVERSAMPLE)
391+
new RescoreVector(DEFAULT_OVERSAMPLE),
392+
false
392393
);
393394
} else if (defaultInt8Hnsw) {
394395
return new Int8HnswIndexOptions(
@@ -1455,15 +1456,20 @@ public DenseVectorIndexOptions parseIndexOptions(String fieldName, Map<String, ?
14551456
}
14561457
int m = XContentMapValues.nodeIntegerValue(mNode);
14571458
int efConstruction = XContentMapValues.nodeIntegerValue(efConstructionNode);
1459+
14581460
RescoreVector rescoreVector = null;
14591461
if (hasRescoreIndexVersion(indexVersion)) {
14601462
rescoreVector = RescoreVector.fromIndexOptions(indexOptionsMap, indexVersion);
14611463
if (rescoreVector == null && defaultOversampleForBBQ(indexVersion)) {
14621464
rescoreVector = new RescoreVector(DEFAULT_OVERSAMPLE);
14631465
}
14641466
}
1467+
1468+
Object directRawVectorReadsNode = indexOptionsMap.remove("direct_raw_vector_reads");
1469+
boolean directRawVectorReads = XContentMapValues.nodeBooleanValue(directRawVectorReadsNode, false);
1470+
14651471
MappingParser.checkNoRemainingFields(fieldName, indexOptionsMap);
1466-
return new BBQHnswIndexOptions(m, efConstruction, rescoreVector);
1472+
return new BBQHnswIndexOptions(m, efConstruction, rescoreVector, directRawVectorReads);
14671473
}
14681474

14691475
@Override
@@ -1518,10 +1524,12 @@ public DenseVectorIndexOptions parseIndexOptions(String fieldName, Map<String, ?
15181524
);
15191525
}
15201526
}
1527+
15211528
RescoreVector rescoreVector = RescoreVector.fromIndexOptions(indexOptionsMap, indexVersion);
15221529
if (rescoreVector == null) {
15231530
rescoreVector = new RescoreVector(DEFAULT_OVERSAMPLE);
15241531
}
1532+
15251533
Object visitPercentageNode = indexOptionsMap.remove("default_visit_percentage");
15261534
double visitPercentage = 0d;
15271535
if (visitPercentageNode != null) {
@@ -1536,8 +1544,12 @@ public DenseVectorIndexOptions parseIndexOptions(String fieldName, Map<String, ?
15361544
);
15371545
}
15381546
}
1547+
1548+
Object directRawVectorReadsNode = indexOptionsMap.remove("direct_raw_vector_reads");
1549+
boolean directRawVectorReads = XContentMapValues.nodeBooleanValue(directRawVectorReadsNode, false);
1550+
15391551
MappingParser.checkNoRemainingFields(fieldName, indexOptionsMap);
1540-
return new BBQIVFIndexOptions(clusterSize, visitPercentage, rescoreVector);
1552+
return new BBQIVFIndexOptions(clusterSize, visitPercentage, rescoreVector, directRawVectorReads);
15411553
}
15421554

15431555
@Override
@@ -2009,17 +2021,23 @@ public String toString() {
20092021
public static class BBQHnswIndexOptions extends QuantizedIndexOptions {
20102022
private final int m;
20112023
private final int efConstruction;
2024+
private final boolean directRawVectorReads;
20122025

2013-
public BBQHnswIndexOptions(int m, int efConstruction, RescoreVector rescoreVector) {
2026+
public BBQHnswIndexOptions(int m, int efConstruction, RescoreVector rescoreVector, boolean directRawVectorReads) {
20142027
super(VectorIndexType.BBQ_HNSW, rescoreVector);
20152028
this.m = m;
20162029
this.efConstruction = efConstruction;
2030+
this.directRawVectorReads = directRawVectorReads;
20172031
}
20182032

20192033
@Override
20202034
KnnVectorsFormat getVectorsFormat(ElementType elementType) {
20212035
assert elementType == ElementType.FLOAT;
2022-
return new ES93HnswBinaryQuantizedVectorsFormat(m, efConstruction);
2036+
var format = new ES93HnswBinaryQuantizedVectorsFormat(m, efConstruction);
2037+
if (directRawVectorReads) {
2038+
format.useDirectIO();
2039+
}
2040+
return format;
20232041
}
20242042

20252043
@Override
@@ -2031,12 +2049,13 @@ public boolean updatableTo(DenseVectorIndexOptions update) {
20312049
@Override
20322050
boolean doEquals(DenseVectorIndexOptions other) {
20332051
BBQHnswIndexOptions that = (BBQHnswIndexOptions) other;
2034-
return m == that.m && efConstruction == that.efConstruction && Objects.equals(rescoreVector, that.rescoreVector);
2052+
return m == that.m && efConstruction == that.efConstruction && Objects.equals(rescoreVector, that.rescoreVector)
2053+
&& directRawVectorReads == that.directRawVectorReads;
20352054
}
20362055

20372056
@Override
20382057
int doHashCode() {
2039-
return Objects.hash(m, efConstruction, rescoreVector);
2058+
return Objects.hash(m, efConstruction, rescoreVector, directRawVectorReads);
20402059
}
20412060

20422061
@Override
@@ -2053,6 +2072,9 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
20532072
if (rescoreVector != null) {
20542073
rescoreVector.toXContent(builder, params);
20552074
}
2075+
if (directRawVectorReads) {
2076+
builder.field("direct_raw_vector_reads", true);
2077+
}
20562078
builder.endObject();
20572079
return builder;
20582080
}
@@ -2131,17 +2153,23 @@ public boolean validateDimension(int dim, boolean throwOnError) {
21312153
static class BBQIVFIndexOptions extends QuantizedIndexOptions {
21322154
final int clusterSize;
21332155
final double defaultVisitPercentage;
2156+
final boolean directRawVectorReads;
21342157

2135-
BBQIVFIndexOptions(int clusterSize, double defaultVisitPercentage, RescoreVector rescoreVector) {
2158+
BBQIVFIndexOptions(int clusterSize, double defaultVisitPercentage, RescoreVector rescoreVector, boolean directRawVectorReads) {
21362159
super(VectorIndexType.BBQ_DISK, rescoreVector);
21372160
this.clusterSize = clusterSize;
21382161
this.defaultVisitPercentage = defaultVisitPercentage;
2162+
this.directRawVectorReads = directRawVectorReads;
21392163
}
21402164

21412165
@Override
21422166
KnnVectorsFormat getVectorsFormat(ElementType elementType) {
21432167
assert elementType == ElementType.FLOAT;
2144-
return new ES920DiskBBQVectorsFormat(clusterSize, ES920DiskBBQVectorsFormat.DEFAULT_CENTROIDS_PER_PARENT_CLUSTER);
2168+
var format = new ES920DiskBBQVectorsFormat(clusterSize, ES920DiskBBQVectorsFormat.DEFAULT_CENTROIDS_PER_PARENT_CLUSTER);
2169+
if (directRawVectorReads) {
2170+
format.useDirectIO();
2171+
}
2172+
return format;
21452173
}
21462174

21472175
@Override
@@ -2154,12 +2182,13 @@ boolean doEquals(DenseVectorIndexOptions other) {
21542182
BBQIVFIndexOptions that = (BBQIVFIndexOptions) other;
21552183
return clusterSize == that.clusterSize
21562184
&& defaultVisitPercentage == that.defaultVisitPercentage
2157-
&& Objects.equals(rescoreVector, that.rescoreVector);
2185+
&& Objects.equals(rescoreVector, that.rescoreVector)
2186+
&& directRawVectorReads == that.directRawVectorReads;
21582187
}
21592188

21602189
@Override
21612190
int doHashCode() {
2162-
return Objects.hash(clusterSize, defaultVisitPercentage, rescoreVector);
2191+
return Objects.hash(clusterSize, defaultVisitPercentage, rescoreVector, directRawVectorReads);
21632192
}
21642193

21652194
@Override
@@ -2176,6 +2205,9 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
21762205
if (rescoreVector != null) {
21772206
rescoreVector.toXContent(builder, params);
21782207
}
2208+
if (directRawVectorReads) {
2209+
builder.field("direct_raw_vector_reads", true);
2210+
}
21792211
builder.endObject();
21802212
return builder;
21812213
}

server/src/test/java/org/elasticsearch/index/mapper/vectors/DenseVectorFieldTypeTests.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ public static DenseVectorFieldMapper.DenseVectorIndexOptions randomIndexOptionsA
100100
new DenseVectorFieldMapper.BBQHnswIndexOptions(
101101
randomIntBetween(1, 100),
102102
randomIntBetween(1, 10_000),
103-
randomFrom((DenseVectorFieldMapper.RescoreVector) null, randomRescoreVector())
103+
randomFrom((DenseVectorFieldMapper.RescoreVector) null, randomRescoreVector()),
104+
randomBoolean()
104105
),
105106
new DenseVectorFieldMapper.BBQFlatIndexOptions(
106107
randomFrom((DenseVectorFieldMapper.RescoreVector) null, randomRescoreVector())
@@ -113,7 +114,8 @@ public static DenseVectorFieldMapper.DenseVectorIndexOptions randomIndexOptionsA
113114
new DenseVectorFieldMapper.BBQIVFIndexOptions(
114115
randomIntBetween(MIN_VECTORS_PER_CLUSTER, MAX_VECTORS_PER_CLUSTER),
115116
randomFloatBetween(0.0f, 100.0f, true),
116-
randomFrom((DenseVectorFieldMapper.RescoreVector) null, randomRescoreVector())
117+
randomFrom((DenseVectorFieldMapper.RescoreVector) null, randomRescoreVector()),
118+
randomBoolean()
117119
)
118120
);
119121
}
@@ -141,7 +143,7 @@ private DenseVectorFieldMapper.DenseVectorIndexOptions randomIndexOptionsHnswQua
141143
randomFrom((Float) null, 0f, (float) randomDoubleBetween(0.9, 1.0, true)),
142144
rescoreVector
143145
),
144-
new DenseVectorFieldMapper.BBQHnswIndexOptions(randomIntBetween(1, 100), randomIntBetween(1, 10_000), rescoreVector)
146+
new DenseVectorFieldMapper.BBQHnswIndexOptions(randomIntBetween(1, 100), randomIntBetween(1, 10_000), rescoreVector, randomBoolean())
145147
);
146148
}
147149

0 commit comments

Comments
 (0)