Stats: Added verbose option to segments api, with full ram tree as first

additional element per segment.

This commit adds a verbose flag to the _segments api.  Currently the
only additional information returned when set to true is the full
ram tree from lucene for each segment.
This commit is contained in:
Ryan Ernst 2014-12-19 01:04:28 -08:00
parent 09b4d0e097
commit f7f99b8dbf
12 changed files with 269 additions and 20 deletions

View File

@ -74,3 +74,42 @@ compound:: Whether the segment is stored in a compound file. When true, this
means that Lucene merged all files from the segment in a single means that Lucene merged all files from the segment in a single
one in order to save file descriptors. one in order to save file descriptors.
=== Verbose mode
To add additional information that can be used for debugging, use the `verbose` flag.
NOTE: The format of additional verbose information is experimental and can change at any time.
[source,js]
--------------------------------------------------
curl -XGET 'http://localhost:9200/test/_segments?verbose=true'
--------------------------------------------------
Response:
[source,js]
--------------------------------------------------
{
...
"_3": {
...
"ram_tree": [
{
"description": "postings [PerFieldPostings(format=1)]",
"size_in_bytes": 2696,
"children": [
{
"description": "format 'Lucene50_0' ...",
"size_in_bytes": 2608,
"children" :[ ... ]
},
...
]
},
...
]
}
...
}
--------------------------------------------------

View File

@ -22,17 +22,21 @@ package org.elasticsearch.action.admin.indices.segments;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import org.apache.lucene.util.Accountable;
import org.elasticsearch.action.ShardOperationFailedException; import org.elasticsearch.action.ShardOperationFailedException;
import org.elasticsearch.action.support.broadcast.BroadcastOperationResponse; import org.elasticsearch.action.support.broadcast.BroadcastOperationResponse;
import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentBuilderString; import org.elasticsearch.common.xcontent.XContentBuilderString;
import org.elasticsearch.index.engine.Segment; import org.elasticsearch.index.engine.Segment;
import java.io.IOException; import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -139,6 +143,13 @@ public class IndicesSegmentResponse extends BroadcastOperationResponse implement
if (segment.getMergeId() != null) { if (segment.getMergeId() != null) {
builder.field(Fields.MERGE_ID, segment.getMergeId()); builder.field(Fields.MERGE_ID, segment.getMergeId());
} }
if (segment.ramTree != null) {
builder.startArray(Fields.RAM_TREE);
for (Accountable child : segment.ramTree.getChildResources()) {
toXContent(builder, child);
}
builder.endArray();
}
builder.endObject(); builder.endObject();
} }
builder.endObject(); builder.endObject();
@ -156,6 +167,21 @@ public class IndicesSegmentResponse extends BroadcastOperationResponse implement
return builder; return builder;
} }
static void toXContent(XContentBuilder builder, Accountable tree) throws IOException {
builder.startObject();
builder.field(Fields.DESCRIPTION, tree.toString());
builder.byteSizeField(Fields.SIZE_IN_BYTES, Fields.SIZE, new ByteSizeValue(tree.ramBytesUsed()));
Collection<Accountable> children = tree.getChildResources();
if (children.isEmpty() == false) {
builder.startArray(Fields.CHILDREN);
for (Accountable child : children) {
toXContent(builder, child);
}
builder.endArray();
}
builder.endObject();
}
static final class Fields { static final class Fields {
static final XContentBuilderString INDICES = new XContentBuilderString("indices"); static final XContentBuilderString INDICES = new XContentBuilderString("indices");
static final XContentBuilderString SHARDS = new XContentBuilderString("shards"); static final XContentBuilderString SHARDS = new XContentBuilderString("shards");
@ -180,5 +206,8 @@ public class IndicesSegmentResponse extends BroadcastOperationResponse implement
static final XContentBuilderString MERGE_ID = new XContentBuilderString("merge_id"); static final XContentBuilderString MERGE_ID = new XContentBuilderString("merge_id");
static final XContentBuilderString MEMORY = new XContentBuilderString("memory"); static final XContentBuilderString MEMORY = new XContentBuilderString("memory");
static final XContentBuilderString MEMORY_IN_BYTES = new XContentBuilderString("memory_in_bytes"); static final XContentBuilderString MEMORY_IN_BYTES = new XContentBuilderString("memory_in_bytes");
static final XContentBuilderString RAM_TREE = new XContentBuilderString("ram_tree");
static final XContentBuilderString DESCRIPTION = new XContentBuilderString("description");
static final XContentBuilderString CHILDREN = new XContentBuilderString("children");
} }
} }

