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/12 00:57:33 UTC

svn commit: r1550321 - in /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment: AbstractStore.java Segment.java SegmentStore.java

Author: jukka
Date: Wed Dec 11 23:57:32 2013
New Revision: 1550321

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

Go back to caching accessed strings and templates per segment.
With the larger segment size achieved through the SegmentWriter changes
this again makes more sense than the centralized record cache in AbstractStore.

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/AbstractStore.java
    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

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/AbstractStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/AbstractStore.java?rev=1550321&r1=1550320&r2=1550321&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/AbstractStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/AbstractStore.java Wed Dec 11 23:57:32 2013
@@ -21,7 +21,6 @@ import static org.apache.jackrabbit.oak.
 
 import java.util.Set;
 import java.util.UUID;
-import java.util.concurrent.Callable;
 
 import javax.annotation.Nonnull;
 
@@ -46,9 +45,6 @@ public abstract class AbstractStore impl
      */
     private int currentlyWaiting = 0;
 
-    private final Cache<RecordId, Object> records =
-            CacheLIRS.newBuilder().maximumSize(1000).build();
-
     private final SegmentWriter writer = new SegmentWriter(this);
 
     protected AbstractStore(int cacheSizeMB) {
@@ -143,24 +139,7 @@ public abstract class AbstractStore impl
     }
 
     @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;
-    }
-
-    @Override
     public void close() {
-        records.invalidateAll();
         if (segments != null) {
             synchronized (segments) {
                 while (!currentlyLoading.isEmpty()) {

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=1550321&r1=1550320&r2=1550321&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 Wed Dec 11 23:57:32 2013
@@ -20,6 +20,7 @@ import static com.google.common.base.Obj
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkPositionIndexes;
 import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.collect.Maps.newConcurrentMap;
 import static org.apache.jackrabbit.oak.plugins.segment.SegmentIdFactory.isDataSegmentId;
 import static org.apache.jackrabbit.oak.plugins.segment.SegmentWriter.BLOCK_SIZE;
 
@@ -29,7 +30,7 @@ import java.nio.ByteBuffer;
 import java.util.Arrays;
 import java.util.List;
 import java.util.UUID;
-import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentMap;
 
 import javax.annotation.Nonnull;
 
@@ -112,6 +113,18 @@ public class Segment {
 
     private final boolean current;
 
+    /**
+     * String records read from segment. Used to avoid duplicate
+     * copies and repeated parsing of the same strings.
+     */
+    private final ConcurrentMap<Integer, String> strings = newConcurrentMap();
+
+    /**
+     * Template records read from segment. Used to avoid duplicate
+     * copies and repeated parsing of the same templates.
+     */
+    private final ConcurrentMap<Integer, Template> templates = newConcurrentMap();
+
     public Segment(SegmentStore store, UUID uuid, ByteBuffer data) {
         this.store = checkNotNull(store);
         this.uuid = checkNotNull(uuid);
@@ -256,15 +269,19 @@ public class Segment {
     }
 
     String readString(final RecordId id) {
-        return store.getRecord(id, new Callable<String>() {
-            @Override
-            public String call() {
-                return getSegment(id).readString(id.getOffset());
-            }
-        });
+        return getSegment(id).readString(id.getOffset());
     }
 
-    String readString(int offset) {
+    private String readString(int offset) {
+        String string = strings.get(offset);
+        if (string == null) {
+            string = loadString(offset);
+            strings.putIfAbsent(offset, string); // only keep the first copy
+        }
+        return string;
+    }
+
+    private String loadString(int offset) {
         int pos = pos(offset, 1);
         long length = internalReadLength(pos);
         if (length < SMALL_LIMIT) {
@@ -300,15 +317,19 @@ public class Segment {
     }
 
     Template readTemplate(final RecordId id) {
-        return store.getRecord(id, new Callable<Template>() {
-            @Override
-            public Template call() {
-                return getSegment(id).readTemplate(id.getOffset());
-            }
-        });
+        return getSegment(id).readTemplate(id.getOffset());
+    }
+
+    private Template readTemplate(int offset) {
+        Template template = templates.get(offset);
+        if (template == null) {
+            template = loadTemplate(offset);
+            templates.putIfAbsent(offset, template); // only keep the first copy
+        }
+        return template;
     }
 
-    Template readTemplate(int 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=1550321&r1=1550320&r2=1550321&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 Wed Dec 11 23:57:32 2013
@@ -17,7 +17,6 @@
 package org.apache.jackrabbit.oak.plugins.segment;
 
 import java.util.UUID;
-import java.util.concurrent.Callable;
 
 public interface SegmentStore {
 
@@ -41,8 +40,6 @@ public interface SegmentStore {
 
     void close();
 
-    <T> T getRecord(RecordId id, Callable<T> loader);
-
     /**
      * Checks whether the given object is a record of the given type and
      * is stored in this segment store.