You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by st...@apache.org on 2011/11/12 22:58:23 UTC
svn commit: r1201340 - in /jackrabbit/sandbox/microkernel: ./
src/main/java/org/apache/jackrabbit/mk/
src/main/java/org/apache/jackrabbit/mk/store/
src/test/java/org/apache/jackrabbit/mk/
Author: stefan
Date: Sat Nov 12 21:58:22 2011
New Revision: 1201340
URL: http://svn.apache.org/viewvc?rev=1201340&view=rev
Log:
experimental mongodb support
Added:
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/MongoRevisionStore.java
Modified:
jackrabbit/sandbox/microkernel/pom.xml
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/Repository.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/CommitBuilder.java
jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/ConcurrentWriteTest.java
Modified: jackrabbit/sandbox/microkernel/pom.xml
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/pom.xml?rev=1201340&r1=1201339&r2=1201340&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/pom.xml (original)
+++ jackrabbit/sandbox/microkernel/pom.xml Sat Nov 12 21:58:22 2011
@@ -45,6 +45,12 @@
<version>4.1.10</version>
</dependency>
+ <dependency>
+ <groupId>org.mongodb</groupId>
+ <artifactId>mongo-java-driver</artifactId>
+ <version>2.7.1</version>
+ </dependency>
+
<!--Test Dependencies-->
<dependency>
<groupId>com.googlecode.json-simple</groupId>
Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/Repository.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/Repository.java?rev=1201340&r1=1201339&r2=1201340&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/Repository.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/Repository.java Sat Nov 12 21:58:22 2011
@@ -22,6 +22,7 @@ import org.apache.jackrabbit.mk.blobs.Fi
import org.apache.jackrabbit.mk.store.Commit;
import org.apache.jackrabbit.mk.store.CommitBuilder;
import org.apache.jackrabbit.mk.store.H2RevisionStore;
+import org.apache.jackrabbit.mk.store.MongoRevisionStore;
import org.apache.jackrabbit.mk.store.Node;
import org.apache.jackrabbit.mk.store.NotFoundException;
import org.apache.jackrabbit.mk.store.PersistenceManager;
@@ -55,6 +56,7 @@ public class Repository {
File home = new File(homeDir);
+ //RevisionStore revStore = new MongoRevisionStore();
RevisionStore revStore = new H2RevisionStore();
//RevisionStore revStore = new SimpleRevisionStore();
//RevisionStore revStore = new BDbRevisionStore();
Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/CommitBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/CommitBuilder.java?rev=1201340&r1=1201339&r2=1201340&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/CommitBuilder.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/CommitBuilder.java Sat Nov 12 21:58:22 2011
@@ -311,8 +311,8 @@ public class CommitBuilder {
* @throws Exception
*/
String /* id of merged root node */ mergeTree(Node baseRoot, Node ourRoot, Node theirRoot) throws Exception {
- // we're going to use the staging area for the merge process,
- // clear it first
+ // as we're going to use the staging area for the merge process,
+ // we need to clear it first
staged.clear();
// recursively merge 'our' changes with 'their' changes...
@@ -365,7 +365,8 @@ public class CommitBuilder {
// merge the dirty subtrees recursively
mergeNode(baseChild, ourChild, theirChild, PathUtils.concat(path, conflictName));
} else {
- // todo handle/merge colliding node additions
+ // todo handle/merge colliding node creation
+ throw new Exception("colliding concurrent node creation: " + conflictPath);
}
break;
}
Added: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/MongoRevisionStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/MongoRevisionStore.java?rev=1201340&view=auto
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/MongoRevisionStore.java (added)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/MongoRevisionStore.java Sat Nov 12 21:58:22 2011
@@ -0,0 +1,247 @@
+/*
+ * 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.mk.store;
+
+import com.mongodb.BasicDBObject;
+import com.mongodb.DB;
+import com.mongodb.DBCollection;
+import com.mongodb.DBObject;
+import com.mongodb.Mongo;
+import com.mongodb.MongoException;
+import com.mongodb.WriteConcern;
+import com.mongodb.gridfs.GridFS;
+import com.mongodb.gridfs.GridFSDBFile;
+import com.mongodb.gridfs.GridFSInputFile;
+import com.sun.tools.javac.jvm.ClassWriter;
+import org.apache.jackrabbit.mk.blobs.BlobStore;
+import org.apache.jackrabbit.mk.util.IOUtils;
+import org.apache.jackrabbit.mk.util.StringUtils;
+import org.bson.types.ObjectId;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.security.DigestOutputStream;
+import java.security.MessageDigest;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ *
+ */
+public class MongoRevisionStore extends AbstractRevisionStore implements BlobStore {
+
+ private boolean initialized;
+
+ private Mongo con;
+ private DB db;
+ private DBCollection revs;
+ private GridFS fs;
+
+ private String headId;
+ private final ReentrantReadWriteLock headLock;
+
+ private static String HEAD_COLLECTION = "head";
+ private static String REVS_COLLECTION = "revs";
+ private static String ID_FIELD = "id";
+ private static String DATA_FIELD = "data";
+
+ public MongoRevisionStore() throws Exception {
+ headId = null;
+ headLock = new ReentrantReadWriteLock();
+
+ initialized = false;
+ }
+
+ //---------------------------------------------------------< RevisionStore >
+
+ public void initialize(File homeDir) throws Exception {
+ if (initialized) {
+ throw new IllegalStateException("already initialized");
+ }
+
+ super.initialize(homeDir);
+
+ con = new Mongo();
+ //con = new Mongo("localhost", 27017);
+
+ db = con.getDB("mk");
+ db.setWriteConcern(WriteConcern.SAFE);
+
+ if (!db.collectionExists(HEAD_COLLECTION)) {
+ // capped collection of size 1
+ db.createCollection(HEAD_COLLECTION, new BasicDBObject("capped", true).append("size", 256).append("max", 1));
+ }
+
+ revs = db.getCollection(REVS_COLLECTION);
+ revs.ensureIndex(
+ new BasicDBObject(ID_FIELD, 1),
+ new BasicDBObject("unique", true));
+ fs = new GridFS(db);
+
+ initialized = true;
+ }
+
+ public void close() {
+ if (!initialized) {
+ return;
+ }
+
+ con.close();
+ con = null;
+ db = null;
+
+ initialized = false;
+ }
+
+ public InputStream get(String id) throws Exception {
+ if (!initialized) {
+ throw new IllegalStateException("not initialized");
+ }
+
+ BasicDBObject key = new BasicDBObject();
+ //key.put(ID_FIELD, StringUtils.convertHexToBytes(id));
+ key.put(ID_FIELD, id);
+ DBObject rev = revs.findOne(key);
+ if (rev != null) {
+ return new ByteArrayInputStream((byte[])rev.get(DATA_FIELD));
+ } else {
+ throw new NotFoundException(id);
+ }
+ }
+
+ public String put(InputStream in) throws Exception {
+ if (!initialized) {
+ throw new IllegalStateException("not initialized");
+ }
+
+ MessageDigest digest = MessageDigest.getInstance("SHA-1");
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ DigestOutputStream dos = new DigestOutputStream(baos, digest);
+
+ try {
+ int read;
+ byte[] buf = new byte[8192];
+ while ((read = in.read(buf, 0, buf.length)) != -1) {
+ dos.write(buf, 0, read);
+ }
+ } finally {
+ dos.flush();
+ // baos.close();
+ in.close();
+ }
+
+ byte[] key = digest.digest();
+ String id = StringUtils.convertBytesToHex(key);
+ //BasicDBObject rev = new BasicDBObject(ID_FIELD, key).append(DATA_FIELD, baos.toByteArray());
+ BasicDBObject rev = new BasicDBObject(ID_FIELD, id).append(DATA_FIELD, baos.toByteArray());
+ try {
+ revs.insert(rev);
+ } catch (MongoException.DuplicateKey ignore) {
+ // fall through
+ }
+
+ return id;
+ }
+
+ //-------------------------------------------------------------< BlobStore >
+
+ public String writeBlob(InputStream in) throws Exception {
+ if (!initialized) {
+ throw new IllegalStateException("not initialized");
+ }
+
+ GridFSInputFile f = fs.createFile(in, true);
+ //f.save(0x20000); // save in 128k chunks
+ f.save();
+
+ return f.getId().toString();
+ }
+
+ public int readBlob(String blobId, long pos, byte[] buff, int off, int length) throws Exception {
+ if (!initialized) {
+ throw new IllegalStateException("not initialized");
+ }
+
+ GridFSDBFile f = fs.findOne(new ObjectId(blobId));
+ if (f == null) {
+ throw new NotFoundException(blobId);
+ }
+ // todo provide a more efficient implementation
+ InputStream in = f.getInputStream();
+ try {
+ in.skip(pos);
+ return in.read(buff, off, length);
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ }
+
+ public long getBlobLength(String blobId) throws Exception {
+ if (!initialized) {
+ throw new IllegalStateException("not initialized");
+ }
+
+ GridFSDBFile f = fs.findOne(new ObjectId(blobId));
+ if (f == null) {
+ throw new NotFoundException(blobId);
+ }
+
+ return f.getLength();
+ }
+
+ //------------------------------------------------------------< overrides >
+
+ @Override
+ public String getHeadId() throws Exception {
+ //return super.getHeadId();
+ if (!initialized) {
+ throw new IllegalStateException("not initialized");
+ }
+ headLock.readLock().lock();
+ try {
+ if (headId == null) {
+ DBObject entry = db.getCollection(HEAD_COLLECTION).findOne();
+ if (entry == null) {
+ return null;
+ }
+ headId = (String) entry.get(ID_FIELD);
+ return headId;
+ } else {
+ return headId;
+ }
+ } finally {
+ headLock.readLock().unlock();
+ }
+ }
+
+ @Override
+ public void setHeadId(String revId) throws Exception {
+ //super.setHeadId(revId);
+ if (!initialized) {
+ throw new IllegalStateException("not initialized");
+ }
+ headLock.writeLock().lock();
+ try {
+ // capped collection of size 1
+ db.getCollection(HEAD_COLLECTION).insert(new BasicDBObject(ID_FIELD, revId));
+ headId = revId;
+ } finally {
+ headLock.writeLock().unlock();
+ }
+ }
+}
Modified: jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/ConcurrentWriteTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/ConcurrentWriteTest.java?rev=1201340&r1=1201339&r2=1201340&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/ConcurrentWriteTest.java (original)
+++ jackrabbit/sandbox/microkernel/src/test/java/org/apache/jackrabbit/mk/ConcurrentWriteTest.java Sat Nov 12 21:58:22 2011
@@ -24,10 +24,10 @@ public class ConcurrentWriteTest extends
protected static final String TEST_PATH = "/" + ConcurrentWriteTest.class.getName();
- // private static final String URL = "fs:{homeDir}/target;clean";
+ private static final String URL = "fs:{homeDir}/target;clean";
// private static final String URL = "fs:{homeDir}/target";
// private static final String URL = "mem:";
- private static final String URL = "mem:fs:target/temp;clean";
+ //private static final String URL = "mem:fs:target/temp;clean";
private static final int NUM_THREADS = 20;
private static final int NUM_CHILDNODES = 1000;