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/12 09:16:44 UTC

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

Author: jukka
Date: Tue Feb 12 08:16:44 2013
New Revision: 1445049

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

Initial MongoDB binding

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

Added: 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=1445049&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoStore.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoStore.java Tue Feb 12 08:16:44 2013
@@ -0,0 +1,155 @@
+/*
+ * 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.util.List;
+import java.util.UUID;
+import java.util.concurrent.ExecutionException;
+
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.mongodb.BasicDBObject;
+import com.mongodb.DB;
+import com.mongodb.DBCollection;
+import com.mongodb.DBObject;
+import com.mongodb.Mongo;
+
+public class MongoStore implements SegmentStore {
+
+    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;
+
+    public MongoStore(DB db, long cacheSize) {
+        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);
+                    }
+                });
+    }
+
+    public MongoStore(DB db) {
+        this(db, DEFAULT_CACHE_SIZE);
+    }
+
+
+    public MongoStore(Mongo mongo) {
+        this(mongo.getDB("Oak"));
+    }
+
+    @Override
+    public RecordId getJournalHead() {
+        DBObject journal = journals.findOne(new BasicDBObject("_id", "root"));
+        return RecordId.fromString(journal.get("head").toString());
+    }
+
+    @Override
+    public boolean setJournalHead(RecordId head, RecordId base) {
+        DBObject baseObject = new BasicDBObject(
+                ImmutableMap.of("_id", "root", "head", base.toString()));
+        DBObject headObject = new BasicDBObject(
+                ImmutableMap.of("_id", "root", "head", head.toString()));
+        return journals.update(baseObject, headObject).getN() == 1;
+    }
+
+    @Override
+    public int getMaxSegmentSize() {
+        return MAX_SEGMENT_SIZE;
+    }
+
+    @Override
+    public Segment readSegment(UUID segmentId) {
+        try {
+            return cache.get(segmentId);
+        } catch (ExecutionException e) {
+            throw new IllegalStateException(
+                    "Failed to read segment " + segmentId, e);
+        }
+    }
+
+    @Override
+    public void createSegment(Segment segment) {
+        cache.put(segment.getSegmentId(), segment);
+        insertSegment(
+                segment.getSegmentId(),
+                segment.getData(),
+                segment.getUUIDs());
+    }
+
+    @Override
+    public void createSegment(
+            UUID segmentId, byte[] data, int offset, int length) {
+        byte[] d = data;
+        if (offset != 0 || length != data.length) {
+            d = new byte[length];
+            System.arraycopy(data, offset, d, 0, length);
+        }
+        insertSegment(segmentId, d, new UUID[0]);
+    }
+
+    private Segment findSegment(UUID segmentId) {
+        DBObject segment = segments.findOne(
+                new BasicDBObject("_id", segmentId.toString()));
+        if (segment == null) {
+            throw new IllegalStateException(
+                    "Segment " + segmentId + " not found");
+        }
+
+        byte[] data = (byte[]) segment.get("data");
+        List<?> list = (List<?>) segment.get("uuids");
+        UUID[] uuids = new UUID[list.size()];
+        for (int i = 0; i < uuids.length; i++) {
+            uuids[i] = UUID.fromString(list.get(i).toString());
+        }
+        return new Segment(segmentId, data, uuids);
+    }
+
+    private void insertSegment(UUID segmentId, byte[] data, UUID[] uuids) {
+        List<String> list = Lists.newArrayListWithCapacity(uuids.length);
+        for (UUID uuid : uuids) {
+            list.add(uuid.toString());
+        }
+
+        BasicDBObject segment = new BasicDBObject();
+        segment.put("_id", segmentId.toString());
+        segment.put("data", data);
+        segment.put("uuids", list);
+        segments.insert(segment);
+    }
+
+    @Override
+    public void deleteSegment(UUID segmentId) {
+        segments.remove(new BasicDBObject("_id", segmentId.toString()));
+        cache.invalidate(segmentId);
+    }
+}

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/RecordId.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/RecordId.java?rev=1445049&r1=1445048&r2=1445049&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/RecordId.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/RecordId.java Tue Feb 12 08:16:44 2013
@@ -24,6 +24,17 @@ public final class RecordId implements C
 
     public static RecordId[] EMPTY_ARRAY = new RecordId[0];
 
+    public static RecordId fromString(String id) {
+        int colon = id.indexOf(':');
+        if (colon != -1) {
+            return new RecordId(
+                    UUID.fromString(id.substring(0, colon)),
+                    Integer.parseInt(id.substring(colon + 1)));
+        } else {
+            throw new IllegalArgumentException("Bad RecordId: " + id);
+        }
+    }
+
     private final UUID segmentId;
 
     private final int offset;

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=1445049&r1=1445048&r2=1445049&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 Tue Feb 12 08:16:44 2013
@@ -47,6 +47,14 @@ class Segment {
         return uuid;
     }
 
+    public byte[] getData() {
+        return data;
+    }
+
+    public UUID[] getUUIDs() {
+        return uuids;
+    }
+
     public int size() {
         return data.length;
     }