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/02/15 13:15:51 UTC

svn commit: r1446549 - in /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment: MongoStore.java Segment.java SegmentCache.java

Author: jukka
Date: Fri Feb 15 12:15:51 2013
New Revision: 1446549

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

Start working on a combined memory/disk cache

Added:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentCache.java
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoStore.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Segment.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoStore.java?rev=1446549&r1=1446548&r2=1446549&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoStore.java Fri Feb 15 12:15:51 2013
@@ -18,6 +18,7 @@ package org.apache.jackrabbit.oak.plugin
 
 import java.util.List;
 import java.util.UUID;
+import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 
 import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeState;
@@ -37,27 +38,17 @@ public class MongoStore implements Segme
 
     private static final int MAX_SEGMENT_SIZE = 1 << 23; // 8MB
 
-    private static final long DEFAULT_CACHE_SIZE = 1 << 28; // 256MB
-
     private final DBCollection segments;
 
     private final DBCollection journals;
 
-    private final LoadingCache<UUID, Segment> cache;
+    private final SegmentCache cache;
 
-    public MongoStore(DB db, long cacheSize) {
+    public MongoStore(DB db, SegmentCache cache) {
         this.segments = db.getCollection("segments");
         this.journals = db.getCollection("journals");
 
-        this.cache = CacheBuilder.newBuilder()
-                .maximumWeight(cacheSize)
-                .weigher(Segment.weigher())
-                .build(new CacheLoader<UUID, Segment>() {
-                    @Override
-                    public Segment load(UUID key) throws Exception {
-                        return findSegment(key);
-                    }
-                });
+        this.cache = cache;
 
         SegmentWriter writer = new SegmentWriter(this);
         RecordId id = writer.writeNode(MemoryNodeState.EMPTY_NODE);
@@ -70,7 +61,7 @@ public class MongoStore implements Segme
     }
 
     public MongoStore(DB db) {
-        this(db, DEFAULT_CACHE_SIZE);
+        this(db, new SegmentCache());
     }
 
 
@@ -99,18 +90,18 @@ public class MongoStore implements Segme
     }
 
     @Override
-    public Segment readSegment(UUID segmentId) {
-        try {
-            return cache.get(segmentId);
-        } catch (ExecutionException e) {
-            throw new IllegalStateException(
-                    "Failed to read segment " + segmentId, e);
-        }
+    public Segment readSegment(final UUID segmentId) {
+        return cache.getSegment(segmentId, new Callable<Segment>() {
+            @Override
+            public Segment call() throws Exception {
+                return findSegment(segmentId);
+            }
+        });
     }
 
     @Override
     public void createSegment(Segment segment) {
-        cache.put(segment.getSegmentId(), segment);
+        cache.addSegment(segment);
         insertSegment(
                 segment.getSegmentId(),
                 segment.getData(),
@@ -161,6 +152,6 @@ public class MongoStore implements Segme
     @Override
     public void deleteSegment(UUID segmentId) {
         segments.remove(new BasicDBObject("_id", segmentId.toString()));
-        cache.invalidate(segmentId);
+        cache.removeSegment(segmentId);
     }
 }

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=1446549&r1=1446548&r2=1446549&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 Fri Feb 15 12:15:51 2013
@@ -27,6 +27,14 @@ import com.google.common.cache.Weigher;
 
 class Segment {
 
+    static final Weigher<UUID, Segment> WEIGHER =
+            new Weigher<UUID, Segment>() {
+                @Override
+                public int weigh(UUID key, Segment value) {
+                    return value.size();
+                }
+            };
+
     static final int SMALL_LIMIT = 1 << 7;
 
     static final int MEDIUM_LIMIT = 1 << 14 + SMALL_LIMIT;
@@ -99,13 +107,4 @@ class Segment {
         return ByteBuffer.wrap(data).getLong(offset);
     }
 
-    public static Weigher<UUID, Segment> weigher() {
-        return new Weigher<UUID, Segment>() {
-            @Override
-            public int weigh(UUID key, Segment value) {
-                return value.size();
-            }
-        };
-    }
-
 }

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentCache.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentCache.java?rev=1446549&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentCache.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentCache.java Fri Feb 15 12:15:51 2013
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.plugins.segment;
+
+import java.io.File;
+import java.util.UUID;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.cache.RemovalListener;
+import com.google.common.cache.RemovalNotification;
+import com.google.common.cache.Weigher;
+
+/**
+ * Combined memory and disk cache for segments.
+ */
+public class SegmentCache {
+
+    private static final long DEFAULT_MEMORY_CACHE_SIZE = 1 << 28; // 256MB
+
+    private final Cache<UUID, Segment> memoryCache;
+
+    // private final Cache<UUID, File> diskCache;
+
+    // private final File diskCacheDirectory;
+
+    public SegmentCache(long memoryCacheSize) {
+//        this.diskCacheDirectory = diskCacheDirectory;
+//        this.diskCache = CacheBuilder.newBuilder()
+//                .maximumWeight(diskCacheSize)
+//                .weigher(new Weigher<UUID, File>() {
+//                    @Override
+//                    public int weigh(UUID key, File value) {
+//                        return (int) value.length(); // <= max segment size
+//                    }
+//                }).build();
+        this.memoryCache = CacheBuilder.newBuilder()
+                .maximumWeight(memoryCacheSize)
+                .weigher(Segment.WEIGHER)
+//                .removalListener(new RemovalListener<UUID, Segment>() {
+//                    @Override
+//                    public void onRemoval(
+//                            RemovalNotification<UUID, Segment> notification) {
+//                        notification.getValue();
+//                    }
+//                })
+                .build();
+    }
+
+    public SegmentCache() {
+        this(DEFAULT_MEMORY_CACHE_SIZE);
+    }
+
+    public Segment getSegment(UUID segmentId, Callable<Segment> loader) {
+        try {
+            return memoryCache.get(segmentId, loader);
+        } catch (ExecutionException e) {
+            throw new IllegalStateException(
+                    "Failed to load segment " + segmentId, e);
+        }
+    }
+
+    public void addSegment(Segment segment) {
+        memoryCache.put(segment.getSegmentId(), segment);
+    }
+
+    public void removeSegment(UUID segmentId) {
+        memoryCache.invalidate(segmentId);
+    }
+
+}