Skip to content

Commit e90ff65

Browse files
committed
Pre-calculate shard & snapshot state summaries in cluster state
1 parent ba62ff6 commit e90ff65

File tree

2 files changed

+58
-20
lines changed

2 files changed

+58
-20
lines changed

server/src/main/java/org/elasticsearch/cluster/SnapshotsInProgress.java

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949

5050
import java.io.IOException;
5151
import java.util.ArrayList;
52+
import java.util.Arrays;
5253
import java.util.Collection;
5354
import java.util.Collections;
5455
import java.util.HashMap;
@@ -58,6 +59,7 @@
5859
import java.util.Map;
5960
import java.util.Objects;
6061
import java.util.Set;
62+
import java.util.stream.Collectors;
6163
import java.util.stream.Stream;
6264

6365
import static org.elasticsearch.repositories.ProjectRepo.PROJECT_REPO_SERIALIZER;
@@ -178,6 +180,28 @@ public List<Entry> forRepo(ProjectId projectId, String repository) {
178180
return forRepo(new ProjectRepo(projectId, repository));
179181
}
180182

183+
/**
184+
* Get a summary how many shards are in each {@link ShardState} for this repository
185+
*
186+
* @param projectId The project ID
187+
* @param repository The repository name
188+
* @return A map of each shard state to the count of shards in that state for all in-progress snapshots
189+
*/
190+
public Map<ShardState, Integer> shardStateSummaryForRepository(ProjectId projectId, String repository) {
191+
return entries.getOrDefault(new ProjectRepo(projectId, repository), ByRepo.EMPTY).shardStateSummary;
192+
}
193+
194+
/**
195+
* Get a summary how many snapshots are in each {@link State} for this repository
196+
*
197+
* @param projectId The project ID
198+
* @param repository The repository name
199+
* @return A map of each snapshot state to the count of in-progress snapshots in that state
200+
*/
201+
public Map<State, Integer> snapshotStateSummaryForRepository(ProjectId projectId, String repository) {
202+
return entries.getOrDefault(new ProjectRepo(projectId, repository), ByRepo.EMPTY).snapshotStateSummary;
203+
}
204+
181205
/**
182206
* Returns the list of snapshots in the specified repository.
183207
*/
@@ -1875,7 +1899,9 @@ public void writeTo(StreamOutput out) throws IOException {
18751899
*
18761900
* @param entries all snapshots executing for a single repository
18771901
*/
1878-
private record ByRepo(List<Entry> entries) implements Diffable<ByRepo> {
1902+
private record ByRepo(List<Entry> entries, Map<State, Integer> snapshotStateSummary, Map<ShardState, Integer> shardStateSummary)
1903+
implements
1904+
Diffable<ByRepo> {
18791905

18801906
static final ByRepo EMPTY = new ByRepo(List.of());
18811907
private static final DiffableUtils.NonDiffableValueSerializer<String, Integer> INT_DIFF_VALUE_SERIALIZER =
@@ -1892,7 +1918,27 @@ public Integer read(StreamInput in, String key) throws IOException {
18921918
};
18931919

18941920
private ByRepo(List<Entry> entries) {
1895-
this.entries = List.copyOf(entries);
1921+
this(List.copyOf(entries), calculateStateSummaries(entries));
1922+
}
1923+
1924+
private ByRepo(List<Entry> entries, Tuple<Map<State, Integer>, Map<ShardState, Integer>> stateSummaries) {
1925+
this(entries, stateSummaries.v1(), stateSummaries.v2());
1926+
}
1927+
1928+
private static Tuple<Map<State, Integer>, Map<ShardState, Integer>> calculateStateSummaries(List<Entry> entries) {
1929+
final int[] snapshotCounts = new int[State.values().length];
1930+
final int[] shardCounts = new int[ShardState.values().length];
1931+
for (Entry entry : entries) {
1932+
snapshotCounts[entry.state().ordinal()]++;
1933+
for (ShardSnapshotStatus shardSnapshotStatus : entry.shards().values()) {
1934+
shardCounts[shardSnapshotStatus.state().ordinal()]++;
1935+
}
1936+
}
1937+
final Map<State, Integer> snapshotStates = Arrays.stream(State.values())
1938+
.collect(Collectors.toUnmodifiableMap(state -> state, state -> snapshotCounts[state.ordinal()]));
1939+
final Map<ShardState, Integer> shardStates = Arrays.stream(ShardState.values())
1940+
.collect(Collectors.toUnmodifiableMap(shardState -> shardState, state -> shardCounts[state.ordinal()]));
1941+
return Tuple.tuple(snapshotStates, shardStates);
18961942
}
18971943

18981944
@Override

server/src/main/java/org/elasticsearch/snapshots/SnapshotsService.java

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,6 @@
99

1010
package org.elasticsearch.snapshots;
1111

12-
import com.carrotsearch.hppc.ObjectIntHashMap;
13-
import com.carrotsearch.hppc.ObjectIntMap;
14-
import com.carrotsearch.hppc.cursors.ObjectIntCursor;
15-
1612
import org.apache.logging.log4j.Level;
1713
import org.apache.logging.log4j.LogManager;
1814
import org.apache.logging.log4j.Logger;
@@ -4496,25 +4492,21 @@ private Collection<LongWithAttributes> getShardsByState() {
44964492
}
44974493
final SnapshotsInProgress snapshotsInProgress = SnapshotsInProgress.get(currentState);
44984494
final List<LongWithAttributes> shardsByState = new ArrayList<>();
4499-
final ObjectIntMap<ShardState> shardCounts = new ObjectIntHashMap<>(TRACKED_SHARD_STATES.size());
4495+
45004496
currentState.metadata().projects().forEach((projectId, project) -> {
45014497
final RepositoriesMetadata repositoriesMetadata = RepositoriesMetadata.get(project);
45024498
if (repositoriesMetadata != null) {
45034499
for (RepositoryMetadata repository : repositoriesMetadata.repositories()) {
4504-
TRACKED_SHARD_STATES.forEach(shardState -> shardCounts.put(shardState, 0));
4505-
for (SnapshotsInProgress.Entry snapshot : snapshotsInProgress.forRepo(projectId, repository.name())) {
4506-
for (ShardSnapshotStatus shardSnapshotStatus : snapshot.shards().values()) {
4507-
if (shardCounts.containsKey(shardSnapshotStatus.state())) {
4508-
shardCounts.addTo(shardSnapshotStatus.state(), 1);
4509-
}
4510-
}
4511-
}
4500+
final Map<ShardState, Integer> shardStateSummary = snapshotsInProgress.shardStateSummaryForRepository(
4501+
projectId,
4502+
repository.name()
4503+
);
45124504
final Map<String, Object> attributesMap = SnapshotMetrics.createAttributesMap(projectId, repository);
4513-
for (ObjectIntCursor<ShardState> entry : shardCounts) {
4514-
shardsByState.add(
4515-
new LongWithAttributes(entry.value, Maps.copyMapWithAddedEntry(attributesMap, "state", entry.key.name()))
4516-
);
4517-
}
4505+
shardStateSummary.forEach(
4506+
(shardState, count) -> shardsByState.add(
4507+
new LongWithAttributes(count, Maps.copyMapWithAddedEntry(attributesMap, "state", shardState.name()))
4508+
)
4509+
);
45184510
}
45194511
}
45204512
});

0 commit comments

Comments
 (0)