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 md...@apache.org on 2012/10/12 16:21:54 UTC

svn commit: r1397576 - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/api/ oak-core/src/main/java/org/apache/jackrabbit/oak/core/ oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/ oak-core/src/main/java/org/apache/jac...

Author: mduerig
Date: Fri Oct 12 14:21:53 2012
New Revision: 1397576

URL: http://svn.apache.org/viewvc?rev=1397576&view=rev
Log:
OAK-375: Binaries are kept in memory on write access
Creating binary values through the value factory causes them to be streamed to the underlying node store.

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/ContentSession.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ContentSessionImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStore.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStore.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeStore.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/value/BinaryImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/value/ValueFactoryImpl.java
    jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/ContentSession.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/ContentSession.java?rev=1397576&r1=1397575&r2=1397576&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/ContentSession.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/api/ContentSession.java Fri Oct 12 14:21:53 2012
@@ -17,6 +17,8 @@
 package org.apache.jackrabbit.oak.api;
 
 import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
 
 import javax.annotation.Nonnull;
 
@@ -83,5 +85,12 @@ public interface ContentSession extends 
     @Nonnull
     Root getLatestRoot();
 
-    // TODO : add versioning operations
+    /**
+     * Create a {@link Blob} from the given input stream. The input stream
+     * is closed after this method returns.
+     * @param inputStream  The input stream for the {@code Blob}
+     * @return  The {@code Blob} representing {@code inputStream}
+     * @throws IOException  If an error occurs while reading from the stream
+     */
+    Blob createBlob(InputStream inputStream) throws IOException;
 }
\ No newline at end of file

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ContentSessionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ContentSessionImpl.java?rev=1397576&r1=1397575&r2=1397576&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ContentSessionImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ContentSessionImpl.java Fri Oct 12 14:21:53 2012
@@ -17,12 +17,14 @@
 package org.apache.jackrabbit.oak.core;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.Set;
 
 import javax.annotation.Nonnull;
 import javax.security.auth.login.LoginException;
 
 import org.apache.jackrabbit.oak.api.AuthInfo;
+import org.apache.jackrabbit.oak.api.Blob;
 import org.apache.jackrabbit.oak.api.ContentSession;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.spi.commit.ConflictHandlerProvider;
@@ -81,6 +83,11 @@ class ContentSessionImpl implements Cont
     }
 
     @Override
+    public Blob createBlob(InputStream inputStream) throws IOException {
+        return store.createBlob(inputStream);
+    }
+
+    @Override
     public synchronized void close() throws IOException {
         try {
             loginContext.logout();

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStore.java?rev=1397576&r1=1397575&r2=1397576&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/kernel/KernelNodeStore.java Fri Oct 12 14:21:53 2012
@@ -16,10 +16,15 @@
  */
 package org.apache.jackrabbit.oak.kernel;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.concurrent.ExecutionException;
 
 import javax.annotation.Nonnull;
 
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
 import org.apache.jackrabbit.mk.api.MicroKernel;
 import org.apache.jackrabbit.mk.api.MicroKernelException;
 import org.apache.jackrabbit.oak.spi.commit.CommitHook;
@@ -30,10 +35,6 @@ import org.apache.jackrabbit.oak.spi.sta
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
 import org.apache.jackrabbit.oak.spi.state.NodeStoreBranch;
 
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-
 import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
@@ -121,6 +122,20 @@ public class KernelNodeStore implements 
         return new KernelNodeStoreBranch(this, getRoot());
     }
 
+    /**
+     * @return An instance of {@link KernelBlob}
+     */
+    @Override
+    public KernelBlob createBlob(InputStream inputStream) throws IOException {
+        try {
+            String blobId = kernel.write(inputStream);
+            return new KernelBlob(blobId, kernel);
+        }
+        catch (MicroKernelException e) {
+            throw new IOException(e);
+        }
+    }
+
     //-----------------------------------------------------------< internal >---
 
     @Nonnull

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStore.java?rev=1397576&r1=1397575&r2=1397576&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/memory/MemoryNodeStore.java Fri Oct 12 14:21:53 2012
@@ -16,8 +16,11 @@
  */
 package org.apache.jackrabbit.oak.plugins.memory;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.concurrent.atomic.AtomicReference;
 
+import com.google.common.io.ByteStreams;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
@@ -42,6 +45,19 @@ public class MemoryNodeStore implements 
         return new MemoryNodeStoreBranch(root.get());
     }
 
