Skip to content

Commit d28fbc3

Browse files
Optimizing get indices to segments map calculations for IndicesSegmen… (opensearch-project#14717)
* Optimizing get indices to segments map calculations for IndicesSegmentResponse class Signed-off-by: Harsh Garg <gkharsh@amazon.com>
1 parent 23f5c2f commit d28fbc3

File tree

2 files changed

+69
-14
lines changed

2 files changed

+69
-14
lines changed

server/src/main/java/org/opensearch/action/admin/indices/segments/IndicesSegmentResponse.java

+16-14
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,12 @@
4545
import org.opensearch.index.engine.Segment;
4646

4747
import java.io.IOException;
48-
import java.util.ArrayList;
48+
import java.util.Arrays;
49+
import java.util.Comparator;
4950
import java.util.HashMap;
50-
import java.util.HashSet;
5151
import java.util.List;
5252
import java.util.Locale;
5353
import java.util.Map;
54-
import java.util.Set;
5554

5655
/**
5756
* Transport response for retrieving indices segment information
@@ -86,21 +85,24 @@ public Map<String, IndexSegments> getIndices() {
8685
return indicesSegments;
8786
}
8887
Map<String, IndexSegments> indicesSegments = new HashMap<>();
89-
90-
Set<String> indices = new HashSet<>();
91-
for (ShardSegments shard : shards) {
92-
indices.add(shard.getShardRouting().getIndexName());
88+
if (shards.length == 0) {
89+
this.indicesSegments = indicesSegments;
90+
return indicesSegments;
9391
}
9492

95-
for (String indexName : indices) {
96-
List<ShardSegments> shards = new ArrayList<>();
97-
for (ShardSegments shard : this.shards) {
98-
if (shard.getShardRouting().getIndexName().equals(indexName)) {
99-
shards.add(shard);
100-
}
93+
Arrays.sort(shards, Comparator.comparing(shardSegment -> shardSegment.getShardRouting().getIndexName()));
94+
int startIndexPos = 0;
95+
String startIndexName = shards[startIndexPos].getShardRouting().getIndexName();
96+
for (int i = 0; i < shards.length; i++) {
97+
if (!shards[i].getShardRouting().getIndexName().equals(startIndexName)) {
98+
indicesSegments.put(startIndexName, new IndexSegments(startIndexName, Arrays.copyOfRange(shards, startIndexPos, i)));
99+
startIndexPos = i;
100+
startIndexName = shards[startIndexPos].getShardRouting().getIndexName();
101101
}
102-
indicesSegments.put(indexName, new IndexSegments(indexName, shards.toArray(new ShardSegments[0])));
103102
}
103+
// Add the last shardSegment from shards list which would have got missed in the loop above
104+
indicesSegments.put(startIndexName, new IndexSegments(startIndexName, Arrays.copyOfRange(shards, startIndexPos, shards.length)));
105+
104106
this.indicesSegments = indicesSegments;
105107
return indicesSegments;
106108
}

server/src/test/java/org/opensearch/action/admin/indices/segments/IndicesSegmentResponseTests.java

+53
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@
4242
import org.opensearch.index.engine.Segment;
4343
import org.opensearch.test.OpenSearchTestCase;
4444

45+
import java.util.ArrayList;
4546
import java.util.Collections;
47+
import java.util.List;
48+
import java.util.Map;
4649

4750
import static org.opensearch.common.xcontent.XContentFactory.jsonBuilder;
4851

@@ -68,4 +71,54 @@ public void testToXContentSerialiationWithSortedFields() throws Exception {
6871
response.toXContent(builder, ToXContent.EMPTY_PARAMS);
6972
}
7073
}
74+
75+
public void testGetIndices() {
76+
final int totalIndices = 5;
77+
final int shardsPerIndex = 3;
78+
final int segmentsPerShard = 2;
79+
// Preparing a ShardSegments list, which will have (totalIndices * shardsPerIndex) shardSegments.
80+
// Indices will be named -> foo1, foo2, ..., foo{totalIndices}
81+
List<ShardSegments> shardSegmentsList = new ArrayList<>();
82+
for (int indexName = 0; indexName < totalIndices; indexName++) {
83+
for (int shardId = 0; shardId < shardsPerIndex; shardId++) {
84+
ShardRouting shardRouting = TestShardRouting.newShardRouting(
85+
"foo" + indexName,
86+
shardId,
87+
"node_id",
88+
true,
89+
ShardRoutingState.STARTED
90+
);
91+
List<Segment> segmentList = new ArrayList<>();
92+
for (int segmentNum = 0; segmentNum < segmentsPerShard; segmentNum++) {
93+
segmentList.add(new Segment("foo" + indexName + shardId + segmentNum));
94+
}
95+
shardSegmentsList.add(new ShardSegments(shardRouting, segmentList));
96+
}
97+
}
98+
Collections.shuffle(shardSegmentsList, random());
99+
100+
// Prepare the IndicesSegmentResponse object and get the indicesSegments map
101+
IndicesSegmentResponse response = new IndicesSegmentResponse(
102+
shardSegmentsList.toArray(new ShardSegments[0]),
103+
totalIndices * shardsPerIndex,
104+
totalIndices * shardsPerIndex,
105+
0,
106+
Collections.emptyList()
107+
);
108+
Map<String, IndexSegments> indicesSegments = response.getIndices();
109+
110+
assertEquals(totalIndices, indicesSegments.size());
111+
for (Map.Entry<String, IndexSegments> indexSegmentEntry : indicesSegments.entrySet()) {
112+
assertEquals(shardsPerIndex, indexSegmentEntry.getValue().getShards().size());
113+
for (IndexShardSegments indexShardSegment : indexSegmentEntry.getValue().getShards().values()) {
114+
for (ShardSegments shardSegment : indexShardSegment.getShards()) {
115+
assertEquals(segmentsPerShard, shardSegment.getSegments().size());
116+
for (int i = 0; i < segmentsPerShard; i++) {
117+
String segmentName = indexSegmentEntry.getKey() + shardSegment.getShardRouting().getId() + i;
118+
assertEquals(segmentName, shardSegment.getSegments().get(i).getName());
119+
}
120+
}
121+
}
122+
}
123+
}
71124
}

0 commit comments

Comments
 (0)