Skip to content

Commit a940930

Browse files
committed
more accurate read time
1 parent 1263b07 commit a940930

File tree

2 files changed

+25
-16
lines changed

2 files changed

+25
-16
lines changed

x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/index/store/direct/DirectBlobContainerIndexInput.java

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import org.apache.lucene.store.IOContext;
99
import org.apache.lucene.store.IndexInput;
1010
import org.elasticsearch.common.CheckedRunnable;
11+
import org.elasticsearch.common.CheckedSupplier;
1112
import org.elasticsearch.common.Nullable;
1213
import org.elasticsearch.common.blobstore.BlobContainer;
1314
import org.elasticsearch.core.internal.io.IOUtils;
@@ -22,6 +23,7 @@
2223
import java.io.IOException;
2324
import java.io.InputStream;
2425
import java.util.Objects;
26+
import java.util.concurrent.atomic.LongAdder;
2527

2628
/**
2729
* A {@link DirectBlobContainerIndexInput} instance corresponds to a single file from a Lucene directory that has been snapshotted. Because
@@ -194,36 +196,38 @@ private int readFromNewSequentialStream(int part, long pos, byte[] b, int offset
194196
return 0;
195197
}
196198

197-
final long startTimeNanos = directory.statsCurrentTimeNanos();
198-
199199
// if we open a stream of length streamLength then it will not be completely consumed by this read, so it is worthwhile to open
200200
// it and keep it open for future reads
201201
final InputStream inputStream = openBlobStream(part, pos, streamLength);
202202
streamForSequentialReads = new StreamForSequentialReads(new FilterInputStream(inputStream) {
203-
private int bytesRead = 0;
203+
private LongAdder bytesRead = new LongAdder();
204+
private LongAdder timeNanos = new LongAdder();
204205

205-
@Override
206-
public int read() throws IOException {
207-
final int result = super.read();
206+
private int onOptimizedRead(CheckedSupplier<Integer, IOException> read) throws IOException {
207+
final long startTimeNanos = directory.statsCurrentTimeNanos();
208+
final int result = read.get();
209+
final long endTimeNanos = directory.statsCurrentTimeNanos();
208210
if (result != -1) {
209-
bytesRead += result;
211+
bytesRead.add(result);
212+
timeNanos.add(endTimeNanos - startTimeNanos);
210213
}
211214
return result;
212215
}
213216

217+
@Override
218+
public int read() throws IOException {
219+
return onOptimizedRead(super::read);
220+
}
221+
214222
@Override
215223
public int read(byte[] b, int off, int len) throws IOException {
216-
final int result = super.read(b, off, len);
217-
if (result != -1) {
218-
bytesRead += result;
219-
}
220-
return result;
224+
return onOptimizedRead(() -> super.read(b, off, len));
221225
}
222226

223227
@Override
224228
public void close() throws IOException {
225229
super.close();
226-
stats.addOptimizedBytesRead(bytesRead, directory.statsCurrentTimeNanos() - startTimeNanos);
230+
stats.addOptimizedBytesRead(Math.toIntExact(bytesRead.sumThenReset()), timeNanos.sumThenReset());
227231
}
228232
}, part, pos, streamLength);
229233

x-pack/plugin/searchable-snapshots/src/test/java/org/elasticsearch/index/store/SearchableSnapshotDirectoryStatsTests.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -261,16 +261,21 @@ public void testOptimizedBytesReads() {
261261
input.readByte();
262262
}
263263

264-
final int bufferSize = BufferedIndexInput.bufferSize(context);
264+
// account for internal buffered reads
265+
final long bufferSize = BufferedIndexInput.bufferSize(context);
265266
if (input.length() <= bufferSize) {
266267
// file is read in a single non-optimized read operation
267268
assertCounter(inputStats.getDirectBytesRead(), input.length(), 1L, input.length(), input.length());
268269
assertThat(inputStats.getDirectBytesRead().totalNanoseconds(), equalTo(FAKE_CLOCK_ADVANCE_NANOS));
269270
assertCounter(inputStats.getOptimizedBytesRead(), 0L, 0L, 0L, 0L);
270271
} else {
272+
final long remaining = input.length() % bufferSize;
273+
final long expectedClockCounts = input.length() / bufferSize + (remaining > 0L ? 1L : 0L);
274+
271275
// file is read in a single optimized read operation
272-
assertCounter(inputStats.getOptimizedBytesRead(), input.length(), 1L, input.length(), input.length());
273-
assertThat(inputStats.getOptimizedBytesRead().totalNanoseconds(), equalTo(FAKE_CLOCK_ADVANCE_NANOS));
276+
IndexInputStats.TimedCounter optimizedBytesRead = inputStats.getOptimizedBytesRead();
277+
assertCounter(optimizedBytesRead, input.length(), 1L, input.length(), input.length());
278+
assertThat(optimizedBytesRead.totalNanoseconds(), equalTo(expectedClockCounts * FAKE_CLOCK_ADVANCE_NANOS));
274279
assertCounter(inputStats.getDirectBytesRead(), 0L, 0L, 0L, 0L);
275280
}
276281
} catch (IOException e) {

0 commit comments

Comments
 (0)