View File

@ -22,9 +22,15 @@ package org.elasticsearch.action.admin.indices.segments;
import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.action.support.broadcast.BroadcastOperationRequest; import org.elasticsearch.action.support.broadcast.BroadcastOperationRequest;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import java.io.IOException;
public class IndicesSegmentsRequest extends BroadcastOperationRequest<IndicesSegmentsRequest> { public class IndicesSegmentsRequest extends BroadcastOperationRequest<IndicesSegmentsRequest> {
protected boolean verbose = false;
public IndicesSegmentsRequest() { public IndicesSegmentsRequest() {
this(Strings.EMPTY_ARRAY); this(Strings.EMPTY_ARRAY);
} }
@ -33,4 +39,34 @@ public class IndicesSegmentsRequest extends BroadcastOperationRequest<IndicesSeg
super(indices); super(indices);
indicesOptions(IndicesOptions.fromOptions(false, false, true, false)); indicesOptions(IndicesOptions.fromOptions(false, false, true, false));
} }
/**
* <code>true</code> if detailed information about each segment should be returned,
* <code>false</code> otherwise.
*/
public boolean verbose() {
return verbose;
}
/**
* Sets the <code>verbose</code> option.
* @see #verbose()
*/
public void verbose(boolean v) {
verbose = v;
}
@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);
out.writeBoolean(verbose);
}
@Override
public void readFrom(StreamInput in) throws IOException {
super.readFrom(in);
verbose = in.readBoolean();
}
} }

View File

@ -32,6 +32,11 @@ public class IndicesSegmentsRequestBuilder extends BroadcastOperationRequestBuil
super(indicesClient, new IndicesSegmentsRequest()); super(indicesClient, new IndicesSegmentsRequest());
} }
public IndicesSegmentsRequestBuilder setVerbose(boolean verbose) {
request.verbose = verbose;
return this;
}
@Override @Override
protected void doExecute(ActionListener<IndicesSegmentResponse> listener) { protected void doExecute(ActionListener<IndicesSegmentResponse> listener) {
client.segments(request, listener); client.segments(request, listener);

View File

@ -131,16 +131,19 @@ public class TransportIndicesSegmentsAction extends TransportBroadcastOperationA
protected ShardSegments shardOperation(IndexShardSegmentRequest request) throws ElasticsearchException { protected ShardSegments shardOperation(IndexShardSegmentRequest request) throws ElasticsearchException {
IndexService indexService = indicesService.indexServiceSafe(request.shardId().getIndex()); IndexService indexService = indicesService.indexServiceSafe(request.shardId().getIndex());
IndexShard indexShard = indexService.shardSafe(request.shardId().id()); IndexShard indexShard = indexService.shardSafe(request.shardId().id());
return new ShardSegments(indexShard.routingEntry(), indexShard.engine().segments()); return new ShardSegments(indexShard.routingEntry(), indexShard.engine().segments(request.verbose));
} }
static class IndexShardSegmentRequest extends BroadcastShardOperationRequest { static class IndexShardSegmentRequest extends BroadcastShardOperationRequest {
final boolean verbose;
IndexShardSegmentRequest() { IndexShardSegmentRequest() {
verbose = false;
} }
IndexShardSegmentRequest(ShardId shardId, IndicesSegmentsRequest request) { IndexShardSegmentRequest(ShardId shardId, IndicesSegmentsRequest request) {
super(shardId, request); super(shardId, request);
verbose = request.verbose();
} }
} }
} }

View File

