Author: tomekr
Date: Tue Apr 26 09:12:20 2016
New Revision: 1740975

URL: http://svn.apache.org/viewvc?rev=1740975&view=rev
Log:
OAK-4307 SegmentWriter saves references to external blobs

Modified:
    
jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/segment/SegmentWriter.java
    
jackrabbit/oak/trunk/oak-segment-next/src/test/java/org/apache/jackrabbit/oak/segment/RecordTest.java

Modified: 
jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/segment/SegmentWriter.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/segment/SegmentWriter.java?rev=1740975&r1=1740974&r2=1740975&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/segment/SegmentWriter.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/segment/SegmentWriter.java
 Tue Apr 26 09:12:20 2016
@@ -608,8 +608,20 @@ public class SegmentWriter {
             boolean threw = true;
             try {
                 RecordId id = SegmentStream.getRecordIdIfAvailable(stream, 
store);
-                if (id == null || isOldGen(id)) {
+                if (id == null) {
+                    // This is either not a segment stream or a one from 
another store:
+                    // fully serialise the stream.
                     id = internalWriteStream(stream);
+                } else if (isOldGen(id)) {
+                    // This is a segment stream from this store but from an 
old generation:
+                    // try to link to the blocks if there are any.
+                    SegmentStream segmentStream = (SegmentStream) stream;
+                    List<RecordId> blockIds = segmentStream.getBlockIds();
+                    if (blockIds == null) {
+                        return internalWriteStream(stream);
+                    } else {
+                        return writeValueRecord(segmentStream.getLength(), 
writeList(blockIds));
+                    }
                 }
                 threw = false;
                 return id;
@@ -619,14 +631,6 @@ public class SegmentWriter {
         }
 
         private RecordId internalWriteStream(InputStream stream) throws 
IOException {
-            if (stream instanceof SegmentStream) {
-                SegmentStream segmentStream = (SegmentStream) stream;
-                List<RecordId> blockIds = segmentStream.getBlockIds();
-                if (blockIds != null) {
-                    return writeValueRecord(segmentStream.getLength(), 
writeList(blockIds));
-                }
-            }
-
             // Special case for short binaries (up to about 16kB):
             // store them directly as small- or medium-sized value records
             byte[] data = new byte[Segment.MEDIUM_LIMIT];

Modified: 
jackrabbit/oak/trunk/oak-segment-next/src/test/java/org/apache/jackrabbit/oak/segment/RecordTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-next/src/test/java/org/apache/jackrabbit/oak/segment/RecordTest.java?rev=1740975&r1=1740974&r2=1740975&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-next/src/test/java/org/apache/jackrabbit/oak/segment/RecordTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-next/src/test/java/org/apache/jackrabbit/oak/segment/RecordTest.java
 Tue Apr 26 09:12:20 2016
@@ -24,6 +24,7 @@ import static java.util.Collections.sing
 import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.fail;
 import static org.apache.jackrabbit.oak.api.Type.BINARIES;
+import static org.apache.jackrabbit.oak.api.Type.BINARY;
 import static org.apache.jackrabbit.oak.api.Type.STRING;
 import static org.apache.jackrabbit.oak.api.Type.STRINGS;
 import static 
org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
@@ -47,16 +48,11 @@ import java.util.Random;
 import com.google.common.base.Charsets;
 import com.google.common.collect.ImmutableMap;
 import org.apache.jackrabbit.oak.api.Blob;
-import org.apache.jackrabbit.oak.segment.BlockRecord;
-import org.apache.jackrabbit.oak.segment.ListRecord;
-import org.apache.jackrabbit.oak.segment.MapEntry;
-import org.apache.jackrabbit.oak.segment.MapRecord;
-import org.apache.jackrabbit.oak.segment.RecordId;
-import org.apache.jackrabbit.oak.segment.Segment;
-import org.apache.jackrabbit.oak.segment.SegmentStore;
-import org.apache.jackrabbit.oak.segment.SegmentTracker;
-import org.apache.jackrabbit.oak.segment.SegmentWriter;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.segment.memory.MemoryStore;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.junit.Test;
@@ -380,6 +376,31 @@ public class RecordTest {
         }
     }
 
+    @Test
+    public void testBinaryPropertyFromExternalSegmentStore() throws 
IOException, CommitFailedException {
+        byte[] data = new byte[Segment.MEDIUM_LIMIT + 1];
+        random.nextBytes(data);
+
+        SegmentNodeStore extStore = SegmentNodeStore.builder(new 
MemoryStore()).build();
+        NodeBuilder extRootBuilder = extStore.getRoot().builder();
+        Blob extBlob = extRootBuilder.createBlob(new 
ByteArrayInputStream(data));
+        extRootBuilder.setProperty("binary", extBlob, BINARY);
+        extStore.merge(extRootBuilder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+        PropertyState extPropertyState = 
extStore.getRoot().getProperty("binary");
+
+        NodeBuilder builder = EMPTY_NODE.builder();
+        builder.setProperty(extPropertyState);
+        NodeState state = writer.writeNode(builder.getNodeState());
+
+        try {
+            InputStream is = 
state.getProperty("binary").getValue(BINARY).getNewStream();
+            is.read();
+            is.close();
+        } catch (SegmentNotFoundException e) {
+            fail("OAK-4307 SegmentWriter saves references to external blobs");
+        }
+    }
+
     @Test
     public void testStringPrimaryType() throws IOException {
         NodeBuilder builder = EMPTY_NODE.builder();


Reply via email to