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();