You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by ju...@apache.org on 2013/12/04 03:48:09 UTC

svn commit: r1547694 - in /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file: FileJournal.java FileStore.java

Author: jukka
Date: Wed Dec  4 02:48:09 2013
New Revision: 1547694

URL: http://svn.apache.org/r1547694
Log:
OAK-593: Segment-based MK

Store the TarMK journal in a separate journal.log file

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileJournal.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileJournal.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileJournal.java?rev=1547694&r1=1547693&r2=1547694&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileJournal.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileJournal.java Wed Dec  4 02:48:09 2013
@@ -16,47 +16,33 @@
  */
 package org.apache.jackrabbit.oak.plugins.segment.file;
 
-import java.io.IOException;
-
+import org.apache.jackrabbit.oak.plugins.segment.Journal;
 import org.apache.jackrabbit.oak.plugins.segment.RecordId;
-import org.apache.jackrabbit.oak.plugins.segment.memory.MemoryJournal;
-import org.apache.jackrabbit.oak.spi.state.NodeState;
 
-class FileJournal extends MemoryJournal {
+class FileJournal implements Journal {
 
     private final FileStore store;
 
-    FileJournal(FileStore store, NodeState head) {
-        super(store, head);
+    private final String name;
+
+    FileJournal(FileStore store, String name) {
         this.store = store;
+        this.name = name;
     }
 
-    FileJournal(FileStore store, String parent) {
-        super(store, parent);
-        this.store = store;
+    @Override
+    public RecordId getHead() {
+        return store.getHead(name);
     }
 
     @Override
-    public synchronized boolean setHead(RecordId base, RecordId head) {
-        if (super.setHead(base, head)) { // flushes the segment if needed
-            try {
-                store.writeJournals();
-                return true;
-            } catch (IOException e) {
-                throw new RuntimeException(e);
-            }
-        } else {
-            return false;
-        }
+    public boolean setHead(RecordId base, RecordId head) {
+        return store.setHead(name, base, head);
     }
 
     @Override
-    public synchronized void merge() {
-        super.merge();
-        try {
-            store.writeJournals();
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
+    public void merge() {
+        throw new UnsupportedOperationException();
     }
+
 }
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java?rev=1547694&r1=1547693&r2=1547694&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java Wed Dec  4 02:48:09 2013
@@ -16,17 +16,17 @@
  */
 package org.apache.jackrabbit.oak.plugins.segment.file;
 
-import static com.google.common.base.Charsets.UTF_8;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkState;
 import static com.google.common.collect.Lists.newArrayList;
 import static com.google.common.collect.Lists.newLinkedList;
-import static com.google.common.collect.Maps.newHashMap;
+import static com.google.common.collect.Maps.newConcurrentMap;
 import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
 import static org.apache.jackrabbit.oak.plugins.segment.SegmentIdFactory.isBulkSegmentId;
 
 import java.io.File;
 import java.io.IOException;
+import java.io.RandomAccessFile;
 import java.nio.ByteBuffer;
 import java.util.LinkedList;
 import java.util.List;
@@ -47,12 +47,10 @@ public class FileStore extends AbstractS
 
     private static final int DEFAULT_MEMORY_CACHE_SIZE = 256;
 
-    private static final long JOURNAL_MAGIC = 0xdf36544212c0cb24L;
-
-    static final UUID JOURNALS_UUID = new UUID(0, 0);
-
     private static final String FILE_NAME_FORMAT = "%s%05d.tar";
 
+    private static final String JOURNAL_FILE_NAME = "journal.log";
+
     private final File directory;
 
     private final int maxFileSize;
@@ -63,7 +61,9 @@ public class FileStore extends AbstractS
 
     private final LinkedList<TarFile> dataFiles = newLinkedList();
 
-    private final Map<String, Journal> journals = newHashMap();
+    private final RandomAccessFile journalFile;
+
+    private final Map<String, RecordId> journals = newConcurrentMap();
 
     public FileStore(File directory, int maxFileSizeMB, boolean memoryMapping)
             throws IOException {
@@ -103,30 +103,46 @@ public class FileStore extends AbstractS
             }
         }
 
-        Segment segment = getWriter().getDummySegment();
-        for (TarFile tar : dataFiles) {
-            ByteBuffer buffer = tar.readEntry(JOURNALS_UUID);
-            if (buffer != null) {
-                checkState(JOURNAL_MAGIC == buffer.getLong());
-                int count = buffer.getInt();
-                for (int i = 0; i < count; i++) {
-                    byte[] b = new byte[buffer.getInt()];
-                    buffer.get(b);
-                    String name = new String(b, UTF_8);
-                    RecordId recordId = new RecordId(
-                            new UUID(buffer.getLong(), buffer.getLong()),
-                            buffer.getInt());
-                    journals.put(name, new FileJournal(
-                            this, new SegmentNodeState(segment, recordId)));
-                }
+        journalFile = new RandomAccessFile(
+                new File(directory, JOURNAL_FILE_NAME), "rw");
+        String line = journalFile.readLine();
+        while (line != null) {
+            int space = line.indexOf(' ');
+            if (space != -1) {
+                String name = line.substring(space + 1);
+                RecordId id = RecordId.fromString(line.substring(0, space));
+                journals.put(name, id);
             }
+            line = journalFile.readLine();
         }
 
         if (!journals.containsKey("root")) {
             NodeBuilder builder = EMPTY_NODE.builder();
             builder.setChildNode("root", initial);
-            journals.put("root", new FileJournal(this, builder.getNodeState()));
-            writeJournals();
+            SegmentNodeState root =
+                    getWriter().writeNode(builder.getNodeState());
+            journals.put("root", root.getRecordId());
+            journalFile.writeBytes(root.getRecordId() + " root\n");
+        }
+    }
+
+    RecordId getHead(String name) {
+        return journals.get(name);
+    }
+
+    synchronized boolean setHead(String name, RecordId base, RecordId head) {
+        if (base.equals(journals.get(name))) {
+            getWriter().flush();
+            try {
+                journalFile.writeBytes(head + " " + name + "\n");
+                journals.put(name, head);
+                return true;
+            } catch (IOException e) {
+                throw new IllegalStateException(
+                        "Failed to update journal " + name, e);
+            }
+        } else {
+            return false;
         }
     }
 
@@ -145,6 +161,9 @@ public class FileStore extends AbstractS
     public synchronized void close() {
         try {
             super.close();
+
+            journalFile.close();
+
             for (TarFile file : bulkFiles) {
                 file.close();
             }
@@ -153,6 +172,7 @@ public class FileStore extends AbstractS
                 file.close();
             }
             dataFiles.clear();
+
             System.gc(); // for any memory-mappings that are no longer used
         } catch (Exception e) {
             throw new RuntimeException(e);
@@ -160,13 +180,13 @@ public class FileStore extends AbstractS
     }
 
     @Override
-    public synchronized Journal getJournal(final String name) {
-        Journal journal = journals.get(name);
-        if (journal == null) {
-            journal = new FileJournal(this, "root");
-            journals.put(name, journal);
+    public Journal getJournal(String name) {
+        synchronized (journals) {
+            if (journals.containsKey(name)) {
+                journals.put(name, journals.get("root"));
+            }
         }
-        return journal;
+        return new FileJournal(this, name);
     }
 
     @Override @Nonnull
@@ -233,26 +253,4 @@ public class FileStore extends AbstractS
         super.deleteSegment(segmentId);
     }
 
-    synchronized void writeJournals() throws IOException {
-        int size = 8 + 4;
-        for (String name : journals.keySet()) {
-            size += 4 + name.getBytes(UTF_8).length + 16 + 4;
-        }
-
-        ByteBuffer buffer = ByteBuffer.allocate(size);
-        buffer.putLong(JOURNAL_MAGIC);
-        buffer.putInt(journals.size());
-        for (Map.Entry<String, Journal> entry : journals.entrySet()) {
-            byte[] name = entry.getKey().getBytes(UTF_8);
-            buffer.putInt(name.length);
-            buffer.put(name);
-            RecordId head = entry.getValue().getHead();
-            buffer.putLong(head.getSegmentId().getMostSignificantBits());
-            buffer.putLong(head.getSegmentId().getLeastSignificantBits());
-            buffer.putInt(head.getOffset());
-        }
-
-        writeEntry(JOURNALS_UUID, buffer.array(), 0, size);
-    }
-
 }