Author: frm Date: Tue Oct 18 09:14:49 2016 New Revision: 1765404 URL: http://svn.apache.org/viewvc?rev=1765404&view=rev Log: OAK-4946 - Introduce a record type for external binary IDs
Added: jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/BlobIdRecordTest.java (with props) Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/RecordType.java jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/RecordWriters.java Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/RecordType.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/RecordType.java?rev=1765404&r1=1765403&r2=1765404&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/RecordType.java (original) +++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/RecordType.java Tue Oct 18 09:14:49 2016 @@ -123,6 +123,11 @@ public enum RecordType { * pointer to the list record)</li> * </ul> */ - NODE + NODE, + + /** + * A reference to an external binary object. + */ + BLOB_ID, } Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/RecordWriters.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/RecordWriters.java?rev=1765404&r1=1765403&r2=1765404&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/RecordWriters.java (original) +++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/RecordWriters.java Tue Oct 18 09:14:49 2016 @@ -23,6 +23,7 @@ import static com.google.common.collect. import static java.util.Arrays.sort; import static java.util.Collections.singleton; import static org.apache.jackrabbit.oak.segment.MapRecord.SIZE_BITS; +import static org.apache.jackrabbit.oak.segment.RecordType.BLOB_ID; import static org.apache.jackrabbit.oak.segment.RecordType.BLOCK; import static org.apache.jackrabbit.oak.segment.RecordType.BRANCH; import static org.apache.jackrabbit.oak.segment.RecordType.BUCKET; @@ -381,13 +382,13 @@ final class RecordWriters { * {@code Segment#BLOB_ID_SMALL_LIMIT}. * * @see Segment#BLOB_ID_SMALL_LIMIT - * @see RecordType#VALUE + * @see RecordType#BLOB_ID */ private static class LargeBlobIdWriter extends RecordWriter { private final RecordId stringRecord; private LargeBlobIdWriter(RecordId stringRecord) { - super(VALUE, 1, stringRecord); + super(BLOB_ID, 1, stringRecord); this.stringRecord = stringRecord; } @@ -408,13 +409,13 @@ final class RecordWriters { * its binary representation is less than {@code Segment#BLOB_ID_SMALL_LIMIT}. * @see Segment#BLOB_ID_SMALL_LIMIT - * @see RecordType#VALUE + * @see RecordType#BLOB_ID */ private static class SmallBlobIdWriter extends RecordWriter { private final byte[] blobId; private SmallBlobIdWriter(byte[] blobId) { - super(VALUE, 2 + blobId.length); + super(BLOB_ID, 2 + blobId.length); checkArgument(blobId.length < Segment.BLOB_ID_SMALL_LIMIT); this.blobId = blobId; } Added: jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/BlobIdRecordTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/BlobIdRecordTest.java?rev=1765404&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/BlobIdRecordTest.java (added) +++ jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/BlobIdRecordTest.java Tue Oct 18 09:14:49 2016 @@ -0,0 +1,157 @@ +/* + * 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.segment; + +import static org.apache.jackrabbit.oak.segment.SegmentWriterBuilder.segmentWriterBuilder; +import static org.apache.jackrabbit.oak.segment.file.FileStoreBuilder.fileStoreBuilder; +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +import javax.annotation.Nonnull; + +import com.google.common.base.Strings; +import org.apache.jackrabbit.oak.plugins.memory.ArrayBasedBlob; +import org.apache.jackrabbit.oak.segment.Segment.RecordConsumer; +import org.apache.jackrabbit.oak.segment.file.FileStore; +import org.apache.jackrabbit.oak.spi.blob.BlobStore; +import org.apache.jackrabbit.oak.spi.blob.MemoryBlobStore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +public class BlobIdRecordTest { + + private static abstract class IdMappingBlobStore implements BlobStore { + + private final MemoryBlobStore bs = new MemoryBlobStore(); + + private final Map<String, String> ids = new HashMap<>(); + + @Override + public String writeBlob(InputStream inputStream) throws IOException { + String in = bs.writeBlob(inputStream); + String out = generateId(); + ids.put(out, in); + return out; + } + + @Override + public int readBlob(String s, long l, byte[] bytes, int i, int i1) throws IOException { + return bs.readBlob(mapId(s), l, bytes, i, i1); + } + + @Override + public long getBlobLength(String s) throws IOException { + return bs.getBlobLength(mapId(s)); + } + + @Override + public InputStream getInputStream(String s) throws IOException { + return bs.getInputStream(mapId(s)); + } + + @Override + public String getBlobId(@Nonnull String s) { + return bs.getBlobId(s); + } + + @Override + public String getReference(@Nonnull String s) { + return bs.getBlobId(mapId(s)); + } + + private String mapId(String in) { + String out = ids.get(in); + if (out == null) { + throw new IllegalArgumentException("in"); + } + return out; + } + + protected abstract String generateId(); + + } + + private static class ShortIdMappingBlobStore extends IdMappingBlobStore { + + private static int next; + + @Override + protected String generateId() { + return Integer.toString(next++); + } + + } + + private static class LongIdMappingBlobStore extends IdMappingBlobStore { + + private static int next; + + @Override + protected String generateId() { + return Strings.repeat("0", Segment.BLOB_ID_SMALL_LIMIT) + Integer.toString(next++); + } + + } + + @Rule + public TemporaryFolder folder = new TemporaryFolder(new File("target")); + + @Test + public void shortReferencesShouldHaveBlobIdType() throws Exception { + try (FileStore ss = newFileStore(new ShortIdMappingBlobStore())) { + SegmentWriter sw = segmentWriterBuilder("test").build(ss); + byte[] content = new byte[Segment.MEDIUM_LIMIT + 1]; + SegmentBlob sb = sw.writeBlob(new ArrayBasedBlob(content)); + assertRecordTypeEquals(sb, RecordType.BLOB_ID); + } + } + + @Test + public void longReferencesShouldHaveBlobIdType() throws Exception { + try (FileStore ss = newFileStore(new LongIdMappingBlobStore())) { + SegmentWriter sw = segmentWriterBuilder("test").build(ss); + byte[] content = new byte[Segment.MEDIUM_LIMIT + 1]; + SegmentBlob sb = sw.writeBlob(new ArrayBasedBlob(content)); + assertRecordTypeEquals(sb, RecordType.BLOB_ID); + } + } + + private FileStore newFileStore(BlobStore blobStore) throws Exception { + return fileStoreBuilder(folder.newFolder("ss")).withBlobStore(blobStore).build(); + } + + private void assertRecordTypeEquals(final Record record, final RecordType expected) { + record.getSegment().forEachRecord(new RecordConsumer() { + + @Override + public void consume(int number, RecordType type, int offset) { + if (number == record.getRecordNumber()) { + assertEquals(expected, type); + } + } + + }); + } + +} Propchange: jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/BlobIdRecordTest.java ------------------------------------------------------------------------------ svn:eol-style = native