فهرست منبع

Make ShardGenerations Immutable (#73452)

This object should be completely immutable. Also added a useful
assertion that makes sure we don't accidentally overwrite a valid
generation with `null` when dealing dealing failed status updates.
Armin Braun 4 سال پیش
والد
کامیت
b8fb1eb33d
1فایلهای تغییر یافته به همراه8 افزوده شده و 7 حذف شده
  1. 8 7
      server/src/main/java/org/elasticsearch/repositories/ShardGenerations.java

+ 8 - 7
server/src/main/java/org/elasticsearch/repositories/ShardGenerations.java

@@ -42,7 +42,7 @@ public final class ShardGenerations {
     private final Map<IndexId, List<String>> shardGenerations;
 
     private ShardGenerations(Map<IndexId, List<String>> shardGenerations) {
-        this.shardGenerations = shardGenerations;
+        this.shardGenerations = Map.copyOf(shardGenerations);
     }
 
     private static final Pattern IS_NUMBER = Pattern.compile("^\\d+$");
@@ -76,7 +76,7 @@ public final class ShardGenerations {
      * @return indices for which shard generations are tracked
      */
     public Collection<IndexId> indices() {
-        return Collections.unmodifiableSet(shardGenerations.keySet());
+        return shardGenerations.keySet();
     }
 
     /**
@@ -135,8 +135,7 @@ public final class ShardGenerations {
     }
 
     public List<String> getGens(IndexId indexId) {
-        final List<String> existing = shardGenerations.get(indexId);
-        return existing == null ? Collections.emptyList() : Collections.unmodifiableList(existing);
+        return shardGenerations.getOrDefault(indexId, Collections.emptyList());
     }
 
     @Override
@@ -200,7 +199,7 @@ public final class ShardGenerations {
                 for (int i = 0; i < gens.size(); i++) {
                     final String gen = gens.get(i);
                     if (gen != null) {
-                        put(indexId, i, gens.get(i));
+                        put(indexId, i, gen);
                     }
                 }
             });
@@ -208,7 +207,9 @@ public final class ShardGenerations {
         }
 
         public Builder put(IndexId indexId, int shardId, String generation) {
-            generations.computeIfAbsent(indexId, i -> new HashMap<>()).put(shardId, generation);
+            String existingGeneration = generations.computeIfAbsent(indexId, i -> new HashMap<>()).put(shardId, generation);
+            assert generation != null || existingGeneration == null :
+                    "must not overwrite existing generation with null generation [" + existingGeneration + "]";
             return this;
         }
 
@@ -223,7 +224,7 @@ public final class ShardGenerations {
                     // a map entry.
                     final String[] gens = new String[size];
                     entry.getValue().forEach((shardId, generation) -> gens[shardId] = generation);
-                    return Arrays.asList(gens);
+                    return Collections.unmodifiableList(Arrays.asList(gens));
                 }
             )));
         }