use of io.pravega.segmentstore.storage.metadata.SegmentMetadata in project pravega by pravega.
the class SystemJournal method createSystemSnapshotRecord.
private CompletableFuture<SystemSnapshotRecord> createSystemSnapshotRecord(MetadataTransaction txn, boolean validateSegment, boolean validateChunks) {
val systemSnapshot = SystemSnapshotRecord.builder().epoch(epoch).fileIndex(currentFileIndex.get()).segmentSnapshotRecords(new ArrayList<>()).build();
val futures = Collections.synchronizedList(new ArrayList<CompletableFuture<Void>>());
for (val systemSegment : systemSegments) {
// Find segment metadata.
val future = txn.get(systemSegment).thenComposeAsync(metadata -> {
val segmentMetadata = (SegmentMetadata) metadata;
segmentMetadata.checkInvariants();
val segmentSnapshot = SegmentSnapshotRecord.builder().segmentMetadata(segmentMetadata).chunkMetadataCollection(new ArrayList<>()).build();
// Enumerate all chunks.
val currentChunkName = new AtomicReference<>(segmentMetadata.getFirstChunk());
val dataSize = new AtomicLong();
val chunkCount = new AtomicLong();
// For each chunk
return Futures.loop(() -> null != currentChunkName.get(), () -> txn.get(currentChunkName.get()).thenComposeAsync(m -> {
val currentChunkMetadata = (ChunkMetadata) m;
CompletableFuture<Void> f;
Preconditions.checkState(null != currentChunkMetadata, "currentChunkMetadata must not be null");
if (validateChunks) {
f = chunkStorage.getInfo(currentChunkName.get()).thenAcceptAsync(chunkInfo -> Preconditions.checkState(chunkInfo.getLength() >= currentChunkMetadata.getLength(), "Wrong chunk length chunkInfo=%d, currentMetadata=%d.", chunkInfo.getLength(), currentChunkMetadata.getLength()), executor);
} else {
f = CompletableFuture.completedFuture(null);
}
return f.thenAcceptAsync(v -> {
chunkCount.getAndIncrement();
dataSize.addAndGet(currentChunkMetadata.getLength());
segmentSnapshot.chunkMetadataCollection.add(currentChunkMetadata);
// move to next chunk
currentChunkName.set(currentChunkMetadata.getNextChunk());
}, executor);
}, executor), executor).thenAcceptAsync(v -> {
// Validate
if (validateSegment) {
Preconditions.checkState(chunkCount.get() == segmentMetadata.getChunkCount(), "Wrong chunk count. Segment=%s", segmentMetadata);
Preconditions.checkState(dataSize.get() == segmentMetadata.getLength() - segmentMetadata.getFirstChunkStartOffset(), "Data size does not match dataSize (%s). Segment=%s", dataSize.get(), segmentMetadata);
}
// Add to the system snapshot.
synchronized (systemSnapshot) {
systemSnapshot.segmentSnapshotRecords.add(segmentSnapshot);
}
}, executor);
}, executor);
futures.add(future);
}
return Futures.allOf(futures).thenApplyAsync(vv -> {
systemSnapshot.checkInvariants();
return systemSnapshot;
}, executor);
}
use of io.pravega.segmentstore.storage.metadata.SegmentMetadata in project pravega by pravega.
the class SystemJournal method applyTruncate.
/**
* Apply truncate action to the segment metadata.
*/
private CompletableFuture<Void> applyTruncate(MetadataTransaction txn, String segmentName, long truncateAt, long firstChunkStartsAt) {
return txn.get(segmentName).thenComposeAsync(metadata -> {
val segmentMetadata = (SegmentMetadata) metadata;
segmentMetadata.checkInvariants();
val currentChunkName = new AtomicReference<>(segmentMetadata.getFirstChunk());
val currentMetadata = new AtomicReference<ChunkMetadata>();
val startOffset = new AtomicLong(segmentMetadata.getFirstChunkStartOffset());
val shouldBreak = new AtomicBoolean();
return Futures.loop(() -> null != currentChunkName.get() && !shouldBreak.get(), () -> txn.get(currentChunkName.get()).thenAcceptAsync(m -> {
currentMetadata.set((ChunkMetadata) m);
// If for given chunk start <= truncateAt < end then we have found the chunk that will be the first chunk.
if ((startOffset.get() <= truncateAt) && (startOffset.get() + currentMetadata.get().getLength() > truncateAt)) {
shouldBreak.set(true);
} else {
startOffset.addAndGet(currentMetadata.get().getLength());
// move to next chunk
currentChunkName.set(currentMetadata.get().getNextChunk());
txn.delete(currentMetadata.get().getName());
segmentMetadata.setChunkCount(segmentMetadata.getChunkCount() - 1);
}
}, executor), executor).thenAcceptAsync(v -> {
Preconditions.checkState(firstChunkStartsAt == startOffset.get(), "firstChunkStartsAt (%s) must be equal to startOffset (%s)", firstChunkStartsAt, startOffset);
segmentMetadata.setFirstChunk(currentChunkName.get());
if (null == currentChunkName.get()) {
segmentMetadata.setLastChunk(null);
segmentMetadata.setLastChunkStartOffset(firstChunkStartsAt);
}
segmentMetadata.setStartOffset(truncateAt);
segmentMetadata.setFirstChunkStartOffset(firstChunkStartsAt);
segmentMetadata.checkInvariants();
}, executor);
}, executor);
}
use of io.pravega.segmentstore.storage.metadata.SegmentMetadata in project pravega by pravega.
the class SystemJournal method validateSegment.
/**
* Validate that all information for given segment in given snapshot exists in transaction.
*/
private CompletableFuture<Void> validateSegment(MetadataTransaction txn, String segmentName) {
return txn.get(segmentName).thenComposeAsync(m -> {
val segmentMetadata = (SegmentMetadata) m;
Preconditions.checkState(null != segmentMetadata, "Segment metadata must not be null.");
val chunkName = new AtomicReference<>(segmentMetadata.getFirstChunk());
return Futures.loop(() -> chunkName.get() != null, () -> txn.get(chunkName.get()).thenAcceptAsync(mm -> {
Preconditions.checkState(null != mm, "Chunk metadata must not be null.");
val chunkMetadata = (ChunkMetadata) mm;
chunkName.set(chunkMetadata.getNextChunk());
}, executor), executor);
}, executor);
}
Aggregations