Skip to content

Commit 9fd2268

Browse files
committed
Add an integration test to verify DirectIO is used for at least one case
1 parent 521f4d8 commit 9fd2268

File tree

2 files changed

+85
-0
lines changed

2 files changed

+85
-0
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.index.store;
11+
12+
import org.apache.logging.log4j.Level;
13+
import org.apache.lucene.tests.util.LuceneTestCase;
14+
import org.elasticsearch.common.settings.Settings;
15+
import org.elasticsearch.plugins.Plugin;
16+
import org.elasticsearch.search.vectors.KnnSearchBuilder;
17+
import org.elasticsearch.search.vectors.VectorData;
18+
import org.elasticsearch.test.ESIntegTestCase;
19+
import org.elasticsearch.test.InternalSettingsPlugin;
20+
import org.elasticsearch.test.MockLog;
21+
import org.elasticsearch.test.junit.annotations.TestLogging;
22+
23+
import java.util.Collection;
24+
import java.util.List;
25+
import java.util.stream.IntStream;
26+
27+
@LuceneTestCase.SuppressCodecs("*") // only use our own codecs
28+
public class DirectIOIT extends ESIntegTestCase {
29+
30+
@Override
31+
protected Collection<Class<? extends Plugin>> nodePlugins() {
32+
return List.of(InternalSettingsPlugin.class);
33+
}
34+
35+
private void indexVectors() {
36+
internalCluster().startNode();
37+
prepareCreate("vectors").setSettings(Settings.builder().put(InternalSettingsPlugin.USE_COMPOUND_FILE.getKey(), false))
38+
.setMapping("""
39+
{
40+
"properties": {
41+
"vector": {
42+
"type": "dense_vector",
43+
"dims": 64,
44+
"element_type": "float",
45+
"index": true,
46+
"similarity": "l2_norm",
47+
"index_options": {
48+
"type": "bbq_flat"
49+
}
50+
}
51+
}
52+
}
53+
""")
54+
.get();
55+
ensureGreen("vectors");
56+
57+
for (int i = 0; i < 1000; i++) {
58+
indexDoc("vectors", Integer.toString(i), "vector", IntStream.range(0, 64).mapToDouble(d -> randomFloat()).toArray());
59+
}
60+
}
61+
62+
@TestLogging(value = "org.elasticsearch.index.store.FsDirectoryFactory:TRACE", reason = "to capture trace logging for direct IO")
63+
public void testDirectIOUsed() {
64+
try (MockLog mockLog = MockLog.capture(FsDirectoryFactory.class)) {
65+
mockLog.addExpectation(
66+
new MockLog.PatternSeenEventExpectation(
67+
"Direct IO used",
68+
FsDirectoryFactory.class.getCanonicalName(),
69+
Level.TRACE,
70+
"Opening .*\\.vec with direct IO"
71+
)
72+
);
73+
74+
indexVectors();
75+
76+
// do a search
77+
prepareSearch("vectors").setKnnSearch(
78+
List.of(new KnnSearchBuilder("vector", new VectorData(null, new byte[64]), 10, 20, null, null))
79+
).get();
80+
81+
mockLog.assertAllExpectationsMatched();
82+
}
83+
}
84+
}

server/src/main/java/org/elasticsearch/index/store/FsDirectoryFactory.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ public IndexInput openInput(String name, IOContext context) throws IOException {
157157
if (directIODelegate != null && context.hints().contains(DirectIOHint.INSTANCE)) {
158158
ensureOpen();
159159
ensureCanRead(name);
160+
Log.trace("Opening {} with direct IO", name);
160161
return directIODelegate.openInput(name, context);
161162
} else if (useDelegate(name, context)) {
162163
// we need to do these checks on the outer directory since the inner doesn't know about pending deletes

0 commit comments

Comments
 (0)