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 2016/04/20 12:05:07 UTC

svn commit: r1740097 - in /jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment: RecordId.java RecordWriters.java SegmentNodeState.java SegmentTracker.java SegmentWriter.java file/FileStore.java

Author: mduerig
Date: Wed Apr 20 10:05:07 2016
New Revision: 1740097

URL: http://svn.apache.org/viewvc?rev=1740097&view=rev
Log:
OAK-3348: Cross gc sessions might introduce references to pre-compacted segments
Better ids for segment node states: use the record id of the node state itself when initially written

Modified:
    jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/RecordId.java
    jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/RecordWriters.java
    jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java
    jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java
    jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java
    jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java

Modified: jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/RecordId.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/RecordId.java?rev=1740097&r1=1740096&r2=1740097&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/RecordId.java (original)
+++ jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/RecordId.java Wed Apr 20 10:05:07 2016
@@ -20,6 +20,7 @@ import static com.google.common.base.Pre
 import static com.google.common.base.Preconditions.checkNotNull;
 import static java.lang.Integer.parseInt;
 import static org.apache.jackrabbit.oak.plugins.segment.Segment.RECORD_ALIGN_BITS;
+import static org.apache.jackrabbit.oak.plugins.segment.Segment.encode;
 
 import java.util.UUID;
 import java.util.regex.Matcher;
@@ -88,6 +89,25 @@ public final class RecordId implements C
         return segmentId.getSegment();
     }
 
+    private static void writeLong(byte[] buffer, int pos, long value) {
+        for (int k = 0; k < 8; k++) {
+            buffer[pos + k] = (byte) (value >> (56 - (k << 3)));
+        }
+    }
+
+    private static void writeShort(byte[] buffer, int pos, short value) {
+        buffer[pos] = (byte) (value >> 8);
+        buffer[pos + 1] = (byte) value;
+    }
+
+    byte[] toArray() {
+        byte[] buffer = new byte[18];
+        writeLong(buffer, 0, segmentId.getMostSignificantBits());
+        writeLong(buffer, 8, segmentId.getLeastSignificantBits());
+        writeShort(buffer, 16, encode(offset));
+        return buffer;
+    }
+
     //--------------------------------------------------------< Comparable >--
 
     @Override

Modified: jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/RecordWriters.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/RecordWriters.java?rev=1740097&r1=1740096&r2=1740097&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/RecordWriters.java (original)
+++ jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/RecordWriters.java Wed Apr 20 10:05:07 2016
@@ -29,6 +29,7 @@ import static org.apache.jackrabbit.oak.
 import static org.apache.jackrabbit.oak.plugins.segment.RecordType.NODE;
 import static org.apache.jackrabbit.oak.plugins.segment.RecordType.TEMPLATE;
 import static org.apache.jackrabbit.oak.plugins.segment.RecordType.VALUE;
+import static org.apache.jackrabbit.oak.plugins.segment.Segment.RECORD_ID_BYTES;
 import static org.apache.jackrabbit.oak.plugins.segment.Segment.SMALL_LIMIT;
 import static org.apache.jackrabbit.oak.plugins.segment.SegmentVersion.V_11;
 
@@ -137,8 +138,8 @@ final class RecordWriters {
             childNameId, propNamesId, version);
     }
 
