jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ju...@apache.org
Subject svn commit: r1527267 - in /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment: MapBranch.java MapLeaf.java MapRecord.java Record.java Segment.java SegmentWriter.java Template.java
Date Sun, 29 Sep 2013 03:08:50 GMT
Author: jukka
Date: Sun Sep 29 03:08:48 2013
New Revision: 1527267

URL: http://svn.apache.org/r1527267
Log:
OAK-1031: SegmentMK: Fewer segment lookups

Cache map records and the string keys of map leaves

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapBranch.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapLeaf.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapRecord.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Record.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Segment.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Template.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapBranch.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapBranch.java?rev=1527267&r1=1527266&r2=1527267&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapBranch.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapBranch.java
Sun Sep 29 03:08:48 2013
@@ -34,6 +34,13 @@ class MapBranch extends MapRecord {
 
     private final int bitmap;
 
+    MapBranch(Segment segment, int offset, int size, int level, int bitmap) {
+        super(segment, offset, size, level);
+        checkArgument(size > BUCKETS_PER_LEVEL);
+        checkArgument(level < MAX_NUMBER_OF_LEVELS);
+        this.bitmap = bitmap;
+    }
+
     MapBranch(Segment segment, RecordId id, int size, int level, int bitmap) {
         super(segment, id, size, level);
         checkArgument(size > BUCKETS_PER_LEVEL);
@@ -70,7 +77,7 @@ class MapBranch extends MapRecord {
             int bytes = 8;
             int ids = bitCount(bitmap & (bit - 1));
             RecordId id = segment.readRecordId(getOffset(bytes, ids));
-            return MapRecord.readMap(segment, id).getEntry(key);
+            return segment.readMap(id).getEntry(key);
         } else {
             return null;
         }
@@ -85,7 +92,7 @@ class MapBranch extends MapRecord {
                     @Override @Nullable
                     public Iterable<String> apply(@Nullable RecordId input) {
                         if (input != null) {
-                            return MapRecord.readMap(segment, input).getKeys();
+                            return segment.readMap(input).getKeys();
                         } else {
                             return Collections.emptyList();
                         }
@@ -102,7 +109,7 @@ class MapBranch extends MapRecord {
                     @Override @Nullable
                     public Iterable<MapEntry> apply(@Nullable RecordId input) {
                         if (input != null) {
-                            return MapRecord.readMap(segment, input).getEntries();
+                            return segment.readMap(input).getEntries();
                         } else {
                             return Collections.emptyList();
                         }
@@ -130,7 +137,7 @@ class MapBranch extends MapRecord {
         for (int i = 0; i < BUCKETS_PER_LEVEL; i++) {
             if (afterBuckets[i] == null) {
                 if (beforeBuckets[i] != null) {
-                    MapRecord map = MapRecord.readMap(beforeSegment, beforeBuckets[i]);
+                    MapRecord map = beforeSegment.readMap(beforeBuckets[i]);
                     for (MapEntry entry : map.getEntries()) {
                         if (!diff.entryDeleted(entry.getName(), entry.getValue())) {
                             return false;
@@ -138,15 +145,15 @@ class MapBranch extends MapRecord {
                     }
                 }
             } else if (beforeBuckets[i] == null) {
-                MapRecord map = MapRecord.readMap(afterSegment, afterBuckets[i]);
+                MapRecord map = afterSegment.readMap(afterBuckets[i]);
                 for (MapEntry entry : map.getEntries()) {
                     if (!diff.entryAdded(entry.getName(), entry.getValue())) {
                         return false;
                     }
                 }
             } else if (!afterBuckets[i].equals(beforeBuckets[i])) {
-                MapRecord afterMap = MapRecord.readMap(afterSegment, afterBuckets[i]);
-                MapRecord beforeMap = MapRecord.readMap(beforeSegment, beforeBuckets[i]);
+                MapRecord afterMap = afterSegment.readMap(afterBuckets[i]);
+                MapRecord beforeMap = beforeSegment.readMap(beforeBuckets[i]);
                 if (!afterMap.compare(beforeMap, diff)) {
                     return false;
                 }
@@ -163,8 +170,8 @@ class MapBranch extends MapRecord {
         int ids = 0;
         for (int i = 0; i < BUCKETS_PER_LEVEL; i++) {
             if ((bitmap & (1 << i)) != 0) {
-                MapRecord bucket = MapRecord.readMap(
-                        segment, segment.readRecordId(getOffset(bytes, ids++)));
+                MapRecord bucket = segment.readMap(
+                        segment.readRecordId(getOffset(bytes, ids++)));
                 if (!bucket.compareAgainstEmptyMap(diff)) {
                     return false;
                 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapLeaf.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapLeaf.java?rev=1527267&r1=1527266&r2=1527267&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapLeaf.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapLeaf.java
Sun Sep 29 03:08:48 2013
@@ -18,7 +18,6 @@ package org.apache.jackrabbit.oak.plugin
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
-import static org.apache.jackrabbit.oak.plugins.segment.Segment.RECORD_ID_BYTES;
 
 import java.util.Iterator;
 import java.util.Map;
@@ -28,10 +27,20 @@ import com.google.common.collect.Maps;
 
 class MapLeaf extends MapRecord {
 
+    private final String[] keys;
+
+    MapLeaf(Segment segment, int offset, int size, int level) {
+        super(segment, offset, size, level);
+        checkArgument(size != 0 || level == 0);
+        checkArgument(size <= BUCKETS_PER_LEVEL || level == MAX_NUMBER_OF_LEVELS);
+        this.keys = new String[size];
+    }
+
     MapLeaf(Segment segment, RecordId id, int size, int level) {
         super(segment, id, size, level);
         checkArgument(size != 0 || level == 0);
         checkArgument(size <= BUCKETS_PER_LEVEL || level == MAX_NUMBER_OF_LEVELS);
+        this.keys = new String[size];
     }
 
     Map<String, MapEntry> getMapEntries() {
@@ -50,7 +59,7 @@ class MapLeaf extends MapRecord {
 
         Map<String, MapEntry> entries = Maps.newHashMapWithExpectedSize(size);
         for (int i = 0; i < size; i++) {
-            String name = segment.readString(keys[i]);
+            String name = getKey(segment, i, keys[i]);
             entries.put(name, new MapEntry(segment, name, keys[i], values[i]));
         }
         return entries;
@@ -86,7 +95,6 @@ class MapLeaf extends MapRecord {
             public Iterator<String> iterator() {
                 return getKeyIterator();
             }
-
         };
     }
 
@@ -159,12 +167,10 @@ class MapLeaf extends MapRecord {
     public boolean compareAgainstEmptyMap(MapDiff diff) {
         Segment segment = getSegment();
 
-        int keyOffset = getOffset() + 4 + size * 4;
-        int valueOffset = keyOffset + size * RECORD_ID_BYTES;
         for (int i = 0; i < size; i++) {
-            RecordId key = segment.readRecordId(keyOffset + i * RECORD_ID_BYTES);
-            RecordId value = segment.readRecordId(valueOffset + i * RECORD_ID_BYTES);
-            if (!diff.entryAdded(segment.readString(key), value)) {
+            RecordId key = segment.readRecordId(getOffset(4 + size * 4, i));
+            RecordId value = segment.readRecordId(getOffset(4 + size * 4, size + i));
+            if (!diff.entryAdded(getKey(segment, i, key), value)) {
                 return false;
             }
         }
@@ -202,16 +208,25 @@ class MapLeaf extends MapRecord {
         return checkNotNull(segment).readInt(getOffset() + 4 + index * 4);
     }
 
-    private String getKey(Segment segment, int index) {
+    private synchronized String getKey(Segment segment, int index) {
         checkNotNull(segment);
-        int offset = getOffset() + 4 + size * 4 + index * RECORD_ID_BYTES;
-        return segment.readString(segment.readRecordId(offset));
+        if (keys[index] == null) {
+            int offset = getOffset(4 + size * 4, index);
+            keys[index] = segment.readString(segment.readRecordId(offset));
+        }
+        return keys[index];
+    }
+
+    private synchronized String getKey(Segment segment, int index, RecordId id) {
+        checkNotNull(segment);
+        if (keys[index] == null) {
+            keys[index] = segment.readString(id);
+        }
+        return keys[index];
     }
 
     private RecordId getValue(Segment segment, int index) {
-        int offset = getOffset()
-                + 4 + size * 4 + size * RECORD_ID_BYTES
-                + index * RECORD_ID_BYTES;
+        int offset = getOffset(4 + size * 4, size + index);
         return checkNotNull(segment).readRecordId(offset);
     }
 

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapRecord.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapRecord.java?rev=1527267&r1=1527266&r2=1527267&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapRecord.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MapRecord.java
Sun Sep 29 03:08:48 2013
@@ -17,14 +17,12 @@
 package org.apache.jackrabbit.oak.plugins.segment;
 
 import static com.google.common.base.Preconditions.checkElementIndex;
-import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkPositionIndex;
 import static com.google.common.collect.Sets.newHashSet;
 import static java.lang.Integer.highestOneBit;
 import static java.lang.Integer.numberOfTrailingZeros;
 
 import java.util.Set;
-import java.util.UUID;
 
 abstract class MapRecord extends Record {
 
@@ -60,24 +58,16 @@ abstract class MapRecord extends Record 
      */
     protected static final int MAX_SIZE = (1 << SIZE_BITS) - 1; // ~268e6
 
-    static MapRecord readMap(Segment segment, RecordId id) {
-        segment = checkNotNull(segment).getSegment(checkNotNull(id));
-        int offset = id.getOffset();
-        int head = segment.readInt(offset);
-        int level = head >>> SIZE_BITS;
-        int size = head & ((1 << SIZE_BITS) - 1);
-        if (size > BUCKETS_PER_LEVEL && level < MAX_NUMBER_OF_LEVELS) {
-            int bitmap = segment.readInt(offset + 4);
-            return new MapBranch(segment, id, size, level, bitmap);
-        } else {
-            return new MapLeaf(segment, id, size, level);
-        }
-    }
-
     protected final int size;
 
     protected final int level;
 
+    protected MapRecord(Segment segment, int offset, int size, int level) {
+        super(segment, offset);
+        this.size = checkElementIndex(size, MAX_SIZE);
+        this.level = checkPositionIndex(level, MAX_NUMBER_OF_LEVELS);
+    }
+
     protected MapRecord(Segment segment, RecordId id, int size, int level) {
         super(segment, id);
         this.size = checkElementIndex(size, MAX_SIZE);

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Record.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Record.java?rev=1527267&r1=1527266&r2=1527267&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Record.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Record.java
Sun Sep 29 03:08:48 2013
@@ -73,6 +73,12 @@ class Record {
         this.offset = id.getOffset();
     }
 
+    protected Record(@Nonnull Segment segment, int offset) {
+        this.segment = checkNotNull(segment);
+        this.uuid = segment.getSegmentId();
+        this.offset = offset;
+    }
+
     // TODO: remove this ugly hack
     protected Record(SegmentStore store, RecordId id) {
         this(new Segment(

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Segment.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Segment.java?rev=1527267&r1=1527266&r2=1527267&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Segment.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Segment.java
Sun Sep 29 03:08:48 2013
@@ -101,6 +101,8 @@ public class Segment {
 
     private final OffsetCache<Template> templates;
 
+    private final OffsetCache<MapRecord> maps;
+
     public Segment(
             SegmentStore store, UUID uuid, ByteBuffer data, List<UUID> uuids) {
         this.store = checkNotNull(store);
@@ -119,6 +121,12 @@ public class Segment {
                 return loadTemplate(offset);
             }
         };
+        this.maps = new OffsetCache<MapRecord>() {
+            @Override
+            protected MapRecord load(int offset) {
+                return loadMap(offset);
+            }
+        };
     }
 
     /**
@@ -253,6 +261,27 @@ public class Segment {
         }
     }
 
+    MapRecord readMap(RecordId id) {
+        return getSegment(id).readMap(id.getOffset());
+    }
+
+    MapRecord readMap(int offset) {
+        return maps.get(offset);
+    }
+
+    private MapRecord loadMap(int offset) {
+        int head = readInt(offset);
+        int level = head >>> MapRecord.SIZE_BITS;
+        int size = head & ((1 << MapRecord.SIZE_BITS) - 1);
+        if (size > MapRecord.BUCKETS_PER_LEVEL
+                && level < MapRecord.MAX_NUMBER_OF_LEVELS) {
+            int bitmap = readInt(offset + 4);
+            return new MapBranch(this, offset, size, level, bitmap);
+        } else {
+            return new MapLeaf(this, offset, size, level);
+        }
+    }
+
     Template readTemplate(RecordId id) {
         return getSegment(id).readTemplate(id.getOffset());
     }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java?rev=1527267&r1=1527266&r2=1527267&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentWriter.java
Sun Sep 29 03:08:48 2013
@@ -288,7 +288,7 @@ public class SegmentWriter {
 
         if (entries == null || entries.isEmpty()) {
             if (baseId != null) {
-                return MapRecord.readMap(dummySegment, baseId);
+                return dummySegment.readMap(baseId);
             } else if (level == 0) {
                 synchronized (this) {
                     RecordId id = prepare(4);
@@ -300,7 +300,7 @@ public class SegmentWriter {
             }
         } else if (baseId != null) {
             // FIXME: messy code with lots of duplication
-            MapRecord base = MapRecord.readMap(dummySegment, baseId);
+            MapRecord base = dummySegment.readMap(baseId);
             if (base instanceof MapLeaf) {
                 Map<String, MapEntry> map = ((MapLeaf) base).getMapEntries();
                 for (MapEntry entry : entries) {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Template.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Template.java?rev=1527267&r1=1527266&r2=1527267&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Template.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Template.java
Sun Sep 29 03:08:48 2013
@@ -279,7 +279,7 @@ public class Template {
         segment = segment.getSegment(recordId);
         int offset = recordId.getOffset() + RECORD_ID_BYTES;
         RecordId childNodesId = segment.readRecordId(offset);
-        return MapRecord.readMap(segment, childNodesId);
+        return segment.readMap(childNodesId);
     }
 
     public boolean hasChildNode(
@@ -562,7 +562,7 @@ public class Template {
 
         if (childName == MANY_CHILD_NODES) {
             RecordId childNodesId = segment.readRecordId(offset);
-            MapRecord children = MapRecord.readMap(segment, childNodesId);
+            MapRecord children = segment.readMap(childNodesId);
             final Segment s = segment;
             children.compareAgainstEmptyMap(new MapDiff() {
                 @Override



Mime
View raw message