Skip to content

Commit d5492e1

Browse files
authored
XContent parsing for DocStats and ShardFieldStats (elastic#135016)
Relates ES-11204
1 parent 188f258 commit d5492e1

File tree

5 files changed

+215
-3
lines changed

5 files changed

+215
-3
lines changed

server/src/main/java/org/elasticsearch/index/shard/DocsStats.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,40 @@
1414
import org.elasticsearch.common.io.stream.Writeable;
1515
import org.elasticsearch.common.unit.ByteSizeValue;
1616
import org.elasticsearch.index.store.StoreStats;
17+
import org.elasticsearch.xcontent.ConstructingObjectParser;
18+
import org.elasticsearch.xcontent.ParseField;
1719
import org.elasticsearch.xcontent.ToXContentFragment;
1820
import org.elasticsearch.xcontent.XContentBuilder;
1921

2022
import java.io.IOException;
2123
import java.util.Objects;
2224

25+
import static org.elasticsearch.xcontent.ConstructingObjectParser.constructorArg;
26+
2327
public class DocsStats implements Writeable, ToXContentFragment {
2428

29+
public static final ConstructingObjectParser<DocsStats, Void> PARSER = new ConstructingObjectParser<>(
30+
"doc_stats",
31+
true,
32+
args -> (DocsStats) args[0]
33+
);
34+
35+
protected static final ConstructingObjectParser<DocsStats, Void> DOC_STATS_PARSER = new ConstructingObjectParser<>(
36+
"doc_stats_fields",
37+
true,
38+
args -> new DocsStats((long) args[0], (long) args[1], (long) args[2])
39+
);
40+
41+
static {
42+
PARSER.declareObject(constructorArg(), DOC_STATS_PARSER, new ParseField(Fields.DOCS));
43+
}
44+
45+
static {
46+
DOC_STATS_PARSER.declareLong(constructorArg(), new ParseField(Fields.COUNT));
47+
DOC_STATS_PARSER.declareLong(constructorArg(), new ParseField(Fields.DELETED));
48+
DOC_STATS_PARSER.declareLong(constructorArg(), new ParseField(Fields.TOTAL_SIZE_IN_BYTES));
49+
}
50+
2551
private long count = 0;
2652
private long deleted = 0;
2753
private long totalSizeInBytes = 0;
@@ -108,4 +134,9 @@ static final class Fields {
108134
static final String TOTAL_SIZE_IN_BYTES = "total_size_in_bytes";
109135
static final String TOTAL_SIZE = "total_size";
110136
}
137+
138+
@Override
139+
public String toString() {
140+
return "DocStats{" + "count=" + count + ", deleted=" + deleted + ", totalSizeInBytes=" + totalSizeInBytes + '}';
141+
}
111142
}

server/src/main/java/org/elasticsearch/index/shard/ShardFieldStats.java

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@
1111

1212
import org.apache.lucene.util.FixedBitSet;
1313
import org.apache.lucene.util.RamUsageEstimator;
14+
import org.elasticsearch.common.unit.ByteSizeValue;
15+
import org.elasticsearch.xcontent.ConstructingObjectParser;
16+
import org.elasticsearch.xcontent.ParseField;
17+
import org.elasticsearch.xcontent.ToXContent;
18+
import org.elasticsearch.xcontent.ToXContentFragment;
19+
import org.elasticsearch.xcontent.XContentBuilder;
20+
21+
import java.io.IOException;
22+
23+
import static org.elasticsearch.xcontent.ConstructingObjectParser.constructorArg;
1424

1525
/**
1626
* A per shard stats including the number of segments and total fields across those segments.
@@ -23,8 +33,61 @@
2333
* @param postingsInMemoryBytes the total bytes in memory used for postings across all fields
2434
* @param liveDocsBytes the total bytes in memory used for live docs
2535
*/
26-
public record ShardFieldStats(int numSegments, int totalFields, long fieldUsages, long postingsInMemoryBytes, long liveDocsBytes) {
36+
public record ShardFieldStats(int numSegments, int totalFields, long fieldUsages, long postingsInMemoryBytes, long liveDocsBytes)
37+
implements
38+
ToXContentFragment {
2739

2840
public static final long FIXED_BITSET_BASE_RAM_BYTES_USED = RamUsageEstimator.shallowSizeOfInstance(FixedBitSet.class);
2941

42+
static final class Fields {
43+
static final String SHARD_FIELD_STATS = "shard_field_stats";
44+
static final String NUM_SEGMENTS = "num_segments";
45+
static final String TOTAL_FIELDS = "total_fields";
46+
static final String FIELD_USAGES = "field_usages";
47+
static final String POSTINGS_IN_MEMORY_BYTES = "postings_in_memory_bytes";
48+
static final String POSTINGS_IN_MEMORY = "postings_in_memory";
49+
static final String LIVE_DOCS_BYTES = "live_docs_bytes";
50+
static final String LIVE_DOCS = "live_docs";
51+
}
52+
53+
public static final ConstructingObjectParser<ShardFieldStats, Void> PARSER = new ConstructingObjectParser<>(
54+
"shard_field_stats",
55+
true,
56+
args -> (ShardFieldStats) args[0]
57+
);
58+
59+
protected static final ConstructingObjectParser<ShardFieldStats, Void> SHARD_FIELD_STATS_PARSER = new ConstructingObjectParser<>(
60+
"shard_field_stats_fields",
61+
true,
62+
args -> new ShardFieldStats((int) args[0], (int) args[1], (long) args[2], (long) args[3], (long) args[4])
63+
);
64+
65+
static {
66+
PARSER.declareObject(constructorArg(), SHARD_FIELD_STATS_PARSER, new ParseField(Fields.SHARD_FIELD_STATS));
67+
}
68+
69+
static {
70+
SHARD_FIELD_STATS_PARSER.declareInt(constructorArg(), new ParseField(Fields.NUM_SEGMENTS));
71+
SHARD_FIELD_STATS_PARSER.declareInt(constructorArg(), new ParseField(Fields.TOTAL_FIELDS));
72+
SHARD_FIELD_STATS_PARSER.declareLong(constructorArg(), new ParseField(Fields.FIELD_USAGES));
73+
SHARD_FIELD_STATS_PARSER.declareLong(constructorArg(), new ParseField(Fields.POSTINGS_IN_MEMORY_BYTES));
74+
SHARD_FIELD_STATS_PARSER.declareLong(constructorArg(), new ParseField(Fields.LIVE_DOCS_BYTES));
75+
}
76+
77+
@Override
78+
public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException {
79+
builder.startObject(Fields.SHARD_FIELD_STATS);
80+
builder.field(Fields.NUM_SEGMENTS, numSegments);
81+
builder.field(Fields.TOTAL_FIELDS, totalFields);
82+
builder.field(Fields.FIELD_USAGES, fieldUsages);
83+
builder.humanReadableField(
84+
Fields.POSTINGS_IN_MEMORY_BYTES,
85+
Fields.POSTINGS_IN_MEMORY,
86+
ByteSizeValue.ofBytes(postingsInMemoryBytes)
87+
);
88+
builder.humanReadableField(Fields.LIVE_DOCS_BYTES, Fields.LIVE_DOCS, ByteSizeValue.ofBytes(liveDocsBytes));
89+
builder.endObject();
90+
return builder;
91+
}
92+
3093
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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.shard;
11+
12+
import org.elasticsearch.common.io.stream.Writeable;
13+
import org.elasticsearch.test.AbstractXContentSerializingTestCase;
14+
import org.elasticsearch.test.ESTestCase;
15+
import org.elasticsearch.xcontent.XContentParser;
16+
17+
import java.io.IOException;
18+
19+
public class DocsStatsSerializationTests extends AbstractXContentSerializingTestCase<DocsStats> {
20+
@Override
21+
protected DocsStats doParseInstance(XContentParser parser) throws IOException {
22+
return DocsStats.PARSER.parse(parser, null);
23+
}
24+
25+
@Override
26+
protected Writeable.Reader<DocsStats> instanceReader() {
27+
return DocsStats::new;
28+
}
29+
30+
@Override
31+
protected DocsStats createTestInstance() {
32+
return new DocsStats(randomNonNegativeLong(), randomNonNegativeLong(), randomNonNegativeLong());
33+
}
34+
35+
@Override
36+
protected DocsStats mutateInstance(DocsStats instance) {
37+
switch (between(0, 2)) {
38+
case 0:
39+
return new DocsStats(
40+
randomValueOtherThan(instance.getCount(), ESTestCase::randomNonNegativeLong),
41+
instance.getDeleted(),
42+
instance.getTotalSizeInBytes()
43+
);
44+
case 1:
45+
return new DocsStats(
46+
instance.getCount(),
47+
randomValueOtherThan(instance.getDeleted(), ESTestCase::randomNonNegativeLong),
48+
instance.getTotalSizeInBytes()
49+
);
50+
case 2:
51+
return new DocsStats(
52+
instance.getCount(),
53+
instance.getDeleted(),
54+
randomValueOtherThan(instance.getTotalSizeInBytes(), ESTestCase::randomNonNegativeLong)
55+
);
56+
default:
57+
throw new AssertionError("failure, illegal switch case");
58+
}
59+
}
60+
61+
}

server/src/test/java/org/elasticsearch/index/shard/DocsStatsTests.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,14 @@
1212
import org.elasticsearch.common.bytes.BytesReference;
1313
import org.elasticsearch.common.io.stream.BytesStreamOutput;
1414
import org.elasticsearch.common.io.stream.StreamInput;
15-
import org.elasticsearch.test.ESTestCase;
15+
import org.elasticsearch.test.AbstractXContentTestCase;
16+
import org.elasticsearch.xcontent.XContentParser;
17+
18+
import java.io.IOException;
1619

1720
import static org.hamcrest.Matchers.equalTo;
1821

19-
public class DocsStatsTests extends ESTestCase {
22+
public class DocsStatsTests extends AbstractXContentTestCase<DocsStats> {
2023

2124
public void testUninitialisedShards() {
2225
DocsStats stats = new DocsStats(0, 0, -1);
@@ -44,4 +47,19 @@ public void testSerialize() throws Exception {
4447
}
4548
}
4649
}
50+
51+
@Override
52+
protected DocsStats createTestInstance() {
53+
return new DocsStats(randomNonNegativeLong(), randomNonNegativeLong(), randomNonNegativeLong());
54+
}
55+
56+
@Override
57+
protected DocsStats doParseInstance(XContentParser parser) throws IOException {
58+
return DocsStats.PARSER.parse(parser, null);
59+
}
60+
61+
@Override
62+
protected boolean supportsUnknownFields() {
63+
return true;
64+
}
4765
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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.shard;
11+
12+
import org.elasticsearch.test.AbstractXContentTestCase;
13+
import org.elasticsearch.xcontent.XContentParser;
14+
15+
import java.io.IOException;
16+
17+
public class ShardFieldStatsTests extends AbstractXContentTestCase<ShardFieldStats> {
18+
19+
@Override
20+
protected ShardFieldStats createTestInstance() {
21+
return new ShardFieldStats(
22+
randomNonNegativeInt(),
23+
randomNonNegativeInt(),
24+
randomNonNegativeLong(),
25+
randomNonNegativeLong(),
26+
randomNonNegativeLong()
27+
);
28+
}
29+
30+
@Override
31+
protected ShardFieldStats doParseInstance(XContentParser parser) throws IOException {
32+
return ShardFieldStats.PARSER.parse(parser, null);
33+
}
34+
35+
@Override
36+
protected boolean supportsUnknownFields() {
37+
return true;
38+
}
39+
}

0 commit comments

Comments
 (0)