-    public static RecordWriter newNodeStateWriter(List<RecordId> ids) {
-        return new NodeStateWriter(ids);
+    public static RecordWriter newNodeStateWriter(RecordId nodeId, List<RecordId> ids) {
+        return new NodeStateWriter(nodeId, ids);
     }
 
     /**
@@ -496,13 +497,21 @@ final class RecordWriters {
      * @see RecordType#NODE
      */
     private static class NodeStateWriter extends RecordWriter {
-        private NodeStateWriter(List<RecordId> ids) {
-            super(NODE, 0, ids);
+        private final RecordId nodeId;
+
+        private NodeStateWriter(RecordId nodeId, List<RecordId> ids) {
+            super(NODE, RECORD_ID_BYTES, ids);
+            this.nodeId = nodeId;
         }
 
         @Override
-        protected RecordId writeRecordContent(RecordId id,
-                SegmentBufferWriter writer) {
+        protected RecordId writeRecordContent(RecordId id, SegmentBufferWriter writer) {
+            if (nodeId == null) {
+                writer.writeRecordId(id);
+            } else {
+                writer.writeRecordId(nodeId);
+            }
+
             for (RecordId recordId : ids) {
                 writer.writeRecordId(recordId);
             }

Modified: jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java?rev=1740097&r1=1740096&r2=1740097&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java (original)
+++ jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java Wed Apr 20 10:05:07 2016
@@ -31,11 +31,14 @@ import static org.apache.jackrabbit.oak.
 import static org.apache.jackrabbit.oak.api.Type.STRINGS;
 import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
 import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.MISSING_NODE;
+import static org.apache.jackrabbit.oak.plugins.segment.Segment.decode;
+import static org.apache.jackrabbit.oak.plugins.segment.Segment.readString;
 import static org.apache.jackrabbit.oak.plugins.segment.SegmentVersion.V_11;
 import static org.apache.jackrabbit.oak.spi.state.AbstractNodeState.checkValidName;
 
 import java.util.Collections;
 import java.util.List;
+import java.util.UUID;
 
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
@@ -86,9 +89,18 @@ public class SegmentNodeState extends Re
         return segment.readMap(segment.readRecordId(getOffset(0, 2)));
     }
 
-    public String getId() {
+    String getId() {
         RecordId id = getSegment().readRecordId(getOffset());
-        return Segment.readString(id);
+        if (id.equals(getRecordId())) {
+            return id.toString10();
+        } else {
+            Segment segment = id.getSegment();
+            int pos = id.getOffset();
+            long msb = segment.readLong(pos);
+            long lsb = segment.readLong(pos + 8);
+            int offset = decode(segment.readShort(pos + 16));
+            return new UUID(msb, lsb) + ":" + offset;
+        }
     }
 
     @Override
@@ -295,7 +307,7 @@ public class SegmentNodeState extends Re
         } else {
             id = getRecordIdV10(segment, template, propertyTemplate);
         }
-        return Segment.readString(id);
+        return readString(id);
     }
 
     /**
@@ -346,13 +358,13 @@ public class SegmentNodeState extends Re
 
         id = segment.readRecordId(id.getOffset() + 4);
         if (size == 1) {
-            return singletonList(Segment.readString(id));
+            return singletonList(readString(id));
         }
 
         List<String> values = newArrayListWithCapacity(size);
         ListRecord list = new ListRecord(id, size);
         for (RecordId value : list.getEntries()) {
-            values.add(Segment.readString(value));
+            values.add(readString(value));
         }
         return values;
     }

Modified: jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java?rev=1740097&r1=1740096&r2=1740097&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java (original)
+++ jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentTracker.java Wed Apr 20 10:05:07 2016
@@ -19,7 +19,6 @@ package org.apache.jackrabbit.oak.plugin
 import static com.google.common.collect.Queues.newArrayDeque;
 import static com.google.common.collect.Sets.newHashSet;
 import static java.lang.Boolean.getBoolean;
-import static java.lang.String.valueOf;
 
 import java.io.IOException;
 import java.security.SecureRandom;
@@ -27,7 +26,6 @@ import java.util.Queue;
 import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
 
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
@@ -147,17 +145,6 @@ public class SegmentTracker {
             .build();
     }
 
-    private final AtomicLong nextId = new AtomicLong();
-
-    public void setInitialId(long id) {
-        nextId.set(id);
-    }
-
-    String createId() {
-        AtomicLong nextId = this.nextId;
-        return valueOf(nextId.getAndIncrement());
-    }
-
     public SegmentTracker(SegmentStore store, SegmentVersion version) {
         this(store, DEFAULT_MEMORY_CACHE_SIZE, version);
     }

Modified: jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java?rev=1740097&r1=1740096&r2=1740097&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java (original)
+++ jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java Wed Apr 20 10:05:07 2016
@@ -810,12 +810,6 @@ public class SegmentWriter {
             }
 
             List<RecordId> ids = newArrayList();
-            if (state instanceof SegmentNodeState) {
-                ids.add(writeString(((SegmentNodeState) state).getId()));
-            } else {
-                ids.add(writeString(store.getTracker().createId()));
-            }
-
             Template template = new Template(state);
             if (template.equals(beforeTemplate)) {
                 ids.add(before.getTemplateId());
@@ -886,7 +880,13 @@ public class SegmentWriter {
                     ids.addAll(pIds);
                 }
             }
-            return newNodeStateWriter(ids).write(writer);
+
+            RecordId nodeId = null;
+            if (state instanceof SegmentNodeState) {
+                byte[] id = ((Record) state).getRecordId().toArray();
+                nodeId = writeBlock(id, 0, id.length);
+            }
+            return newNodeStateWriter(nodeId, ids).write(writer);
         }
 
         private boolean hasSegment(SegmentNodeState node) {

Modified: jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java?rev=1740097&r1=1740096&r2=1740097&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java (original)
+++ jackrabbit/oak/trunk/oak-segment-next/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java Wed Apr 20 10:05:07 2016
@@ -24,7 +24,6 @@ import static com.google.common.collect.
 import static com.google.common.collect.Maps.newHashMap;
 import static com.google.common.collect.Maps.newLinkedHashMap;
 import static com.google.common.collect.Sets.newHashSet;
-import static java.lang.Long.parseLong;
 import static java.lang.String.format;
 import static java.lang.Thread.currentThread;
 import static java.util.Collections.emptyMap;
@@ -476,7 +475,6 @@ public class FileStore implements Segmen
         }
 
         if (id != null) {
-            tracker.setInitialId(1 + parseLong(new SegmentNodeState(id).getId()));
             head = new AtomicReference<RecordId>(id);
             persistedHead = new AtomicReference<RecordId>(id);
         } else {