Skip to content

Commit a39ad3a

Browse files
committed
Return cached segments stats if include_unloaded_segments is true
Today we don't return segments stats for closed indices which makes it hard to tell how much memory such an index would require. With this change we return the statistics if requested by setting `include_unloaded_segments` to true on the rest request. Relates to elastic#39512/
1 parent 73d4516 commit a39ad3a

File tree

2 files changed

+47
-7
lines changed

2 files changed

+47
-7
lines changed

server/src/main/java/org/elasticsearch/index/engine/NoOpEngine.java

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,13 @@
2323
import org.apache.lucene.index.IndexCommit;
2424
import org.apache.lucene.index.IndexWriter;
2525
import org.apache.lucene.index.LeafReader;
26+
import org.apache.lucene.index.LeafReaderContext;
27+
import org.apache.lucene.index.SegmentReader;
2628
import org.apache.lucene.store.Directory;
29+
import org.elasticsearch.common.lucene.Lucene;
2730

2831
import java.io.IOException;
32+
import java.io.UncheckedIOException;
2933
import java.util.List;
3034
import java.util.function.Function;
3135

@@ -36,8 +40,20 @@
3640
*/
3741
public final class NoOpEngine extends ReadOnlyEngine {
3842

43+
private final SegmentsStats stats;
44+
3945
public NoOpEngine(EngineConfig config) {
4046
super(config, null, null, true, Function.identity());
47+
this.stats = new SegmentsStats();
48+
Directory directory = store.directory();
49+
try (DirectoryReader reader = DirectoryReader.open(directory)) {
50+
for (LeafReaderContext ctx : reader.getContext().leaves()) {
51+
SegmentReader segmentReader = Lucene.segmentReader(ctx.reader());
52+
fillSegmentStats(segmentReader, true, stats);
53+
}
54+
} catch (IOException e) {
55+
throw new UncheckedIOException(e);
56+
}
4157
}
4258

4359
@Override
@@ -47,17 +63,17 @@ protected DirectoryReader open(final IndexCommit commit) throws IOException {
4763
final IndexCommit indexCommit = indexCommits.get(indexCommits.size() - 1);
4864
return new DirectoryReader(directory, new LeafReader[0]) {
4965
@Override
50-
protected DirectoryReader doOpenIfChanged() throws IOException {
66+
protected DirectoryReader doOpenIfChanged() {
5167
return null;
5268
}
5369

5470
@Override
55-
protected DirectoryReader doOpenIfChanged(IndexCommit commit) throws IOException {
71+
protected DirectoryReader doOpenIfChanged(IndexCommit commit) {
5672
return null;
5773
}
5874

5975
@Override
60-
protected DirectoryReader doOpenIfChanged(IndexWriter writer, boolean applyAllDeletes) throws IOException {
76+
protected DirectoryReader doOpenIfChanged(IndexWriter writer, boolean applyAllDeletes) {
6177
return null;
6278
}
6379

@@ -67,17 +83,17 @@ public long getVersion() {
6783
}
6884

6985
@Override
70-
public boolean isCurrent() throws IOException {
86+
public boolean isCurrent() {
7187
return true;
7288
}
7389

7490
@Override
75-
public IndexCommit getIndexCommit() throws IOException {
91+
public IndexCommit getIndexCommit() {
7692
return indexCommit;
7793
}
7894

7995
@Override
80-
protected void doClose() throws IOException {
96+
protected void doClose() {
8197
}
8298

8399
@Override
@@ -86,4 +102,18 @@ public CacheHelper getReaderCacheHelper() {
86102
}
87103
};
88104
}
105+
106+
@Override
107+
public SegmentsStats segmentsStats(boolean includeSegmentFileSizes, boolean includeUnloadedSegments) {
108+
if (includeUnloadedSegments) {
109+
final SegmentsStats stats = new SegmentsStats();
110+
stats.add(this.stats);
111+
if (includeSegmentFileSizes == false) {
112+
stats.clearFileSizes();
113+
}
114+
return stats;
115+
} else {
116+
return super.segmentsStats(includeSegmentFileSizes, includeUnloadedSegments);
117+
}
118+
}
89119
}

server/src/test/java/org/elasticsearch/index/engine/NoOpEngineTests.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ public void testNoopAfterRegularEngine() throws IOException {
100100
noOpEngine.close();
101101
}
102102

103-
public void testNoOpEngineDocStats() throws Exception {
103+
public void testNoOpEngineStats() throws Exception {
104104
IOUtils.close(engine, store);
105105
final AtomicLong globalCheckpoint = new AtomicLong(SequenceNumbers.NO_OPS_PERFORMED);
106106
try (Store store = createStore()) {
@@ -131,15 +131,25 @@ public void testNoOpEngineDocStats() throws Exception {
131131
}
132132

133133
final DocsStats expectedDocStats;
134+
boolean includeFileSize = randomBoolean();
135+
final SegmentsStats expectedSegmentStats;
134136
try (InternalEngine engine = createEngine(config)) {
135137
expectedDocStats = engine.docStats();
138+
expectedSegmentStats = engine.segmentsStats(includeFileSize, true);
136139
}
137140

138141
try (NoOpEngine noOpEngine = new NoOpEngine(config)) {
139142
assertEquals(expectedDocStats.getCount(), noOpEngine.docStats().getCount());
140143
assertEquals(expectedDocStats.getDeleted(), noOpEngine.docStats().getDeleted());
141144
assertEquals(expectedDocStats.getTotalSizeInBytes(), noOpEngine.docStats().getTotalSizeInBytes());
142145
assertEquals(expectedDocStats.getAverageSizeInBytes(), noOpEngine.docStats().getAverageSizeInBytes());
146+
assertEquals(expectedSegmentStats.getCount(), noOpEngine.segmentsStats(includeFileSize, true).getCount());
147+
assertEquals(expectedSegmentStats.getMemoryInBytes(), noOpEngine.segmentsStats(includeFileSize, true).getMemoryInBytes());
148+
assertEquals(expectedSegmentStats.getFileSizes().size(),
149+
noOpEngine.segmentsStats(includeFileSize, true).getFileSizes().size());
150+
151+
assertEquals(0, noOpEngine.segmentsStats(includeFileSize, false).getFileSizes().size());
152+
assertEquals(0, noOpEngine.segmentsStats(includeFileSize, false).getMemoryInBytes());
143153
} catch (AssertionError e) {
144154
logger.error(config.getMergePolicy());
145155
throw e;

0 commit comments

Comments
 (0)