+    /**
+     * @return An instance of {@link ArrayBasedBlob}.
+     */
+    @Override
+    public ArrayBasedBlob createBlob(InputStream inputStream) throws IOException {
+        try {
+            return new ArrayBasedBlob(ByteStreams.toByteArray(inputStream));
+        }
+        finally {
+            inputStream.close();
+        }
+    }
+
     private class MemoryNodeStoreBranch implements NodeStoreBranch {
 
         private final NodeState base;

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeStore.java?rev=1397576&r1=1397575&r2=1397576&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/state/NodeStore.java Fri Oct 12 14:21:53 2012
@@ -16,8 +16,13 @@
  */
 package org.apache.jackrabbit.oak.spi.state;
 
+import java.io.IOException;
+import java.io.InputStream;
+
 import javax.annotation.Nonnull;
 
+import org.apache.jackrabbit.oak.api.Blob;
+
 /**
  * Storage abstraction for trees. At any given point in time the stored
  * tree is rooted at a single immutable node state.
@@ -44,4 +49,12 @@ public interface NodeStore {
     @Nonnull
     NodeStoreBranch branch();
 
+    /**
+     * Create a {@link Blob} from the given input stream. The input stream
+     * is closed after this method returns.
+     * @param inputStream  The input stream for the {@code Blob}
+     * @return  The {@code Blob} representing {@code inputStream}
+     * @throws IOException  If an error occurs while reading from the stream
+     */
+    Blob createBlob(InputStream inputStream) throws IOException;
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/value/BinaryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/value/BinaryImpl.java?rev=1397576&r1=1397575&r2=1397576&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/value/BinaryImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/value/BinaryImpl.java Fri Oct 12 14:21:53 2012
@@ -36,6 +36,10 @@ class BinaryImpl implements Binary {
         this.value = value;
     }
 
+    ValueImpl getBinaryValue() {
+        return value.getType() == PropertyType.BINARY ? value : null;
+    }
+
     //-------------------------------------------------------------< Binary >---
     @Override
     public InputStream getStream() throws RepositoryException {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/value/ValueFactoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/value/ValueFactoryImpl.java?rev=1397576&r1=1397575&r2=1397576&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/value/ValueFactoryImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/value/ValueFactoryImpl.java Fri Oct 12 14:21:53 2012
@@ -34,7 +34,8 @@ import javax.jcr.ValueFactory;
 import javax.jcr.ValueFormatException;
 
 import com.google.common.collect.Lists;
-import com.google.common.io.ByteStreams;
+import org.apache.jackrabbit.oak.api.Blob;
+import org.apache.jackrabbit.oak.api.ContentSession;
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 import org.apache.jackrabbit.oak.plugins.identifier.IdentifierManager;
@@ -50,6 +51,7 @@ import org.slf4j.LoggerFactory;
 public class ValueFactoryImpl implements ValueFactory {
     private static final Logger log = LoggerFactory.getLogger(ValueFactoryImpl.class);
 
+    private final ContentSession contentSession;
     private final NamePathMapper namePathMapper;
 
     /**
@@ -58,7 +60,8 @@ public class ValueFactoryImpl implements
      * @param namePathMapper The name/path mapping used for converting JCR names/paths to
      * the internal representation.
      */
-    public ValueFactoryImpl(NamePathMapper namePathMapper) {
+    public ValueFactoryImpl(ContentSession session, NamePathMapper namePathMapper) {
+        this.contentSession = session;
         this.namePathMapper = namePathMapper;
     }
 
@@ -99,11 +102,7 @@ public class ValueFactoryImpl implements
     @Override
     public Value createValue(InputStream value) {
         try {
-            try {
-                return createValueImpl(value);
-            } finally {
-                value.close();
-            }
+            return createValueImpl(value);
         } catch (IOException e) {
             return new ErrorValue(e, PropertyType.BINARY);
         }
@@ -112,7 +111,14 @@ public class ValueFactoryImpl implements
     @Override
     public Value createValue(Binary value) {
         try {
-            return createValueImpl(value.getStream());
+            ValueImpl binaryValue = null;
+            if (value instanceof BinaryImpl) {
+                binaryValue = ((BinaryImpl) value).getBinaryValue();
+            }
+            // No need to create the value again if we have it already underlying the binary
+            return binaryValue == null
+                ? createValueImpl(value.getStream())
+                : binaryValue;
         } catch (RepositoryException e) {
             return new ErrorValue(e, PropertyType.BINARY);
         } catch (IOException e) {
@@ -248,12 +254,8 @@ public class ValueFactoryImpl implements
     }
 
     private ValueImpl createValueImpl(InputStream value) throws IOException {
-        try {
-            // TODO add streaming capability to ContentSession via KernelBasedBlob
-            return new ValueImpl(PropertyStates.binaryProperty("", ByteStreams.toByteArray(value)), namePathMapper);
-        } finally {
-            value.close();
-        }
+        Blob blob = contentSession.createBlob(value);
+        return new ValueImpl(PropertyStates.binaryProperty("", blob), namePathMapper);
     }
 
     //------------------------------------------------------------< ErrorValue >---

Modified: jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java?rev=1397576&r1=1397575&r2=1397576&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/SessionDelegate.java Fri Oct 12 14:21:53 2012
@@ -96,7 +96,7 @@ public class SessionDelegate {
         this.session = new SessionImpl(this);
         this.idManager = new IdentifierManager(root);
         this.namePathMapper = new NamePathMapperImpl(new SessionNameMapper(this), idManager);
-        this.valueFactory = new ValueFactoryImpl(namePathMapper);
+        this.valueFactory = new ValueFactoryImpl(contentSession, namePathMapper);
     }
 
     /**