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;
}