Expose field level field data statistics

closes #2889
This commit is contained in:
Shay Banon 2013-04-12 15:51:08 -07:00
parent 3b7a195f6f
commit a2d72697eb
18 changed files with 340 additions and 147 deletions

View File

@ -25,6 +25,7 @@ import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import java.io.IOException;
import java.util.Map;
@ -118,4 +119,17 @@ public class NodesStatsResponse extends NodesOperationResponse<NodeStats> implem
return builder;
}
@Override
public String toString() {
try {
XContentBuilder builder = XContentFactory.jsonBuilder().prettyPrint();
builder.startObject();
toXContent(builder, EMPTY_PARAMS);
builder.endObject();
return builder.string();
} catch (IOException e) {
return "{ \"error\" : \"" + e.getMessage() + "\"}";
}
}
}

View File

@ -28,10 +28,11 @@ import java.util.EnumSet;
/**
*/
public class CommonStatsFlags implements Streamable {
public class CommonStatsFlags implements Streamable, Cloneable {
private EnumSet<Flag> flags = EnumSet.of(Flag.Docs, Flag.Store, Flag.Indexing, Flag.Get, Flag.Search);
private String[] types = null;
private String[] groups = null;
private String[] fieldDataFields = null;
/**
* Sets all flags to return all stats.
@ -40,6 +41,7 @@ public class CommonStatsFlags implements Streamable {
flags = EnumSet.allOf(Flag.class);
types = null;
groups = null;
fieldDataFields = null;
return this;
}
@ -50,13 +52,14 @@ public class CommonStatsFlags implements Streamable {
flags = EnumSet.noneOf(Flag.class);
types = null;
groups = null;
fieldDataFields = null;
return this;
}
public boolean anySet() {
return !flags.isEmpty();
}
public Flag[] getFlags() {
return flags.toArray(new Flag[flags.size()]);
}
@ -90,19 +93,33 @@ public class CommonStatsFlags implements Streamable {
public String[] groups() {
return this.groups;
}
/**
* Sets specific search group stats to retrieve the stats for. Mainly affects search
* when enabled.
*/
public CommonStatsFlags fieldDataFields(String... fieldDataFields) {
this.fieldDataFields = fieldDataFields;
return this;
}
public String[] fieldDataFields() {
return this.fieldDataFields;
}
public boolean isSet(Flag flag) {
return flags.contains(flag);
}
boolean unSet(Flag flag) {
return flags.remove(flag);
}
void set(Flag flag) {
flags.add(flag);
}
public CommonStatsFlags set(Flag flag, boolean add) {
if (add) {
set(flag);
@ -125,49 +142,37 @@ public class CommonStatsFlags implements Streamable {
longFlags |= (1 << flag.ordinal());
}
out.writeLong(longFlags);
if (types == null) {
out.writeVInt(0);
} else {
out.writeVInt(types.length);
for (String type : types) {
out.writeString(type);
}
}
if (groups == null) {
out.writeVInt(0);
} else {
out.writeVInt(groups.length);
for (String group : groups) {
out.writeString(group);
}
}
out.writeStringArrayNullable(types);
out.writeStringArrayNullable(groups);
out.writeStringArrayNullable(fieldDataFields);
}
@Override
public void readFrom(StreamInput in) throws IOException {
final long longFlags = in.readLong();
flags.clear();
for(Flag flag : Flag.values()) {
for (Flag flag : Flag.values()) {
if ((longFlags & (1 << flag.ordinal())) != 0) {
flags.add(flag);
}
}
int size = in.readVInt();
if (size > 0) {
types = new String[size];
for (int i = 0; i < size; i++) {
types[i] = in.readString();
}
}
size = in.readVInt();
if (size > 0) {
groups = new String[size];
for (int i = 0; i < size; i++) {
groups[i] = in.readString();
}
types = in.readStringArray();
groups = in.readStringArray();
fieldDataFields = in.readStringArray();
}
@Override
public CommonStatsFlags clone() {
try {
CommonStatsFlags cloned = (CommonStatsFlags) super.clone();
cloned.flags = flags.clone();
return cloned;
} catch (CloneNotSupportedException e) {
throw new AssertionError(e);
}
}
public static enum Flag {
// Do not change the order of these flags we use
// the ordinal for encoding! Only append to the end!
@ -183,16 +188,16 @@ public class CommonStatsFlags implements Streamable {
FieldData("fielddata"),
Docs("docs"),
Warmer("warmer");
private final String restName;
Flag(String restName) {
this.restName = restName;
}
public String getRestName() {
return restName;
}
}
}

View File

@ -19,13 +19,13 @@
package org.elasticsearch.action.admin.indices.stats;
import java.io.IOException;
import org.elasticsearch.action.admin.indices.stats.CommonStatsFlags.Flag;
import org.elasticsearch.action.support.broadcast.BroadcastOperationRequest;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import java.io.IOException;
/**
* A request to get indices level stats. Allow to enable different stats to be returned.
* <p/>
@ -141,7 +141,7 @@ public class IndicesStatsRequest extends BroadcastOperationRequest<IndicesStatsR
}
public IndicesStatsRequest refresh(boolean refresh) {
flags.set(Flag.Refresh, refresh);
flags.set(Flag.Refresh, refresh);
return this;
}
@ -194,6 +194,15 @@ public class IndicesStatsRequest extends BroadcastOperationRequest<IndicesStatsR
return flags.isSet(Flag.FieldData);
}
public IndicesStatsRequest fieldDataFields(String... fieldDataFields) {
flags.fieldDataFields(fieldDataFields);
return this;
}
public String[] fieldDataFields() {
return flags.fieldDataFields();
}
@Override
public void writeTo(StreamOutput out) throws IOException {
super.writeTo(out);

View File

@ -129,6 +129,11 @@ public class IndicesStatsRequestBuilder extends BroadcastOperationRequestBuilder
return this;
}
public IndicesStatsRequestBuilder setFieldDataFields(String... fields) {
request.fieldDataFields(fields);
return this;
}
@Override
protected void doExecute(ActionListener<IndicesStatsResponse> listener) {
((IndicesAdminClient) client).stats(request, listener);

View File

@ -30,6 +30,7 @@ import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentBuilderString;
import org.elasticsearch.common.xcontent.XContentFactory;
import java.io.IOException;
import java.util.List;
@ -202,4 +203,17 @@ public class IndicesStatsResponse extends BroadcastOperationResponse implements
static final XContentBuilderString NODE = new XContentBuilderString("node");
static final XContentBuilderString RELOCATING_NODE = new XContentBuilderString("relocating_node");
}
@Override
public String toString() {
try {
XContentBuilder builder = XContentFactory.jsonBuilder().prettyPrint();
builder.startObject();
toXContent(builder, EMPTY_PARAMS);
builder.endObject();
return builder.string();
} catch (IOException e) {
return "{ \"error\" : \"" + e.getMessage() + "\"}";
}
}
}

View File

@ -179,7 +179,7 @@ public class TransportIndicesStatsAction extends TransportBroadcastOperationActi
stats.stats.idCache = indexShard.idCacheStats();
}
if (request.request.fieldData()) {
stats.stats.fieldData = indexShard.fieldDataStats();
stats.stats.fieldData = indexShard.fieldDataStats(request.request.fieldDataFields());
}
return stats;

View File

@ -171,6 +171,9 @@ public class PathTrie<T> {
}
if (index == (path.length - 1)) {
if (params != null && node.isNamedWildcard()) {
put(params, node.namedWildcard(), token);
}
return node.value;
}

View File

@ -19,6 +19,9 @@
package org.elasticsearch.index.fielddata;
import gnu.trove.iterator.TObjectLongIterator;
import gnu.trove.map.hash.TObjectLongHashMap;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Streamable;
@ -35,19 +38,29 @@ public class FieldDataStats implements Streamable, ToXContent {
long memorySize;
long evictions;
@Nullable
TObjectLongHashMap<String> fields;
public FieldDataStats() {
}
public FieldDataStats(long memorySize, long evictions) {
public FieldDataStats(long memorySize, long evictions, @Nullable TObjectLongHashMap<String> fields) {
this.memorySize = memorySize;
this.evictions = evictions;
this.fields = fields;
}
public void add(FieldDataStats stats) {
this.memorySize += stats.memorySize;
this.evictions += stats.evictions;
if (stats.fields != null) {
if (fields == null) fields = new TObjectLongHashMap<String>();
for (TObjectLongIterator<String> it = stats.fields.iterator(); it.hasNext(); ) {
it.advance();
fields.adjustOrPutValue(it.key(), it.value(), it.value());
}
}
}
public long getMemorySizeInBytes() {
@ -62,6 +75,11 @@ public class FieldDataStats implements Streamable, ToXContent {
return this.evictions;
}
@Nullable
public TObjectLongHashMap<String> getFields() {
return fields;
}
public static FieldDataStats readFieldDataStats(StreamInput in) throws IOException {
FieldDataStats stats = new FieldDataStats();
stats.readFrom(in);
@ -72,12 +90,30 @@ public class FieldDataStats implements Streamable, ToXContent {
public void readFrom(StreamInput in) throws IOException {
memorySize = in.readVLong();
evictions = in.readVLong();
if (in.readBoolean()) {
int size = in.readVInt();
fields = new TObjectLongHashMap<String>(size);
for (int i = 0; i < size; i++) {
fields.put(in.readString(), in.readVLong());
}
}
}
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeVLong(memorySize);
out.writeVLong(evictions);
if (fields == null) {
out.writeBoolean(false);
} else {
out.writeBoolean(true);
out.writeVInt(fields.size());
for (TObjectLongIterator<String> it = fields.iterator(); it.hasNext(); ) {
it.advance();
out.writeString(it.key());
out.writeVLong(it.value());
}
}
}
@Override
@ -86,6 +122,17 @@ public class FieldDataStats implements Streamable, ToXContent {
builder.field(Fields.MEMORY_SIZE, getMemorySize().toString());
builder.field(Fields.MEMORY_SIZE_IN_BYTES, memorySize);
builder.field(Fields.EVICTIONS, getEvictions());
if (fields != null) {
builder.startObject(Fields.FIELDS);
for (TObjectLongIterator<String> it = fields.iterator(); it.hasNext(); ) {
it.advance();
builder.startObject(it.key(), XContentBuilder.FieldCaseConversion.NONE);
builder.field(Fields.MEMORY_SIZE, new ByteSizeValue(it.value()).toString());
builder.field(Fields.MEMORY_SIZE_IN_BYTES, it.value());
builder.endObject();
}
builder.endObject();
}
builder.endObject();
return builder;
}
@ -95,5 +142,6 @@ public class FieldDataStats implements Streamable, ToXContent {
static final XContentBuilderString MEMORY_SIZE = new XContentBuilderString("memory_size");
static final XContentBuilderString MEMORY_SIZE_IN_BYTES = new XContentBuilderString("memory_size_in_bytes");
static final XContentBuilderString EVICTIONS = new XContentBuilderString("evictions");
static final XContentBuilderString FIELDS = new XContentBuilderString("fields");
}
}

View File

@ -82,7 +82,11 @@ public interface IndexFieldDataCache {
@Override
public void onRemoval(RemovalNotification<Key, AtomicFieldData> notification) {
if (notification.getKey() != null) {
notification.getKey().listener.onUnload(fieldNames, fieldDataType, notification.wasEvicted(), notification.getKey().sizeInBytes, notification.getValue());
long sizeInBytes = notification.getKey().sizeInBytes;
if (sizeInBytes == -1 && notification.getValue() != null) {
sizeInBytes = notification.getValue().getMemorySizeInBytes();
}
notification.getKey().listener.onUnload(fieldNames, fieldDataType, notification.wasEvicted(), sizeInBytes, notification.getValue());
}
}

View File

@ -19,15 +19,21 @@
package org.elasticsearch.index.fielddata;
import gnu.trove.map.hash.TObjectLongHashMap;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.metrics.CounterMetric;
import org.elasticsearch.common.regex.Regex;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.ConcurrentCollections;
import org.elasticsearch.index.mapper.FieldMapper;
import org.elasticsearch.index.settings.IndexSettings;
import org.elasticsearch.index.shard.AbstractIndexShardComponent;
import org.elasticsearch.index.shard.ShardId;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
/**
*/
public class ShardFieldData extends AbstractIndexShardComponent implements IndexFieldDataCache.Listener {
@ -35,19 +41,46 @@ public class ShardFieldData extends AbstractIndexShardComponent implements Index
final CounterMetric evictionsMetric = new CounterMetric();
final CounterMetric totalMetric = new CounterMetric();
final ConcurrentMap<String, CounterMetric> perFieldTotals = ConcurrentCollections.newConcurrentMap();
@Inject
public ShardFieldData(ShardId shardId, @IndexSettings Settings indexSettings) {
super(shardId, indexSettings);
}
public FieldDataStats stats() {
return new FieldDataStats(totalMetric.count(), evictionsMetric.count());
public FieldDataStats stats(String... fields) {
TObjectLongHashMap<String> fieldTotals = null;
if (fields != null && fields.length > 0) {
fieldTotals = new TObjectLongHashMap<String>();
for (Map.Entry<String, CounterMetric> entry : perFieldTotals.entrySet()) {
for (String field : fields) {
if (Regex.simpleMatch(field, entry.getKey())) {
fieldTotals.put(entry.getKey(), entry.getValue().count());
}
}
}
}
return new FieldDataStats(totalMetric.count(), evictionsMetric.count(), fieldTotals);
}
@Override
public void onLoad(FieldMapper.Names fieldNames, FieldDataType fieldDataType, AtomicFieldData fieldData) {
totalMetric.inc(fieldData.getMemorySizeInBytes());
long sizeInBytes = fieldData.getMemorySizeInBytes();
totalMetric.inc(sizeInBytes);
String keyFieldName = fieldNames.indexName();
CounterMetric total = perFieldTotals.get(keyFieldName);
if (total != null) {
total.inc(sizeInBytes);
} else {
total = new CounterMetric();
total.inc(sizeInBytes);
CounterMetric prev = perFieldTotals.putIfAbsent(keyFieldName, total);
if (prev != null) {
prev.inc(sizeInBytes);
}
}
}
@Override
@ -57,8 +90,12 @@ public class ShardFieldData extends AbstractIndexShardComponent implements Index
}
if (sizeInBytes != -1) {
totalMetric.dec(sizeInBytes);
} else if (fieldData != null) {
totalMetric.dec(fieldData.getMemorySizeInBytes());
String keyFieldName = fieldNames.indexName();
CounterMetric total = perFieldTotals.get(keyFieldName);
if (total != null) {
total.dec(sizeInBytes);
}
}
}
}

View File

@ -92,7 +92,7 @@ public interface IndexShard extends IndexShardComponent {
IdCacheStats idCacheStats();
FieldDataStats fieldDataStats();
FieldDataStats fieldDataStats(String... fields);
IndexShardState state();

View File

@ -477,8 +477,8 @@ public class InternalIndexShard extends AbstractIndexShardComponent implements I
}
@Override
public FieldDataStats fieldDataStats() {
return shardFieldData.stats();
public FieldDataStats fieldDataStats(String... fields) {
return shardFieldData.stats(fields);
}
@Override

View File

@ -192,98 +192,110 @@ public class InternalIndicesService extends AbstractLifecycleComponent<IndicesSe
public NodeIndicesStats stats(boolean includePrevious, CommonStatsFlags flags) {
CommonStats stats = new CommonStats();
Flag[] setFlags = flags.getFlags();
for(Flag flag : setFlags) {
for (Flag flag : setFlags) {
switch (flag) {
case Docs:
stats.docs = new DocsStats();
break;
case Store:
stats.store = new StoreStats();
break;
case Warmer:
stats.warmer = new WarmerStats();
break;
case Get:
stats.get = new GetStats();
if (includePrevious) {stats.get.add(oldShardsStats.getStats);}
break;
case Indexing:
stats.indexing = new IndexingStats();
if (includePrevious) {stats.indexing.add(oldShardsStats.indexingStats);}
break;
case Search:
stats.search = new SearchStats();
if (includePrevious) {stats.search.add(oldShardsStats.searchStats);}
break;
case Merge:
stats.merge = new MergeStats();
if (includePrevious) {stats.merge.add(oldShardsStats.mergeStats);}
break;
case Refresh:
stats.refresh = new RefreshStats();
if (includePrevious) {stats.refresh.add(oldShardsStats.refreshStats);}
break;
case Flush:
stats.flush = new FlushStats();
if (includePrevious) {stats.flush.add(oldShardsStats.flushStats);}
break;
case FieldData:
stats.fieldData = new FieldDataStats();
break;
case IdCache:
stats.idCache = new IdCacheStats();
break;
case FilterCache:
stats.filterCache = new FilterCacheStats();
break;
default:
throw new IllegalStateException("Unknown Flag: " + flag);
case Docs:
stats.docs = new DocsStats();
break;
case Store:
stats.store = new StoreStats();
break;
case Warmer:
stats.warmer = new WarmerStats();
break;
case Get:
stats.get = new GetStats();
if (includePrevious) {
stats.get.add(oldShardsStats.getStats);
}
break;
case Indexing:
stats.indexing = new IndexingStats();
if (includePrevious) {
stats.indexing.add(oldShardsStats.indexingStats);
}
break;
case Search:
stats.search = new SearchStats();
if (includePrevious) {
stats.search.add(oldShardsStats.searchStats);
}
break;
case Merge:
stats.merge = new MergeStats();
if (includePrevious) {
stats.merge.add(oldShardsStats.mergeStats);
}
break;
case Refresh:
stats.refresh = new RefreshStats();
if (includePrevious) {
stats.refresh.add(oldShardsStats.refreshStats);
}
break;
case Flush:
stats.flush = new FlushStats();
if (includePrevious) {
stats.flush.add(oldShardsStats.flushStats);
}
break;
case FieldData:
stats.fieldData = new FieldDataStats();
break;
case IdCache:
stats.idCache = new IdCacheStats();
break;
case FilterCache:
stats.filterCache = new FilterCacheStats();
break;
default:
throw new IllegalStateException("Unknown Flag: " + flag);
}
}
for (IndexService indexService : indices.values()) {
for (IndexShard indexShard : indexService) {
for(Flag flag : setFlags) {
for (Flag flag : setFlags) {
switch (flag) {
case Store:
stats.store.add(indexShard.storeStats());
break;
case Docs:
stats.docs.add(indexShard.docStats());
break;
case Get:
stats.get.add(indexShard.getStats());
break;
case Indexing:
stats.indexing.add(indexShard.indexingStats());
break;
case Search:
stats.search.add(indexShard.searchStats());
break;
case Merge:
stats.merge.add(indexShard.mergeStats());
break;
case Refresh:
stats.refresh.add(indexShard.refreshStats());
break;
case Flush:
stats.flush.add(indexShard.flushStats());
break;
case FilterCache:
stats.filterCache.add(indexShard.filterCacheStats());
break;
case IdCache:
stats.idCache.add(indexShard.idCacheStats());
break;
case FieldData:
stats.fieldData.add(indexShard.fieldDataStats());
break;
case Warmer:
stats.warmer.add(indexShard.warmerStats());
break;
default:
throw new IllegalStateException("Unknown Flag: " + flag);
case Store:
stats.store.add(indexShard.storeStats());
break;
case Docs:
stats.docs.add(indexShard.docStats());
break;
case Get:
stats.get.add(indexShard.getStats());
break;
case Indexing:
stats.indexing.add(indexShard.indexingStats());
break;
case Search:
stats.search.add(indexShard.searchStats());
break;
case Merge:
stats.merge.add(indexShard.mergeStats());
break;
case Refresh:
stats.refresh.add(indexShard.refreshStats());
break;
case Flush:
stats.flush.add(indexShard.flushStats());
break;
case FilterCache:
stats.filterCache.add(indexShard.filterCacheStats());
break;
case IdCache:
stats.idCache.add(indexShard.idCacheStats());
break;
case FieldData:
stats.fieldData.add(indexShard.fieldDataStats(flags.fieldDataFields()));
break;
case Warmer:
stats.warmer.add(indexShard.warmerStats());
break;
default:
throw new IllegalStateException("Unknown Flag: " + flag);
}
}
}

View File

@ -102,7 +102,11 @@ public class IndicesFieldDataCache extends AbstractComponent implements RemovalL
public void onRemoval(RemovalNotification<Key, AtomicFieldData> notification) {
if (notification.getKey() != null && notification.getKey().listener != null) {
IndexFieldCache indexCache = notification.getKey().indexCache;
notification.getKey().listener.onUnload(indexCache.fieldNames, indexCache.fieldDataType, notification.wasEvicted(), notification.getKey().sizeInBytes, notification.getValue());
long sizeInBytes = notification.getKey().sizeInBytes;
if (sizeInBytes == -1 && notification.getValue() != null) {
sizeInBytes = notification.getValue().getMemorySizeInBytes();
}
notification.getKey().listener.onUnload(indexCache.fieldNames, indexCache.fieldDataType, notification.wasEvicted(), sizeInBytes, notification.getValue());
}
}

View File

@ -58,7 +58,14 @@ public class RestNodesStatsAction extends BaseRestHandler {
controller.registerHandler(RestRequest.Method.GET, "/_nodes/stats/indices/" + flag.getRestName(), indicesHandler);
controller.registerHandler(RestRequest.Method.GET, "/_nodes/{nodeId}/stats/indices/" + flag.getRestName(), indicesHandler);
controller.registerHandler(RestRequest.Method.GET, "/_nodes/indices/" + flag.getRestName() + "/stats", indicesHandler);
controller.registerHandler(RestRequest.Method.GET, "/_nodes/{nodeId}/indices/" + flag.getRestName() + "/stats", indicesHandler);
controller.registerHandler(RestRequest.Method.GET, "/_nodes/{nodeId}/indices/" + flag.getRestName() + "/stats", indicesHandler);
if (flag == Flag.FieldData) {
// add field specific endpoint
controller.registerHandler(RestRequest.Method.GET, "/_nodes/stats/indices/" + flag.getRestName() + "/{fields}", indicesHandler);
controller.registerHandler(RestRequest.Method.GET, "/_nodes/{nodeId}/stats/indices/" + flag.getRestName() + "/{fields}", indicesHandler);
controller.registerHandler(RestRequest.Method.GET, "/_nodes/indices/" + flag.getRestName() + "/{fields}/stats", indicesHandler);
controller.registerHandler(RestRequest.Method.GET, "/_nodes/{nodeId}/indices/" + flag.getRestName() + "/{fields}/stats", indicesHandler);
}
}
RestOsHandler osHandler = new RestOsHandler();
@ -174,6 +181,10 @@ public class RestNodesStatsAction extends BaseRestHandler {
@Override
public void handleRequest(final RestRequest request, final RestChannel channel) {
NodesStatsRequest nodesStatsRequest = new NodesStatsRequest(RestActions.splitNodes(request.param("nodeId")));
CommonStatsFlags flags = this.flags;
if (flags.isSet(Flag.FieldData) && request.hasParam("fields")) {
flags = flags.clone().fieldDataFields(request.paramAsStringArray("fields", null));
}
nodesStatsRequest.clear().indices(flags);
executeNodeStats(request, channel, nodesStatsRequest);
}

View File

@ -86,6 +86,8 @@ public class RestIndicesStatsAction extends BaseRestHandler {
controller.registerHandler(GET, "/_stats/fielddata", new RestFieldDataStatsHandler());
controller.registerHandler(GET, "/{index}/_stats/fielddata", new RestFieldDataStatsHandler());
controller.registerHandler(GET, "/_stats/fielddata/{fields}", new RestFieldDataStatsHandler());
controller.registerHandler(GET, "/{index}/_stats/fielddata/{fields}", new RestFieldDataStatsHandler());
}
@Override
@ -548,6 +550,7 @@ public class RestIndicesStatsAction extends BaseRestHandler {
indicesStatsRequest.clear().fieldData(true);
indicesStatsRequest.indices(splitIndices(request.param("index")));
indicesStatsRequest.types(splitTypes(request.param("types")));
indicesStatsRequest.fieldDataFields(request.paramAsStringArray("fields", null));
client.admin().indices().stats(indicesStatsRequest, new ActionListener<IndicesStatsResponse>() {
@Override

View File

@ -20,6 +20,7 @@
package org.elasticsearch.test.integration.indices.cache;
import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsResponse;
import org.elasticsearch.action.admin.indices.stats.CommonStatsFlags;
import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
@ -34,8 +35,7 @@ import org.testng.annotations.Test;
import static org.elasticsearch.index.query.QueryBuilders.filteredQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.*;
/**
*/
@ -91,8 +91,8 @@ public class CacheTests extends AbstractNodesTests {
public void testFieldDataStats() {
client.admin().indices().prepareDelete().execute().actionGet();
client.admin().indices().prepareCreate("test").setSettings(ImmutableSettings.settingsBuilder().put("index.number_of_shards", 1)).execute().actionGet();
client.prepareIndex("test", "type", "1").setSource("field", "value1").execute().actionGet();
client.prepareIndex("test", "type", "2").setSource("field", "value2").execute().actionGet();
client.prepareIndex("test", "type", "1").setSource("field", "value1", "field2", "value1").execute().actionGet();
client.prepareIndex("test", "type", "2").setSource("field", "value2", "field2", "value2").execute().actionGet();
client.admin().indices().prepareRefresh().execute().actionGet();
NodesStatsResponse nodesStats = client.admin().cluster().prepareNodesStats().setIndices(true).execute().actionGet();
@ -109,12 +109,27 @@ public class CacheTests extends AbstractNodesTests {
indicesStats = client.admin().indices().prepareStats("test").clear().setFieldData(true).execute().actionGet();
assertThat(indicesStats.getTotal().getFieldData().getMemorySizeInBytes(), greaterThan(0l));
client.admin().indices().prepareClearCache().setFieldDataCache(true).execute().actionGet();
// sort to load it to field data...
client.prepareSearch().addSort("field2", SortOrder.ASC).execute().actionGet();
client.prepareSearch().addSort("field2", SortOrder.ASC).execute().actionGet();
// now check the per field stats
nodesStats = client.admin().cluster().prepareNodesStats().setIndices(new CommonStatsFlags().set(CommonStatsFlags.Flag.FieldData, true).fieldDataFields("*")).execute().actionGet();
assertThat(nodesStats.getNodes()[0].getIndices().getFieldData().getMemorySizeInBytes(), greaterThan(0l));
assertThat(nodesStats.getNodes()[0].getIndices().getFieldData().getFields().get("field"), greaterThan(0l));
assertThat(nodesStats.getNodes()[0].getIndices().getFieldData().getFields().get("field"), lessThan(nodesStats.getNodes()[0].getIndices().getFieldData().getMemorySizeInBytes()));
indicesStats = client.admin().indices().prepareStats("test").clear().setFieldData(true).setFieldDataFields("*").execute().actionGet();
assertThat(indicesStats.getTotal().getFieldData().getMemorySizeInBytes(), greaterThan(0l));
assertThat(indicesStats.getTotal().getFieldData().getFields().get("field"), greaterThan(0l));
assertThat(indicesStats.getTotal().getFieldData().getFields().get("field"), lessThan(indicesStats.getTotal().getFieldData().getMemorySizeInBytes()));
client.admin().indices().prepareClearCache().setFieldDataCache(true).execute().actionGet();
nodesStats = client.admin().cluster().prepareNodesStats().setIndices(true).execute().actionGet();
assertThat(nodesStats.getNodes()[0].getIndices().getFieldData().getMemorySizeInBytes(), equalTo(0l));
indicesStats = client.admin().indices().prepareStats("test").clear().setFieldData(true).execute().actionGet();
assertThat(indicesStats.getTotal().getFieldData().getMemorySizeInBytes(), equalTo(0l));
}
@Test

View File

@ -111,4 +111,13 @@ public class PathTrieTests {
assertThat(trie.retrieve("/b", params), equalTo("test2"));
assertThat(trie.retrieve("/b/a", params), equalTo("test4"));
}
@Test
public void testEndWithNamedWildcardAndLookupWithWildcard() {
PathTrie<String> trie = new PathTrie<String>();
trie.insert("x/{test}", "test1");
Map<String, String> params = newHashMap();
assertThat(trie.retrieve("/x/*", params), equalTo("test1"));
assertThat(params.get("test"), equalTo("*"));
}
}