Skip to content

Commit 0ba208c

Browse files
authored
Simplify Store$MetadataSnapshot and friends (#84357)
`TransportNodesListShardStoreMetadata$StoreFilesMetadata` and `Store$MetadataSnapshot` are both morally-speaking records, and `LoadedMetadata` is really the same as `MetadataSnapshot`. This commit turns them into real records, gets rid of the unnecessary extra class, and renames some of the accessors. Spotted while working on #84034
1 parent 0116cce commit 0ba208c

File tree

12 files changed

+106
-141
lines changed

12 files changed

+106
-141
lines changed

server/src/internalClusterTest/java/org/elasticsearch/indices/recovery/IndexRecoveryIT.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,10 +1072,10 @@ public void testRecoverLocallyUpToGlobalCheckpoint() throws Exception {
10721072
logger.info(
10731073
"--> start recovery request: starting seq_no {}, commit {}",
10741074
startRecoveryRequest.startingSeqNo(),
1075-
startRecoveryRequest.metadataSnapshot().getCommitUserData()
1075+
startRecoveryRequest.metadataSnapshot().commitUserData()
10761076
);
10771077
SequenceNumbers.CommitInfo commitInfoAfterLocalRecovery = SequenceNumbers.loadSeqNoInfoFromLuceneCommit(
1078-
startRecoveryRequest.metadataSnapshot().getCommitUserData().entrySet()
1078+
startRecoveryRequest.metadataSnapshot().commitUserData().entrySet()
10791079
);
10801080
assertThat(commitInfoAfterLocalRecovery.localCheckpoint, equalTo(lastSyncedGlobalCheckpoint));
10811081
assertThat(commitInfoAfterLocalRecovery.maxSeqNo, equalTo(lastSyncedGlobalCheckpoint));

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2913,7 +2913,7 @@ private void doCheckIndex() throws IOException {
29132913
throw e;
29142914
}
29152915
final List<String> checkedFiles = new ArrayList<>(metadata.size());
2916-
for (Map.Entry<String, StoreFileMetadata> entry : metadata.asMap().entrySet()) {
2916+
for (Map.Entry<String, StoreFileMetadata> entry : metadata.fileMetadataMap().entrySet()) {
29172917
try {
29182918
Store.checkIntegrity(entry.getValue(), store.directory());
29192919
if (corrupt == null) {

server/src/main/java/org/elasticsearch/index/store/Store.java

Lines changed: 51 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ public MetadataSnapshot getMetadata(IndexCommit commit, boolean lockDirectory) t
265265
java.util.concurrent.locks.Lock lock = lockDirectory ? metadataLock.writeLock() : metadataLock.readLock();
266266
lock.lock();
267267
try (Closeable ignored = lockDirectory ? directory.obtainLock(IndexWriter.WRITE_LOCK_NAME) : () -> {}) {
268-
return new MetadataSnapshot(commit, directory, logger);
268+
return MetadataSnapshot.loadFromIndexCommit(commit, directory, logger);
269269
} catch (CorruptIndexException | IndexFormatTooOldException | IndexFormatTooNewException ex) {
270270
markStoreCorrupted(ex);
271271
throw ex;
@@ -448,7 +448,7 @@ public static MetadataSnapshot readMetadataSnapshot(
448448
Directory dir = new NIOFSDirectory(indexLocation)
449449
) {
450450
failIfCorrupted(dir);
451-
return new MetadataSnapshot(null, dir, logger);
451+
return MetadataSnapshot.loadFromIndexCommit(null, dir, logger);
452452
} catch (IndexNotFoundException ex) {
453453
// that's fine - happens all the time no need to log
454454
} catch (FileNotFoundException | NoSuchFileException ex) {
@@ -756,80 +756,24 @@ public String toString() {
756756
* change concurrently for safety reasons.
757757
*
758758
* @see StoreFileMetadata
759+
*
760+
* @param numDocs the number of documents in this store snapshot
759761
*/
760-
public static final class MetadataSnapshot implements Iterable<StoreFileMetadata>, Writeable {
761-
private final Map<String, StoreFileMetadata> metadata;
762-
private final Map<String, String> commitUserData;
763-
private final long numDocs;
762+
public record MetadataSnapshot(Map<String, StoreFileMetadata> fileMetadataMap, Map<String, String> commitUserData, long numDocs)
763+
implements
764+
Iterable<StoreFileMetadata>,
765+
Writeable {
764766

765767
public static final MetadataSnapshot EMPTY = new MetadataSnapshot(emptyMap(), emptyMap(), 0L);
766768

767-
public MetadataSnapshot(Map<String, StoreFileMetadata> metadata, Map<String, String> commitUserData, long numDocs) {
768-
this.metadata = metadata;
769-
this.commitUserData = commitUserData;
770-
this.numDocs = numDocs;
771-
}
772-
773-
MetadataSnapshot(IndexCommit commit, Directory directory, Logger logger) throws IOException {
774-
LoadedMetadata loadedMetadata = loadMetadata(commit, directory, logger);
775-
metadata = loadedMetadata.fileMetadata;
776-
commitUserData = loadedMetadata.userData;
777-
numDocs = loadedMetadata.numDocs;
778-
assert metadata.isEmpty() || numSegmentFiles() == 1 : "numSegmentFiles: " + numSegmentFiles();
779-
}
780-
781-
public static MetadataSnapshot readFrom(StreamInput in) throws IOException {
782-
final Map<String, StoreFileMetadata> metadata = in.readMapValues(StoreFileMetadata::new, StoreFileMetadata::name);
783-
final var commitUserData = in.readMap(StreamInput::readString, StreamInput::readString);
784-
final var numDocs = in.readLong();
785-
786-
if (metadata.size() == 0 && commitUserData.size() == 0 && numDocs == 0) {
787-
return MetadataSnapshot.EMPTY;
788-
} else {
789-
return new MetadataSnapshot(metadata, commitUserData, numDocs);
790-
}
791-
}
792-
793-
@Override
794-
public void writeTo(StreamOutput out) throws IOException {
795-
out.writeMapValues(metadata);
796-
out.writeMap(commitUserData, StreamOutput::writeString, StreamOutput::writeString);
797-
out.writeLong(numDocs);
798-
}
799-
800-
/**
801-
* Returns the number of documents in this store snapshot
802-
*/
803-
public long getNumDocs() {
804-
return numDocs;
805-
}
806-
807-
@Nullable
808-
public org.elasticsearch.Version getCommitVersion() {
809-
String version = commitUserData.get(ES_VERSION);
810-
return version == null ? null : org.elasticsearch.Version.fromString(version);
811-
}
812-
813-
static class LoadedMetadata {
814-
final Map<String, StoreFileMetadata> fileMetadata;
815-
final Map<String, String> userData;
769+
static MetadataSnapshot loadFromIndexCommit(IndexCommit commit, Directory directory, Logger logger) throws IOException {
816770
final long numDocs;
817-
818-
LoadedMetadata(Map<String, StoreFileMetadata> fileMetadata, Map<String, String> userData, long numDocs) {
819-
this.fileMetadata = fileMetadata;
820-
this.userData = userData;
821-
this.numDocs = numDocs;
822-
}
823-
}
824-
825-
static LoadedMetadata loadMetadata(IndexCommit commit, Directory directory, Logger logger) throws IOException {
826-
long numDocs;
827-
Map<String, StoreFileMetadata> builder = new HashMap<>();
828-
Map<String, String> commitUserDataBuilder = new HashMap<>();
771+
final Map<String, StoreFileMetadata> metadataByFile = new HashMap<>();
772+
final Map<String, String> commitUserData;
829773
try {
830774
final SegmentInfos segmentCommitInfos = Store.readSegmentsInfo(commit, directory);
831775
numDocs = Lucene.getNumDocs(segmentCommitInfos);
832-
commitUserDataBuilder.putAll(segmentCommitInfos.getUserData());
776+
commitUserData = Map.copyOf(segmentCommitInfos.getUserData());
833777
// we don't know which version was used to write so we take the max version.
834778
Version maxVersion = segmentCommitInfos.getMinSegmentLuceneVersion();
835779
for (SegmentCommitInfo info : segmentCommitInfos) {
@@ -849,7 +793,7 @@ static LoadedMetadata loadMetadata(IndexCommit commit, Directory directory, Logg
849793
checksumFromLuceneFile(
850794
directory,
851795
file,
852-
builder,
796+
metadataByFile,
853797
logger,
854798
version.toString(),
855799
SEGMENT_INFO_EXTENSION.equals(IndexFileNames.getExtension(file)),
@@ -864,7 +808,7 @@ static LoadedMetadata loadMetadata(IndexCommit commit, Directory directory, Logg
864808
checksumFromLuceneFile(
865809
directory,
866810
segmentsFile,
867-
builder,
811+
metadataByFile,
868812
logger,
869813
maxVersion.toString(),
870814
true,
@@ -886,16 +830,41 @@ static LoadedMetadata loadMetadata(IndexCommit commit, Directory directory, Logg
886830
ex
887831
);
888832
Lucene.checkSegmentInfoIntegrity(directory);
889-
} catch (CorruptIndexException | IndexFormatTooOldException | IndexFormatTooNewException cex) {
890-
cex.addSuppressed(ex);
891-
throw cex;
892833
} catch (Exception inner) {
893834
inner.addSuppressed(ex);
894835
throw inner;
895836
}
896837
throw ex;
897838
}
898-
return new LoadedMetadata(unmodifiableMap(builder), unmodifiableMap(commitUserDataBuilder), numDocs);
839+
final var metadataSnapshot = new MetadataSnapshot(unmodifiableMap(metadataByFile), commitUserData, numDocs);
840+
assert metadataSnapshot.fileMetadataMap.isEmpty() || metadataSnapshot.numSegmentFiles() == 1
841+
: "numSegmentFiles: " + metadataSnapshot.numSegmentFiles();
842+
return metadataSnapshot;
843+
}
844+
845+
public static MetadataSnapshot readFrom(StreamInput in) throws IOException {
846+
final Map<String, StoreFileMetadata> metadata = in.readMapValues(StoreFileMetadata::new, StoreFileMetadata::name);
847+
final var commitUserData = in.readMap(StreamInput::readString, StreamInput::readString);
848+
final var numDocs = in.readLong();
849+
850+
if (metadata.size() == 0 && commitUserData.size() == 0 && numDocs == 0) {
851+
return MetadataSnapshot.EMPTY;
852+
} else {
853+
return new MetadataSnapshot(metadata, commitUserData, numDocs);
854+
}
855+
}
856+
857+
@Override
858+
public void writeTo(StreamOutput out) throws IOException {
859+
out.writeMapValues(fileMetadataMap);
860+
out.writeMap(commitUserData, StreamOutput::writeString, StreamOutput::writeString);
861+
out.writeLong(numDocs);
862+
}
863+
864+
@Nullable
865+
public org.elasticsearch.Version getCommitVersion() {
866+
String version = commitUserData.get(ES_VERSION);
867+
return version == null ? null : org.elasticsearch.Version.fromString(version);
899868
}
900869

901870
private static void checksumFromLuceneFile(
@@ -956,15 +925,11 @@ public static void hashFile(BytesRefBuilder fileHash, InputStream in, long size)
956925

957926
@Override
958927
public Iterator<StoreFileMetadata> iterator() {
959-
return metadata.values().iterator();
928+
return fileMetadataMap.values().iterator();
960929
}
961930

962931
public StoreFileMetadata get(String name) {
963-
return metadata.get(name);
964-
}
965-
966-
public Map<String, StoreFileMetadata> asMap() {
967-
return metadata;
932+
return fileMetadataMap.get(name);
968933
}
969934

970935
private static final String SEGMENT_INFO_EXTENSION = "si";
@@ -1079,13 +1044,13 @@ public RecoveryDiff recoveryDiff(final MetadataSnapshot targetSnapshot) {
10791044
Collections.unmodifiableList(different),
10801045
Collections.unmodifiableList(missing)
10811046
);
1082-
assert recoveryDiff.size() == metadata.size()
1047+
assert recoveryDiff.size() == fileMetadataMap.size()
10831048
: "some files are missing: recoveryDiff is ["
10841049
+ recoveryDiff
10851050
+ "] comparing: ["
1086-
+ metadata
1051+
+ fileMetadataMap
10871052
+ "] to ["
1088-
+ targetSnapshot.metadata
1053+
+ targetSnapshot.fileMetadataMap
10891054
+ "]";
10901055
return recoveryDiff;
10911056
}
@@ -1094,11 +1059,7 @@ public RecoveryDiff recoveryDiff(final MetadataSnapshot targetSnapshot) {
10941059
* Returns the number of files in this snapshot
10951060
*/
10961061
public int size() {
1097-
return metadata.size();
1098-
}
1099-
1100-
public Map<String, String> getCommitUserData() {
1101-
return commitUserData;
1062+
return fileMetadataMap.size();
11021063
}
11031064

11041065
/**
@@ -1112,7 +1073,7 @@ public String getHistoryUUID() {
11121073
* Returns true iff this metadata contains the given file.
11131074
*/
11141075
public boolean contains(String existingFile) {
1115-
return metadata.containsKey(existingFile);
1076+
return fileMetadataMap.containsKey(existingFile);
11161077
}
11171078

11181079
/**
@@ -1124,7 +1085,7 @@ public StoreFileMetadata getSegmentsFile() {
11241085
return file;
11251086
}
11261087
}
1127-
assert metadata.isEmpty();
1088+
assert fileMetadataMap.isEmpty();
11281089
return null;
11291090
}
11301091

server/src/main/java/org/elasticsearch/indices/recovery/PeerRecoveryTargetService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ public static StartRecoveryRequest getStartRecoveryRequest(
299299
metadataSnapshot = recoveryTarget.indexShard().snapshotStoreMetadata();
300300
// Make sure that the current translog is consistent with the Lucene index; otherwise, we have to throw away the Lucene index.
301301
try {
302-
final String expectedTranslogUUID = metadataSnapshot.getCommitUserData().get(Translog.TRANSLOG_UUID_KEY);
302+
final String expectedTranslogUUID = metadataSnapshot.commitUserData().get(Translog.TRANSLOG_UUID_KEY);
303303
final long globalCheckpoint = Translog.readGlobalCheckpoint(recoveryTarget.translogLocation(), expectedTranslogUUID);
304304
assert globalCheckpoint + 1 >= startingSeqNo : "invalid startingSeqNo " + startingSeqNo + " >= " + globalCheckpoint;
305305
} catch (IOException | TranslogCorruptedException e) {

server/src/main/java/org/elasticsearch/indices/recovery/RecoverySourceHandler.java

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -547,10 +547,10 @@ void phase1(IndexCommit snapshot, long startingSeqNo, IntSupplier translogOps, A
547547
for (String name : snapshot.getFileNames()) {
548548
final StoreFileMetadata md = recoverySourceMetadata.get(name);
549549
if (md == null) {
550-
logger.info("Snapshot differs from actual index for file: {} meta: {}", name, recoverySourceMetadata.asMap());
550+
logger.info("Snapshot differs from actual index for file: {} meta: {}", name, recoverySourceMetadata.fileMetadataMap());
551551
throw new CorruptIndexException(
552552
"Snapshot differs from actual index - maybe index was removed metadata has "
553-
+ recoverySourceMetadata.asMap().size()
553+
+ recoverySourceMetadata.fileMetadataMap().size()
554554
+ " files",
555555
name
556556
);
@@ -624,11 +624,11 @@ void recoverFilesFromSourceAndSnapshot(
624624
}
625625

626626
for (StoreFileMetadata md : shardRecoveryPlan.getSourceFilesToRecover()) {
627-
if (request.metadataSnapshot().asMap().containsKey(md.name())) {
627+
if (request.metadataSnapshot().fileMetadataMap().containsKey(md.name())) {
628628
logger.trace(
629629
"recovery [phase1]: recovering [{}], exists in local store, but is different: remote [{}], local [{}]",
630630
md.name(),
631-
request.metadataSnapshot().asMap().get(md.name()),
631+
request.metadataSnapshot().fileMetadataMap().get(md.name()),
632632
md
633633
);
634634
} else {
@@ -638,11 +638,11 @@ void recoverFilesFromSourceAndSnapshot(
638638

639639
for (BlobStoreIndexShardSnapshot.FileInfo fileInfo : shardRecoveryPlan.getSnapshotFilesToRecover()) {
640640
final StoreFileMetadata md = fileInfo.metadata();
641-
if (request.metadataSnapshot().asMap().containsKey(md.name())) {
641+
if (request.metadataSnapshot().fileMetadataMap().containsKey(md.name())) {
642642
logger.trace(
643643
"recovery [phase1]: recovering [{}], exists in local store, but is different: remote [{}], local [{}]",
644644
md.name(),
645-
request.metadataSnapshot().asMap().get(md.name()),
645+
request.metadataSnapshot().fileMetadataMap().get(md.name()),
646646
md
647647
);
648648
} else {
@@ -986,32 +986,32 @@ boolean canSkipPhase1(Store.MetadataSnapshot source, Store.MetadataSnapshot targ
986986
if (source.getSyncId() == null || source.getSyncId().equals(target.getSyncId()) == false) {
987987
return false;
988988
}
989-
if (source.getNumDocs() != target.getNumDocs()) {
989+
if (source.numDocs() != target.numDocs()) {
990990
throw new IllegalStateException(
991991
"try to recover "
992992
+ request.shardId()
993993
+ " from primary shard with sync id but number "
994994
+ "of docs differ: "
995-
+ source.getNumDocs()
995+
+ source.numDocs()
996996
+ " ("
997997
+ request.sourceNode().getName()
998998
+ ", primary) vs "
999-
+ target.getNumDocs()
999+
+ target.numDocs()
10001000
+ "("
10011001
+ request.targetNode().getName()
10021002
+ ")"
10031003
);
10041004
}
1005-
SequenceNumbers.CommitInfo sourceSeqNos = SequenceNumbers.loadSeqNoInfoFromLuceneCommit(source.getCommitUserData().entrySet());
1006-
SequenceNumbers.CommitInfo targetSeqNos = SequenceNumbers.loadSeqNoInfoFromLuceneCommit(target.getCommitUserData().entrySet());
1005+
SequenceNumbers.CommitInfo sourceSeqNos = SequenceNumbers.loadSeqNoInfoFromLuceneCommit(source.commitUserData().entrySet());
1006+
SequenceNumbers.CommitInfo targetSeqNos = SequenceNumbers.loadSeqNoInfoFromLuceneCommit(target.commitUserData().entrySet());
10071007
if (sourceSeqNos.localCheckpoint != targetSeqNos.localCheckpoint || targetSeqNos.maxSeqNo != sourceSeqNos.maxSeqNo) {
10081008
final String message = "try to recover "
10091009
+ request.shardId()
10101010
+ " with sync id but "
10111011
+ "seq_no stats are mismatched: ["
1012-
+ source.getCommitUserData()
1012+
+ source.commitUserData()
10131013
+ "] vs ["
1014-
+ target.getCommitUserData()
1014+
+ target.commitUserData()
10151015
+ "]";
10161016
assert false : message;
10171017
throw new IllegalStateException(message);

server/src/main/java/org/elasticsearch/indices/store/TransportNodesListShardStoreMetadata.java

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -192,18 +192,14 @@ private StoreFilesMetadata listStoreMetadata(NodeRequest request) throws IOExcep
192192
}
193193
}
194194

195-
public static class StoreFilesMetadata implements Iterable<StoreFileMetadata>, Writeable {
196-
private final Store.MetadataSnapshot metadataSnapshot;
197-
private final List<RetentionLease> peerRecoveryRetentionLeases;
195+
public record StoreFilesMetadata(Store.MetadataSnapshot metadataSnapshot, List<RetentionLease> peerRecoveryRetentionLeases)
196+
implements
197+
Iterable<StoreFileMetadata>,
198+
Writeable {
198199

199200
private static final ShardId FAKE_SHARD_ID = new ShardId("_na_", "_na_", 0);
200201
public static final StoreFilesMetadata EMPTY = new StoreFilesMetadata(Store.MetadataSnapshot.EMPTY, emptyList());
201202

202-
public StoreFilesMetadata(Store.MetadataSnapshot metadataSnapshot, List<RetentionLease> peerRecoveryRetentionLeases) {
203-
this.metadataSnapshot = metadataSnapshot;
204-
this.peerRecoveryRetentionLeases = peerRecoveryRetentionLeases;
205-
}
206-
207203
public static StoreFilesMetadata readFrom(StreamInput in) throws IOException {
208204
if (in.getVersion().before(Version.V_8_2_0)) {
209205
new ShardId(in);
@@ -240,11 +236,11 @@ public Iterator<StoreFileMetadata> iterator() {
240236
}
241237

242238
public boolean fileExists(String name) {
243-
return metadataSnapshot.asMap().containsKey(name);
239+
return metadataSnapshot.fileMetadataMap().containsKey(name);
244240
}
245241

246242
public StoreFileMetadata file(String name) {
247-
return metadataSnapshot.asMap().get(name);
243+
return metadataSnapshot.fileMetadataMap().get(name);
248244
}
249245

250246
/**
@@ -260,10 +256,6 @@ public long getPeerRecoveryRetentionLeaseRetainingSeqNo(DiscoveryNode node) {
260256
.orElse(-1L);
261257
}
262258

263-
public List<RetentionLease> peerRecoveryRetentionLeases() {
264-
return peerRecoveryRetentionLeases;
265-
}
266-
267259
/**
268260
* @return commit sync id if exists, else null
269261
*/

0 commit comments

Comments
 (0)