Author: mduerig
Date: Wed Oct 19 08:37:12 2016
New Revision: 1765553
URL: http://svn.apache.org/viewvc?rev=1765553&view=rev
Log:
OAK-4923: Improve segment deserialization performance
Load (and cache) segment references lazyly
Removed:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/ImmutableSegmentReferences.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/ImmutableSegmentReferencesTest.java
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Segment.java
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Segment.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Segment.java?rev=1765553&r1=1765552&r2=1765553&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Segment.java
(original)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/Segment.java
Wed Oct 19 08:37:12 2016
@@ -18,10 +18,10 @@
*/
package org.apache.jackrabbit.oak.segment;
+import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkPositionIndexes;
import static com.google.common.base.Preconditions.checkState;
-import static com.google.common.collect.Lists.newArrayListWithCapacity;
import static com.google.common.collect.Maps.newLinkedHashMap;
import static org.apache.jackrabbit.oak.commons.IOUtils.closeQuietly;
import static org.apache.jackrabbit.oak.segment.SegmentId.isDataSegmentId;
@@ -37,7 +37,7 @@ import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.WritableByteChannel;
import java.util.Arrays;
-import java.util.List;
+import java.util.Iterator;
import java.util.Map;
import java.util.UUID;
@@ -45,6 +45,7 @@ import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import com.google.common.base.Charsets;
+import com.google.common.collect.AbstractIterator;
import org.apache.commons.io.HexDump;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.jackrabbit.oak.api.PropertyState;
@@ -248,21 +249,44 @@ public class Segment {
checkState(getReferencedSegmentIdCount() + 1 < 0xffff,
"Segment cannot have more than 0xffff references");
- List<SegmentId> referencedSegments =
newArrayListWithCapacity(getReferencedSegmentIdCount());
-
- int position = data.position();
-
- position += HEADER_SIZE;
-
- for (int i = 0; i < getReferencedSegmentIdCount(); i++) {
- long msb = data.getLong(position);
- position += 8;
- long lsb = data.getLong(position);
- position += 8;
- referencedSegments.add(store.newSegmentId(msb, lsb));
- }
-
- return new ImmutableSegmentReferences(referencedSegments);
+ final int referencedSegmentIdCount = getReferencedSegmentIdCount();
+ final int refOffset = data.position() + HEADER_SIZE;
+ final SegmentId[] refIds = new SegmentId[referencedSegmentIdCount];
+ return new SegmentReferences() {
+ @Override
+ public SegmentId getSegmentId(int reference) {
+ checkArgument(reference <= referencedSegmentIdCount);
+ SegmentId id = refIds[reference - 1];
+ if (id == null) {
+ synchronized(refIds) {
+ id = refIds[reference - 1];
+ if (id == null) {
+ int position = refOffset + (reference - 1) *
SEGMENT_REFERENCE_SIZE;
+ long msb = data.getLong(position);
+ long lsb = data.getLong(position + 8);
+ id = store.newSegmentId(msb, lsb);
+ refIds[reference - 1] = id;
+ }
+ }
+ }
+ return id;
+ }
+
+ @Override
+ public Iterator<SegmentId> iterator() {
+ return new AbstractIterator<SegmentId>() {
+ private int reference = 1;
+ @Override
+ protected SegmentId computeNext() {
+ if (reference <= referencedSegmentIdCount) {
+ return getSegmentId(reference++);
+ } else {
+ return endOfData();
+ }
+ }
+ };
+ }
+ };
}
Segment(@Nonnull SegmentStore store,