Author: frm Date: Tue Oct 18 12:04:37 2016 New Revision: 1765419 URL: http://svn.apache.org/viewvc?rev=1765419&view=rev Log: OAK-4740 - Delegate segment recovery to the FileStore
Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/AbstractFileStore.java jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/ReadOnlyFileStore.java jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/TarReader.java Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/AbstractFileStore.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/AbstractFileStore.java?rev=1765419&r1=1765418&r2=1765419&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/AbstractFileStore.java (original) +++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/AbstractFileStore.java Tue Oct 18 12:04:37 2016 @@ -27,8 +27,10 @@ import static java.util.Collections.sing import java.io.Closeable; import java.io.File; import java.io.IOException; +import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Map; +import java.util.UUID; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -37,7 +39,11 @@ import javax.annotation.Nonnull; import org.apache.jackrabbit.oak.api.jmx.CacheStatsMBean; import org.apache.jackrabbit.oak.segment.CachingSegmentReader; +import org.apache.jackrabbit.oak.segment.RecordType; import org.apache.jackrabbit.oak.segment.Revisions; +import org.apache.jackrabbit.oak.segment.Segment; +import org.apache.jackrabbit.oak.segment.Segment.RecordConsumer; +import org.apache.jackrabbit.oak.segment.SegmentBlob; import org.apache.jackrabbit.oak.segment.SegmentCache; import org.apache.jackrabbit.oak.segment.SegmentId; import org.apache.jackrabbit.oak.segment.SegmentIdFactory; @@ -94,6 +100,15 @@ public abstract class AbstractFileStore @Nonnull final SegmentCache segmentCache; + final TarRecovery recovery = new TarRecovery() { + + @Override + public void recoverEntry(UUID uuid, byte[] data, TarWriter writer) throws IOException { + writeSegment(uuid, data, writer); + } + + }; + @Nonnull private final SegmentIdFactory segmentIdFactory = new SegmentIdFactory() { @@ -301,6 +316,41 @@ public abstract class AbstractFileStore return blobStore; } + private void writeSegment(UUID id, byte[] data, TarWriter w) throws IOException { + long msb = id.getMostSignificantBits(); + long lsb = id.getLeastSignificantBits(); + ByteBuffer buffer = ByteBuffer.wrap(data); + int generation = Segment.getGcGeneration(buffer, id); + w.writeEntry(msb, lsb, data, 0, data.length, generation); + if (SegmentId.isDataSegmentId(lsb)) { + Segment segment = new Segment(this, segmentReader, newSegmentId(msb, lsb), buffer); + populateTarGraph(segment, w); + populateTarBinaryReferences(segment, w); + } + } + + final void populateTarGraph(Segment segment, TarWriter w) { + UUID from = segment.getSegmentId().asUUID(); + for (int i = 0; i < segment.getReferencedSegmentIdCount(); i++) { + w.addGraphEdge(from, segment.getReferencedSegmentId(i)); + } + } + + final void populateTarBinaryReferences(final Segment segment, final TarWriter w) { + final int generation = segment.getGcGeneration(); + final UUID id = segment.getSegmentId().asUUID(); + segment.forEachRecord(new RecordConsumer() { + + @Override + public void consume(int number, RecordType type, int offset) { + if (type == RecordType.BLOB_ID) { + w.addBinaryReference(generation, id, SegmentBlob.readBlobId(segment, number)); + } + } + + }); + } + static void closeAndLogOnFail(Closeable closeable) { if (closeable != null) { try { @@ -311,4 +361,5 @@ public abstract class AbstractFileStore } } } + } Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java?rev=1765419&r1=1765418&r2=1765419&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java (original) +++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java Tue Oct 18 12:04:37 2016 @@ -193,7 +193,7 @@ public class FileStore extends AbstractF Integer[] indices = map.keySet().toArray(new Integer[map.size()]); Arrays.sort(indices); for (int i = indices.length - 1; i >= 0; i--) { - readers.add(TarReader.open(map.get(indices[i]), memoryMapping)); + readers.add(TarReader.open(map.get(indices[i]), memoryMapping, recovery)); } this.stats = new FileStoreStats(builder.getStatsProvider(), this, size()); @@ -641,8 +641,8 @@ public class FileStore extends AbstractF // (potentially) flushing the TAR file. if (segment != null) { - populateTarGraph(segment); - populateTarBinaryReferences(segment); + populateTarGraph(segment, tarWriter); + populateTarBinaryReferences(segment, tarWriter); } // Close the TAR file if the size exceeds the maximum. @@ -661,28 +661,6 @@ public class FileStore extends AbstractF } } - private void populateTarGraph(Segment segment) { - UUID from = segment.getSegmentId().asUUID(); - for (int i = 0; i < segment.getReferencedSegmentIdCount(); i++) { - tarWriter.addGraphEdge(from, segment.getReferencedSegmentId(i)); - } - } - - private void populateTarBinaryReferences(final Segment segment) { - final int generation = segment.getGcGeneration(); - final UUID id = segment.getSegmentId().asUUID(); - segment.forEachRecord(new RecordConsumer() { - - @Override - public void consume(int number, RecordType type, int offset) { - if (type == RecordType.BLOB_ID) { - tarWriter.addBinaryReference(generation, id, SegmentBlob.readBlobId(segment, number)); - } - } - - }); - } - /** * Switch to a new tar writer. * This method may only be called when holding the write lock of {@link #fileStoreLock} Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/ReadOnlyFileStore.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/ReadOnlyFileStore.java?rev=1765419&r1=1765418&r2=1765419&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/ReadOnlyFileStore.java (original) +++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/ReadOnlyFileStore.java Tue Oct 18 12:04:37 2016 @@ -82,8 +82,7 @@ public class ReadOnlyFileStore extends A // only try to read-only recover the latest file as that might // be the *only* one still being accessed by a writer boolean recover = i == indices.length - 1; - readers.add(TarReader.openRO(map.get(indices[i]), memoryMapping, - recover)); + readers.add(TarReader.openRO(map.get(indices[i]), memoryMapping, recover, recovery)); } log.info("TarMK ReadOnly opened: {} (mmap={})", directory, memoryMapping); Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/TarReader.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/TarReader.java?rev=1765419&r1=1765418&r2=1765419&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/TarReader.java (original) +++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/TarReader.java Tue Oct 18 12:04:37 2016 @@ -71,18 +71,6 @@ class TarReader implements Closeable { private static final Logger GC_LOG = LoggerFactory.getLogger(TarReader.class.getName() + "-GC"); - private static final TarRecovery DEFAULT_TAR_RECOVERY = new TarRecovery() { - - @Override - public void recoverEntry(UUID uuid, byte[] data, TarWriter writer) throws IOException { - int generation = getGcGeneration(wrap(data), uuid); - long msb = uuid.getMostSignificantBits(); - long lsb = uuid.getLeastSignificantBits(); - writer.writeEntry(msb, lsb, data, 0, data.length, generation); - } - - }; - /** Magic byte sequence at the end of the index block. */ private static final int INDEX_MAGIC = TarWriter.INDEX_MAGIC; @@ -126,8 +114,7 @@ class TarReader implements Closeable { * @return * @throws IOException */ - static TarReader open(Map<Character, File> files, boolean memoryMapping) - throws IOException { + static TarReader open(Map<Character, File> files, boolean memoryMapping, TarRecovery recovery) throws IOException { SortedMap<Character, File> sorted = newTreeMap(); sorted.putAll(files); @@ -148,7 +135,7 @@ class TarReader implements Closeable { // regenerate the first generation based on the recovered data File file = sorted.values().iterator().next(); - generateTarFile(entries, file, DEFAULT_TAR_RECOVERY); + generateTarFile(entries, file, recovery); reader = openFirstFileWithValidIndex(singletonList(file), memoryMapping); if (reader != null) { @@ -158,8 +145,7 @@ class TarReader implements Closeable { } } - static TarReader openRO(Map<Character, File> files, boolean memoryMapping, - boolean recover) throws IOException { + static TarReader openRO(Map<Character, File> files, boolean memoryMapping, boolean recover, TarRecovery recovery) throws IOException { // for readonly store only try the latest generation of a given // tar file to prevent any rollback or rewrite File file = files.get(Collections.max(files.keySet())); @@ -178,7 +164,7 @@ class TarReader implements Closeable { LinkedHashMap<UUID, byte[]> entries = newLinkedHashMap(); collectFileEntries(file, entries, false); file = findAvailGen(file, ".ro.bak"); - generateTarFile(entries, file, DEFAULT_TAR_RECOVERY); + generateTarFile(entries, file, recovery); reader = openFirstFileWithValidIndex(singletonList(file), memoryMapping); if (reader != null) {