36
36
import java .util .Collection ;
37
37
import java .util .Collections ;
38
38
import java .util .HashMap ;
39
- import java .util .LinkedHashSet ;
39
+ import java .util .HashSet ;
40
40
import java .util .List ;
41
41
import java .util .Map ;
42
42
import java .util .Objects ;
43
- import java .util .Set ;
44
43
import java .util .function .Function ;
45
44
import java .util .stream .Collectors ;
46
45
@@ -90,7 +89,7 @@ public final class RepositoryData {
90
89
/**
91
90
* The snapshots that each index belongs to.
92
91
*/
93
- private final Map <IndexId , Set <SnapshotId >> indexSnapshots ;
92
+ private final Map <IndexId , List <SnapshotId >> indexSnapshots ;
94
93
95
94
private final Map <String , Version > snapshotVersions ;
96
95
@@ -100,7 +99,7 @@ public final class RepositoryData {
100
99
private final ShardGenerations shardGenerations ;
101
100
102
101
public RepositoryData (long genId , Map <String , SnapshotId > snapshotIds , Map <String , SnapshotState > snapshotStates ,
103
- Map <String , Version > snapshotVersions , Map <IndexId , Set <SnapshotId >> indexSnapshots ,
102
+ Map <String , Version > snapshotVersions , Map <IndexId , List <SnapshotId >> indexSnapshots ,
104
103
ShardGenerations shardGenerations ) {
105
104
this .genId = genId ;
106
105
this .snapshotIds = Collections .unmodifiableMap (snapshotIds );
@@ -112,6 +111,8 @@ public RepositoryData(long genId, Map<String, SnapshotId> snapshotIds, Map<Strin
112
111
this .snapshotVersions = snapshotVersions ;
113
112
assert indices .values ().containsAll (shardGenerations .indices ()) : "ShardGenerations contained indices "
114
113
+ shardGenerations .indices () + " but snapshots only reference indices " + indices .values ();
114
+ assert indexSnapshots .values ().stream ().noneMatch (snapshotIdList -> new HashSet <>(snapshotIdList ).size () != snapshotIdList .size ()) :
115
+ "Found duplicate snapshot ids per index in [" + indexSnapshots + "]" ;
115
116
}
116
117
117
118
protected RepositoryData copy () {
@@ -213,9 +214,17 @@ public RepositoryData addSnapshot(final SnapshotId snapshotId,
213
214
newSnapshotStates .put (snapshotId .getUUID (), snapshotState );
214
215
Map <String , Version > newSnapshotVersions = new HashMap <>(snapshotVersions );
215
216
newSnapshotVersions .put (snapshotId .getUUID (), version );
216
- Map <IndexId , Set <SnapshotId >> allIndexSnapshots = new HashMap <>(indexSnapshots );
217
+ Map <IndexId , List <SnapshotId >> allIndexSnapshots = new HashMap <>(indexSnapshots );
217
218
for (final IndexId indexId : shardGenerations .indices ()) {
218
- allIndexSnapshots .computeIfAbsent (indexId , k -> new LinkedHashSet <>()).add (snapshotId );
219
+ final List <SnapshotId > snapshotIds = allIndexSnapshots .get (indexId );
220
+ if (snapshotIds == null ) {
221
+ allIndexSnapshots .put (indexId , Collections .singletonList (snapshotId ));
222
+ } else {
223
+ final List <SnapshotId > copy = new ArrayList <>(snapshotIds .size () + 1 );
224
+ copy .addAll (snapshotIds );
225
+ copy .add (snapshotId );
226
+ allIndexSnapshots .put (indexId , Collections .unmodifiableList (copy ));
227
+ }
219
228
}
220
229
return new RepositoryData (genId , snapshots , newSnapshotStates , newSnapshotVersions , allIndexSnapshots ,
221
230
ShardGenerations .builder ().putAll (this .shardGenerations ).putAll (shardGenerations ).build ());
@@ -253,23 +262,25 @@ public RepositoryData removeSnapshot(final SnapshotId snapshotId, final ShardGen
253
262
newSnapshotStates .remove (snapshotId .getUUID ());
254
263
final Map <String , Version > newSnapshotVersions = new HashMap <>(snapshotVersions );
255
264
newSnapshotVersions .remove (snapshotId .getUUID ());
256
- Map <IndexId , Set <SnapshotId >> indexSnapshots = new HashMap <>();
265
+ Map <IndexId , List <SnapshotId >> indexSnapshots = new HashMap <>();
257
266
for (final IndexId indexId : indices .values ()) {
258
- Set <SnapshotId > set ;
259
- Set <SnapshotId > snapshotIds = this .indexSnapshots .get (indexId );
267
+ List <SnapshotId > remaining ;
268
+ List <SnapshotId > snapshotIds = this .indexSnapshots .get (indexId );
260
269
assert snapshotIds != null ;
261
- if (snapshotIds .contains (snapshotId )) {
270
+ final int listIndex = snapshotIds .indexOf (snapshotId );
271
+ if (listIndex > -1 ) {
262
272
if (snapshotIds .size () == 1 ) {
263
273
// removing the snapshot will mean no more snapshots
264
274
// have this index, so just skip over it
265
275
continue ;
266
276
}
267
- set = new LinkedHashSet <>(snapshotIds );
268
- set .remove (snapshotId );
277
+ remaining = new ArrayList <>(snapshotIds );
278
+ remaining .remove (listIndex );
279
+ remaining = Collections .unmodifiableList (remaining );
269
280
} else {
270
- set = snapshotIds ;
281
+ remaining = snapshotIds ;
271
282
}
272
- indexSnapshots .put (indexId , set );
283
+ indexSnapshots .put (indexId , remaining );
273
284
}
274
285
275
286
return new RepositoryData (genId , newSnapshotIds , newSnapshotStates , newSnapshotVersions , indexSnapshots ,
@@ -281,8 +292,8 @@ public RepositoryData removeSnapshot(final SnapshotId snapshotId, final ShardGen
281
292
/**
282
293
* Returns an immutable collection of the snapshot ids for the snapshots that contain the given index.
283
294
*/
284
- public Set <SnapshotId > getSnapshots (final IndexId indexId ) {
285
- Set <SnapshotId > snapshotIds = indexSnapshots .get (indexId );
295
+ public List <SnapshotId > getSnapshots (final IndexId indexId ) {
296
+ List <SnapshotId > snapshotIds = indexSnapshots .get (indexId );
286
297
if (snapshotIds == null ) {
287
298
throw new IllegalArgumentException ("unknown snapshot index " + indexId );
288
299
}
@@ -384,7 +395,7 @@ public XContentBuilder snapshotsToXContent(final XContentBuilder builder, final
384
395
builder .startObject (indexId .getName ());
385
396
builder .field (INDEX_ID , indexId .getId ());
386
397
builder .startArray (SNAPSHOTS );
387
- Set <SnapshotId > snapshotIds = indexSnapshots .get (indexId );
398
+ List <SnapshotId > snapshotIds = indexSnapshots .get (indexId );
388
399
assert snapshotIds != null ;
389
400
for (final SnapshotId snapshotId : snapshotIds ) {
390
401
builder .value (snapshotId .getUUID ());
@@ -415,7 +426,7 @@ public static RepositoryData snapshotsFromXContent(final XContentParser parser,
415
426
final Map <String , SnapshotId > snapshots = new HashMap <>();
416
427
final Map <String , SnapshotState > snapshotStates = new HashMap <>();
417
428
final Map <String , Version > snapshotVersions = new HashMap <>();
418
- final Map <IndexId , Set <SnapshotId >> indexSnapshots = new HashMap <>();
429
+ final Map <IndexId , List <SnapshotId >> indexSnapshots = new HashMap <>();
419
430
final ShardGenerations .Builder shardGenerations = ShardGenerations .builder ();
420
431
421
432
if (parser .nextToken () == XContentParser .Token .START_OBJECT ) {
@@ -459,7 +470,7 @@ public static RepositoryData snapshotsFromXContent(final XContentParser parser,
459
470
}
460
471
while (parser .nextToken () != XContentParser .Token .END_OBJECT ) {
461
472
final String indexName = parser .currentName ();
462
- final Set <SnapshotId > snapshotIds = new LinkedHashSet <>();
473
+ final List <SnapshotId > snapshotIds = new ArrayList <>();
463
474
final List <String > gens = new ArrayList <>();
464
475
465
476
IndexId indexId = null ;
@@ -513,7 +524,7 @@ public static RepositoryData snapshotsFromXContent(final XContentParser parser,
513
524
}
514
525
}
515
526
assert indexId != null ;
516
- indexSnapshots .put (indexId , snapshotIds );
527
+ indexSnapshots .put (indexId , Collections . unmodifiableList ( snapshotIds ) );
517
528
for (int i = 0 ; i < gens .size (); i ++) {
518
529
shardGenerations .put (indexId , i , gens .get (i ));
519
530
}
0 commit comments