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/09/29 21:48:58 UTC

svn commit: r1527390 - in /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment: AbstractStore.java OffsetCache.java Segment.java SegmentStore.java file/FileStore.java memory/MemoryStore.java mongo/MongoStore.java

Author: jukka
Date: Sun Sep 29 19:48:58 2013
New Revision: 1527390

URL: http://svn.apache.org/r1527390
Log:
OAK-1031: SegmentMK: Fewer segment lookups

Replace the per-segment OffsetCaches with a per-store LIRS record cache.
This way we can avoid the segment lookups for the string and template
records that quite frequently cross segment boundaries.

Added:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/AbstractStore.java
      - copied, changed from r1527267, jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStore.java
Removed:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/OffsetCache.java
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Segment.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStore.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/memory/MemoryStore.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/mongo/MongoStore.java

Copied: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/AbstractStore.java (from r1527267, jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStore.java)
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/AbstractStore.java?p2=jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/AbstractStore.java&p1=jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStore.java&r1=1527267&r2=1527390&rev=1527390&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/AbstractStore.java Sun Sep 29 19:48:58 2013
@@ -16,32 +16,31 @@
  */
 package org.apache.jackrabbit.oak.plugins.segment;
 
-import java.util.List;
-import java.util.UUID;
+import java.util.concurrent.Callable;
 