@ -103,7 +103,7 @@ public interface Engine extends CloseableComponent {
/** /**
* The list of segments in the engine. * The list of segments in the engine.
*/ */
List<Segment> segments(); List<Segment> segments(boolean verbose);
/** /**
* Returns <tt>true</tt> if a refresh is really needed. * Returns <tt>true</tt> if a refresh is really needed.

View File

@ -19,6 +19,9 @@
package org.elasticsearch.index.engine; package org.elasticsearch.index.engine;
import com.google.common.collect.Iterators;
import org.apache.lucene.util.Accountable;
import org.apache.lucene.util.Accountables;
import org.elasticsearch.common.Nullable; import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.StreamOutput;
@ -27,6 +30,10 @@ import org.elasticsearch.common.lucene.Lucene;
import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.unit.ByteSizeValue;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
public class Segment implements Streamable { public class Segment implements Streamable {
@ -41,6 +48,7 @@ public class Segment implements Streamable {
public Boolean compound = null; public Boolean compound = null;
public String mergeId; public String mergeId;
public long memoryInBytes; public long memoryInBytes;
public Accountable ramTree = null;
Segment() { Segment() {
} }
@ -143,6 +151,10 @@ public class Segment implements Streamable {
compound = in.readOptionalBoolean(); compound = in.readOptionalBoolean();
mergeId = in.readOptionalString(); mergeId = in.readOptionalString();
memoryInBytes = in.readLong(); memoryInBytes = in.readLong();
if (in.readBoolean()) {
// verbose mode
ramTree = readRamTree(in);
}
} }
@Override @Override
@ -157,6 +169,37 @@ public class Segment implements Streamable {
out.writeOptionalBoolean(compound); out.writeOptionalBoolean(compound);
out.writeOptionalString(mergeId); out.writeOptionalString(mergeId);
out.writeLong(memoryInBytes); out.writeLong(memoryInBytes);
boolean verbose = ramTree != null;
out.writeBoolean(verbose);
if (verbose) {
writeRamTree(out, ramTree);
}
}
Accountable readRamTree(StreamInput in) throws IOException {
final String name = in.readString();
final long bytes = in.readVLong();
int numChildren = in.readVInt();
if (numChildren == 0) {
return Accountables.namedAccountable(name, bytes);
}
List<Accountable> children = new ArrayList(numChildren);
while (numChildren-- > 0) {
children.add(readRamTree(in));
}
return Accountables.namedAccountable(name, children, bytes);
}
// the ram tree is written recursively since the depth is fairly low (5 or 6)
void writeRamTree(StreamOutput out, Accountable tree) throws IOException {
out.writeString(tree.toString());
out.writeVLong(tree.ramBytesUsed());
Collection<Accountable> children = tree.getChildResources();
out.writeVInt(children.size());
for (Accountable child : children) {
writeRamTree(out, child);
}
} }
@Override @Override

View File

@ -27,6 +27,7 @@ import org.apache.lucene.search.*;
import org.apache.lucene.store.AlreadyClosedException; import org.apache.lucene.store.AlreadyClosedException;
import org.apache.lucene.store.LockObtainFailedException; import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.util.Accountable; import org.apache.lucene.util.Accountable;
import org.apache.lucene.util.Accountables;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.IOUtils; import org.apache.lucene.util.IOUtils;
import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchException;
@ -1266,7 +1267,7 @@ public class InternalEngine implements Engine {
} }
@Override @Override
public List<Segment> segments() { public List<Segment> segments(boolean verbose) {
try (InternalLock _ = readLock.acquire()) { try (InternalLock _ = readLock.acquire()) {
ensureOpen(); ensureOpen();
Map<String, Segment> segments = new HashMap<>(); Map<String, Segment> segments = new HashMap<>();
@ -1290,6 +1291,9 @@ public class InternalEngine implements Engine {
} }
final SegmentReader segmentReader = segmentReader(reader.reader()); final SegmentReader segmentReader = segmentReader(reader.reader());
segment.memoryInBytes = segmentReader.ramBytesUsed(); segment.memoryInBytes = segmentReader.ramBytesUsed();
if (verbose) {
segment.ramTree = Accountables.namedAccountable("root", segmentReader);
}
// TODO: add more fine grained mem stats values to per segment info here // TODO: add more fine grained mem stats values to per segment info here
segments.put(info.info.name, segment); segments.put(info.info.name, segment);
} }

View File

@ -274,8 +274,8 @@ public class InternalEngineHolder extends AbstractIndexShardComponent implements
} }
@Override @Override
public List<Segment> segments() { public List<Segment> segments(boolean verbose) {
return engineSafe().segments(); return engineSafe().segments(verbose);
} }
@Override @Override

View File

@ -48,6 +48,7 @@ public class RestIndicesSegmentsAction extends BaseRestHandler {
@Override @Override
public void handleRequest(final RestRequest request, final RestChannel channel, final Client client) { public void handleRequest(final RestRequest request, final RestChannel channel, final Client client) {
IndicesSegmentsRequest indicesSegmentsRequest = new IndicesSegmentsRequest(Strings.splitStringByCommaToArray(request.param("index"))); IndicesSegmentsRequest indicesSegmentsRequest = new IndicesSegmentsRequest(Strings.splitStringByCommaToArray(request.param("index")));
indicesSegmentsRequest.verbose(request.paramAsBoolean("verbose", false));
indicesSegmentsRequest.listenerThreaded(false); indicesSegmentsRequest.listenerThreaded(false);
indicesSegmentsRequest.indicesOptions(IndicesOptions.fromRequest(request, indicesSegmentsRequest.indicesOptions())); indicesSegmentsRequest.indicesOptions(IndicesOptions.fromRequest(request, indicesSegmentsRequest.indicesOptions()));
client.admin().indices().segments(indicesSegmentsRequest, new RestBuilderListener<IndicesSegmentResponse>(channel) { client.admin().indices().segments(indicesSegmentsRequest, new RestBuilderListener<IndicesSegmentResponse>(channel) {

View File

@ -0,0 +1,59 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.action.admin.indices.segments;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.engine.Segment;
import org.elasticsearch.test.ElasticsearchSingleNodeTest;
import org.junit.Before;
import java.util.List;
public class IndicesSegmentsRequestTests extends ElasticsearchSingleNodeTest {
@Before
public void setupIndex() {
Settings settings = ImmutableSettings.builder()
// don't allow any merges so that the num docs is the expected segments
.put("index.merge.policy.segments_per_tier", 1000000f)
.build();
createIndex("test", settings);
int numDocs = scaledRandomIntBetween(100, 1000);
for (int j = 0; j < numDocs; ++j) {
String id = Integer.toString(j);
client().prepareIndex("test", "type1", id).setSource("text", "sometext").get();
}
client().admin().indices().prepareFlush("test").get();
}
public void testBasic() {
IndicesSegmentResponse rsp = client().admin().indices().prepareSegments("test").get();
List<Segment> segments = rsp.getIndices().get("test").iterator().next().getShards()[0].getSegments();
assertNull(segments.get(0).ramTree);
}
public void testVerbose() {
IndicesSegmentResponse rsp = client().admin().indices().prepareSegments("test").setVerbose(true).get();
List<Segment> segments = rsp.getIndices().get("test").iterator().next().getShards()[0].getSegments();
assertNotNull(segments.get(0).ramTree);
}
}

View File

@ -241,7 +241,7 @@ public class InternalEngineTests extends ElasticsearchLuceneTestCase {
@Test @Test
public void testSegments() throws Exception { public void testSegments() throws Exception {
List<Segment> segments = engine.segments(); List<Segment> segments = engine.segments(false);
assertThat(segments.isEmpty(), equalTo(true)); assertThat(segments.isEmpty(), equalTo(true));
assertThat(engine.segmentsStats().getCount(), equalTo(0l)); assertThat(engine.segmentsStats().getCount(), equalTo(0l));
assertThat(engine.segmentsStats().getMemoryInBytes(), equalTo(0l)); assertThat(engine.segmentsStats().getMemoryInBytes(), equalTo(0l));
@ -255,7 +255,7 @@ public class InternalEngineTests extends ElasticsearchLuceneTestCase {
engine.create(new Engine.Create(null, newUid("2"), doc2)); engine.create(new Engine.Create(null, newUid("2"), doc2));
engine.refresh("test", false); engine.refresh("test", false);
segments = engine.segments(); segments = engine.segments(false);
assertThat(segments.size(), equalTo(1)); assertThat(segments.size(), equalTo(1));
SegmentsStats stats = engine.segmentsStats(); SegmentsStats stats = engine.segmentsStats();
assertThat(stats.getCount(), equalTo(1l)); assertThat(stats.getCount(), equalTo(1l));
@ -269,10 +269,11 @@ public class InternalEngineTests extends ElasticsearchLuceneTestCase {
assertThat(segments.get(0).getNumDocs(), equalTo(2)); assertThat(segments.get(0).getNumDocs(), equalTo(2));
assertThat(segments.get(0).getDeletedDocs(), equalTo(0)); assertThat(segments.get(0).getDeletedDocs(), equalTo(0));
assertThat(segments.get(0).isCompound(), equalTo(defaultCompound)); assertThat(segments.get(0).isCompound(), equalTo(defaultCompound));
assertThat(segments.get(0).ramTree, nullValue());
engine.flush(Engine.FlushType.COMMIT_TRANSLOG, false, false); engine.flush(Engine.FlushType.COMMIT_TRANSLOG, false, false);
segments = engine.segments(); segments = engine.segments(false);
assertThat(segments.size(), equalTo(1)); assertThat(segments.size(), equalTo(1));
assertThat(engine.segmentsStats().getCount(), equalTo(1l)); assertThat(engine.segmentsStats().getCount(), equalTo(1l));
assertThat(segments.get(0).isCommitted(), equalTo(true)); assertThat(segments.get(0).isCommitted(), equalTo(true));
@ -287,7 +288,7 @@ public class InternalEngineTests extends ElasticsearchLuceneTestCase {
engine.create(new Engine.Create(null, newUid("3"), doc3)); engine.create(new Engine.Create(null, newUid("3"), doc3));
engine.refresh("test", false); engine.refresh("test", false);
segments = engine.segments(); segments = engine.segments(false);
assertThat(segments.size(), equalTo(2)); assertThat(segments.size(), equalTo(2));
assertThat(engine.segmentsStats().getCount(), equalTo(2l)); assertThat(engine.segmentsStats().getCount(), equalTo(2l));
assertThat(engine.segmentsStats().getTermsMemoryInBytes(), greaterThan(stats.getTermsMemoryInBytes())); assertThat(engine.segmentsStats().getTermsMemoryInBytes(), greaterThan(stats.getTermsMemoryInBytes()));
@ -313,7 +314,7 @@ public class InternalEngineTests extends ElasticsearchLuceneTestCase {
engine.delete(new Engine.Delete("test", "1", newUid("1"))); engine.delete(new Engine.Delete("test", "1", newUid("1")));
engine.refresh("test", false); engine.refresh("test", false);
segments = engine.segments(); segments = engine.segments(false);
assertThat(segments.size(), equalTo(2)); assertThat(segments.size(), equalTo(2));
assertThat(engine.segmentsStats().getCount(), equalTo(2l)); assertThat(engine.segmentsStats().getCount(), equalTo(2l));
assertThat(segments.get(0).getGeneration() < segments.get(1).getGeneration(), equalTo(true)); assertThat(segments.get(0).getGeneration() < segments.get(1).getGeneration(), equalTo(true));
@ -334,7 +335,7 @@ public class InternalEngineTests extends ElasticsearchLuceneTestCase {
engine.create(new Engine.Create(null, newUid("4"), doc4)); engine.create(new Engine.Create(null, newUid("4"), doc4));
engine.refresh("test", false); engine.refresh("test", false);
segments = engine.segments(); segments = engine.segments(false);
assertThat(segments.size(), equalTo(3)); assertThat(segments.size(), equalTo(3));
assertThat(engine.segmentsStats().getCount(), equalTo(3l)); assertThat(engine.segmentsStats().getCount(), equalTo(3l));
assertThat(segments.get(0).getGeneration() < segments.get(1).getGeneration(), equalTo(true)); assertThat(segments.get(0).getGeneration() < segments.get(1).getGeneration(), equalTo(true));
@ -357,6 +358,33 @@ public class InternalEngineTests extends ElasticsearchLuceneTestCase {
assertThat(segments.get(2).isCompound(), equalTo(true)); assertThat(segments.get(2).isCompound(), equalTo(true));
} }
public void testVerboseSegments() throws Exception {
List<Segment> segments = engine.segments(true);
assertThat(segments.isEmpty(), equalTo(true));
ParsedDocument doc = testParsedDocument("1", "1", "test", null, -1, -1, testDocumentWithTextField(), Lucene.STANDARD_ANALYZER, B_1, false);
engine.create(new Engine.Create(null, newUid("1"), doc));
engine.refresh("test", false);
segments = engine.segments(true);
assertThat(segments.size(), equalTo(1));
assertThat(segments.get(0).ramTree, notNullValue());
ParsedDocument doc2 = testParsedDocument("2", "2", "test", null, -1, -1, testDocumentWithTextField(), Lucene.STANDARD_ANALYZER, B_2, false);
engine.create(new Engine.Create(null, newUid("2"), doc2));
engine.refresh("test", false);
ParsedDocument doc3 = testParsedDocument("3", "3", "test", null, -1, -1, testDocumentWithTextField(), Lucene.STANDARD_ANALYZER, B_3, false);
engine.create(new Engine.Create(null, newUid("3"), doc3));
engine.refresh("test", false);
segments = engine.segments(true);
assertThat(segments.size(), equalTo(3));
assertThat(segments.get(0).ramTree, notNullValue());
assertThat(segments.get(1).ramTree, notNullValue());
assertThat(segments.get(2).ramTree, notNullValue());
}
public void testStartAndAcquireConcurrently() throws IOException { public void testStartAndAcquireConcurrently() throws IOException {
ConcurrentMergeSchedulerProvider mergeSchedulerProvider = new ConcurrentMergeSchedulerProvider(shardId, EMPTY_SETTINGS, threadPool, new IndexSettingsService(shardId.index(), EMPTY_SETTINGS)); ConcurrentMergeSchedulerProvider mergeSchedulerProvider = new ConcurrentMergeSchedulerProvider(shardId, EMPTY_SETTINGS, threadPool, new IndexSettingsService(shardId.index(), EMPTY_SETTINGS));
final Store store = createStore(); final Store store = createStore();
@ -419,19 +447,21 @@ public class InternalEngineTests extends ElasticsearchLuceneTestCase {
Engine.Index index = new Engine.Index(null, newUid("1"), doc); Engine.Index index = new Engine.Index(null, newUid("1"), doc);
engine.index(index); engine.index(index);
engine.flush(Engine.FlushType.COMMIT_TRANSLOG, false, false); engine.flush(Engine.FlushType.COMMIT_TRANSLOG, false, false);
assertThat(engine.segments().size(), equalTo(1)); assertThat(engine.segments(false).size(), equalTo(1));
index = new Engine.Index(null, newUid("2"), doc); index = new Engine.Index(null, newUid("2"), doc);
engine.index(index); engine.index(index);
engine.flush(Engine.FlushType.COMMIT_TRANSLOG, false, false); engine.flush(Engine.FlushType.COMMIT_TRANSLOG, false, false);
assertThat(engine.segments().size(), equalTo(2)); List<Segment> segments = engine.segments(false);
for (Segment segment : engine.segments()) { assertThat(segments.size(), equalTo(2));
for (Segment segment : segments) {
assertThat(segment.getMergeId(), nullValue()); assertThat(segment.getMergeId(), nullValue());
} }
index = new Engine.Index(null, newUid("3"), doc); index = new Engine.Index(null, newUid("3"), doc);
engine.index(index); engine.index(index);
engine.flush(Engine.FlushType.COMMIT_TRANSLOG, false, false); engine.flush(Engine.FlushType.COMMIT_TRANSLOG, false, false);
assertThat(engine.segments().size(), equalTo(3)); segments = engine.segments(false);
for (Segment segment : engine.segments()) { assertThat(segments.size(), equalTo(3));
for (Segment segment : segments) {
assertThat(segment.getMergeId(), nullValue()); assertThat(segment.getMergeId(), nullValue());
} }
@ -440,7 +470,7 @@ public class InternalEngineTests extends ElasticsearchLuceneTestCase {
engine.forceMerge(false, false); engine.forceMerge(false, false);
waitTillMerge.get().await(); waitTillMerge.get().await();
for (Segment segment : engine.segments()) { for (Segment segment : engine.segments(false)) {
assertThat(segment.getMergeId(), notNullValue()); assertThat(segment.getMergeId(), notNullValue());
} }
@ -453,7 +483,7 @@ public class InternalEngineTests extends ElasticsearchLuceneTestCase {
// now, optimize and wait for merges, see that we have no merge flag // now, optimize and wait for merges, see that we have no merge flag
engine.forceMerge(true, true); engine.forceMerge(true, true);
for (Segment segment : engine.segments()) { for (Segment segment : engine.segments(false)) {
assertThat(segment.getMergeId(), nullValue()); assertThat(segment.getMergeId(), nullValue());
} }
// we could have multiple underlying merges, so the generation may increase more than once // we could have multiple underlying merges, so the generation may increase more than once
@ -463,7 +493,7 @@ public class InternalEngineTests extends ElasticsearchLuceneTestCase {
final long gen2 = store.readLastCommittedSegmentsInfo().getGeneration(); final long gen2 = store.readLastCommittedSegmentsInfo().getGeneration();
engine.forceMerge(flush, false); engine.forceMerge(flush, false);
waitTillMerge.get().await(); waitTillMerge.get().await();
for (Segment segment : engine.segments()) { for (Segment segment : engine.segments(false)) {
assertThat(segment.getMergeId(), nullValue()); assertThat(segment.getMergeId(), nullValue());
} }
waitForMerge.get().countDown(); waitForMerge.get().countDown();