-public interface SegmentStore {
+import org.apache.jackrabbit.oak.cache.CacheLIRS;
 
-    SegmentWriter getWriter();
+import com.google.common.cache.Cache;
 
-    Journal getJournal(String name);
+public abstract class AbstractStore implements SegmentStore {
 
-    Segment readSegment(UUID segmentId);
-
-    /**
-     * Writes the given segment to the segment store.
-     *
-     * @param segmentId segment identifier
-     * @param bytes byte buffer that contains the raw contents of the segment
-     * @param offset start offset within the byte buffer
-     * @param length length of the segment
-     * @param referencedSegmentIds identifiers of all the referenced segments
-     */
-    void writeSegment(
-            UUID segmentId, byte[] bytes, int offset, int length,
-            List<UUID> referencedSegmentIds);
-
-    void deleteSegment(UUID segmentId);
-
-    void close();
+    private final Cache<RecordId, Object> records =
+            CacheLIRS.newBuilder().maximumSize(10000).build();
+
+    @Override
+    public <T> T getRecord(RecordId id, Callable<T> loader) {
+        @SuppressWarnings("unchecked")
+        T record = (T) records.getIfPresent(id);
+        if (record == null) {
+            try {
+                record = loader.call();
+                records.put(id, record);
+            } catch (Exception e) {
+                throw new IllegalStateException(
+                        "Failed to load record " + id, e);
+            }
+        }
+        return record;
+    }
 
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Segment.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Segment.java?rev=1527390&r1=1527389&r2=1527390&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Segment.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Segment.java Sun Sep 29 19:48:58 2013
@@ -25,6 +25,7 @@ import java.nio.ByteBuffer;
 import java.util.Arrays;
 import java.util.List;
 import java.util.UUID;
+import java.util.concurrent.Callable;
 
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Type;
@@ -97,36 +98,12 @@ public class Segment {
 
     private final List<UUID> uuids;
 
-    private final OffsetCache<String> strings;
-
-    private final OffsetCache<Template> templates;
-
-    private final OffsetCache<MapRecord> maps;
-
     public Segment(
             SegmentStore store, UUID uuid, ByteBuffer data, List<UUID> uuids) {
         this.store = checkNotNull(store);
         this.uuid = checkNotNull(uuid);
         this.data = checkNotNull(data);
         this.uuids = checkNotNull(uuids);
-        this.strings = new OffsetCache<String>() {
-            @Override
-            protected String load(int offset) {
-                return loadString(offset);
-            }
-        };
-        this.templates = new OffsetCache<Template>() {
-            @Override
-            protected Template load(int offset) {
-                return loadTemplate(offset);
-            }
-        };
-        this.maps = new OffsetCache<MapRecord>() {
-            @Override
-            protected MapRecord load(int offset) {
-                return loadMap(offset);
-            }
-        };
     }
 
     /**
@@ -222,15 +199,16 @@ public class Segment {
                 | (data.get(pos + 3) & 0xff);
     }
 
-    String readString(RecordId id) {
-        return getSegment(id).readString(id.getOffset());
+    String readString(final RecordId id) {
+        return store.getRecord(id, new Callable<String>() {
+            @Override
+            public String call() {
+                return getSegment(id).readString(id.getOffset());
+            }
+        });
     }
 
     String readString(int offset) {
-        return strings.get(offset);
-    }
-
-    private String loadString(int offset) {
         int pos = pos(offset, 1);
         long length = internalReadLength(pos);
         if (length < SMALL_LIMIT) {
@@ -261,15 +239,16 @@ public class Segment {
         }
     }
 
-    MapRecord readMap(RecordId id) {
-        return getSegment(id).readMap(id.getOffset());
+    MapRecord readMap(final RecordId id) {
+        return store.getRecord(id, new Callable<MapRecord>() {
+            @Override
+            public MapRecord call() {
+                return getSegment(id).readMap(id.getOffset());
+            }
+        });
     }
 
     MapRecord readMap(int offset) {
-        return maps.get(offset);
-    }
-
-    private MapRecord loadMap(int offset) {
         int head = readInt(offset);
         int level = head >>> MapRecord.SIZE_BITS;
         int size = head & ((1 << MapRecord.SIZE_BITS) - 1);
@@ -282,15 +261,16 @@ public class Segment {
         }
     }
 
-    Template readTemplate(RecordId id) {
-        return getSegment(id).readTemplate(id.getOffset());
+    Template readTemplate(final RecordId id) {
+        return store.getRecord(id, new Callable<Template>() {
+            @Override
+            public Template call() {
+                return getSegment(id).readTemplate(id.getOffset());
+            }
+        });
     }
 
     Template readTemplate(int offset) {
-        return templates.get(offset);
-    }
-
-    private Template loadTemplate(int offset) {
         int head = readInt(offset);
         boolean hasPrimaryType = (head & (1 << 31)) != 0;
         boolean hasMixinTypes = (head & (1 << 30)) != 0;

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStore.java?rev=1527390&r1=1527389&r2=1527390&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStore.java Sun Sep 29 19:48:58 2013
@@ -18,6 +18,7 @@ package org.apache.jackrabbit.oak.plugin
 
 import java.util.List;
 import java.util.UUID;
+import java.util.concurrent.Callable;
 
 public interface SegmentStore {
 
@@ -44,4 +45,6 @@ public interface SegmentStore {
 
     void close();
 
+    <T> T getRecord(RecordId id, Callable<T> loader);
+
 }

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=1527390&r1=1527389&r2=1527390&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 Sun Sep 29 19:48:58 2013
@@ -33,16 +33,16 @@ import java.util.Map;
 import java.util.concurrent.Callable;
 import java.util.UUID;
 
+import org.apache.jackrabbit.oak.plugins.segment.AbstractStore;
 import org.apache.jackrabbit.oak.plugins.segment.Journal;
 import org.apache.jackrabbit.oak.plugins.segment.RecordId;
 import org.apache.jackrabbit.oak.plugins.segment.Segment;
 import org.apache.jackrabbit.oak.plugins.segment.SegmentCache;
 import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeState;
-import org.apache.jackrabbit.oak.plugins.segment.SegmentStore;
 import org.apache.jackrabbit.oak.plugins.segment.SegmentWriter;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 
-public class FileStore implements SegmentStore {
+public class FileStore extends AbstractStore {
 
     private static final long SEGMENT_MAGIC = 0x4f616b0a527845ddL;
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/memory/MemoryStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/memory/MemoryStore.java?rev=1527390&r1=1527389&r2=1527390&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/memory/MemoryStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/memory/MemoryStore.java Sun Sep 29 19:48:58 2013
@@ -24,9 +24,9 @@ import java.util.Map;
 import java.util.UUID;
 import java.util.concurrent.ConcurrentMap;
 
+import org.apache.jackrabbit.oak.plugins.segment.AbstractStore;
 import org.apache.jackrabbit.oak.plugins.segment.Journal;
 import org.apache.jackrabbit.oak.plugins.segment.Segment;
-import org.apache.jackrabbit.oak.plugins.segment.SegmentStore;
 import org.apache.jackrabbit.oak.plugins.segment.SegmentWriter;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
@@ -34,7 +34,7 @@ import org.apache.jackrabbit.oak.spi.sta
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 
-public class MemoryStore implements SegmentStore {
+public class MemoryStore extends AbstractStore {
 
     private final Map<String, Journal> journals = Maps.newHashMap();
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/mongo/MongoStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/mongo/MongoStore.java?rev=1527390&r1=1527389&r2=1527390&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/mongo/MongoStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/mongo/MongoStore.java Sun Sep 29 19:48:58 2013
@@ -29,10 +29,10 @@ import java.util.Map;
 import java.util.UUID;
 import java.util.concurrent.Callable;
 
+import org.apache.jackrabbit.oak.plugins.segment.AbstractStore;
 import org.apache.jackrabbit.oak.plugins.segment.Journal;
 import org.apache.jackrabbit.oak.plugins.segment.Segment;
 import org.apache.jackrabbit.oak.plugins.segment.SegmentCache;
-import org.apache.jackrabbit.oak.plugins.segment.SegmentStore;
 import org.apache.jackrabbit.oak.plugins.segment.SegmentWriter;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 
@@ -45,7 +45,7 @@ import com.mongodb.DBObject;
 import com.mongodb.Mongo;
 import com.mongodb.WriteConcern;
 
-public class MongoStore implements SegmentStore {
+public class MongoStore extends AbstractStore {
 
     private final WriteConcern concern = WriteConcern.SAFE; // TODO: MAJORITY?