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/10/19 08:37:25 UTC

svn commit: r1765555 - in /jackrabbit/oak/trunk/oak-segment-tar/src: main/java/org/apache/jackrabbit/oak/segment/MutableRecordNumbers.java test/java/org/apache/jackrabbit/oak/segment/MutableRecordNumbersTest.java

Author: mduerig
Date: Wed Oct 19 08:37:25 2016
New Revision: 1765555

URL: http://svn.apache.org/viewvc?rev=1765555&view=rev
Log:
OAK-4953: Optimise MutableRecordNumbers
Array based implementation of recordNumbers (aka DIY memory management)

Modified:
    jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/MutableRecordNumbers.java
    jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/MutableRecordNumbersTest.java

Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/MutableRecordNumbers.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/MutableRecordNumbers.java?rev=1765555&r1=1765554&r2=1765555&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/MutableRecordNumbers.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/MutableRecordNumbers.java Wed Oct 19 08:37:25 2016
@@ -17,48 +17,74 @@
 
 package org.apache.jackrabbit.oak.segment;
 
+import static java.util.Arrays.copyOf;
+import static java.util.Arrays.fill;
+
 import java.util.Iterator;
-import java.util.Map;
 
-import com.google.common.collect.Maps;
+import com.google.common.collect.AbstractIterator;
 
 /**
  * A thread-safe, mutable record table.
  */
 class MutableRecordNumbers implements RecordNumbers {
+    private int[] recordEntries;
+    private int size;
 
-    private final Object lock = new Object();
-
-    private final Map<Integer, RecordEntry> records = Maps.newLinkedHashMap();
+    public MutableRecordNumbers() {
+        recordEntries = new int[16384];
+        fill(recordEntries, -1);
+    }
 
     @Override
     public int getOffset(int recordNumber) {
-        RecordEntry entry = records.get(recordNumber);
-
-        if (entry != null) {
-            return entry.getOffset();
-        }
-
-        synchronized (lock) {
-            entry = records.get(recordNumber);
-
-            if (entry != null) {
-                return entry.getOffset();
+        int recordEntry;
+        recordEntry = recordNumber * 2 >= recordEntries.length
+            ? -1
+            : recordEntries[recordNumber * 2];
+
+        if (recordEntry == -1) {
+            synchronized (this) {
+                recordEntry = recordEntries[recordNumber * 2];
             }
-
-            return -1;
         }
+        return recordEntry;
     }
 
     @Override
-    public Iterator<Entry> iterator() {
-        Map<Integer, RecordEntry> recordNumbers;
-
-        synchronized (lock) {
-            recordNumbers = Maps.newLinkedHashMap(this.records);
-        }
-
-        return new RecordNumbersIterator(recordNumbers.entrySet().iterator());
+    public synchronized Iterator<Entry> iterator() {
+        return new AbstractIterator<Entry>() {
+            int[] entries = copyOf(recordEntries, size * 2);
+            int index = 0;
+
+            @Override
+            protected Entry computeNext() {
+                if (index < entries.length) {
+                    return new Entry() {
+                        final int recordNumber = index/2;
+                        final int offset = entries[index++];
+                        final RecordType type = RecordType.values()[entries[index++]];
+
+                        @Override
+                        public int getRecordNumber() {
+                            return recordNumber;
+                        }
+
+                        @Override
+                        public int getOffset() {
+                            return offset;
+                        }
+
+                        @Override
+                        public RecordType getType() {
+                            return type;
+                        }
+                    };
+                } else {
+                    return endOfData();
+                }
+            }
+        };
     }
 
     /**
@@ -66,10 +92,8 @@ class MutableRecordNumbers implements Re
      *
      * @return the size of this table.
      */
-    public int size() {
-        synchronized (lock) {
-            return records.size();
-        }
+    public synchronized int size() {
+        return size;
     }
 
     /**
@@ -79,15 +103,14 @@ class MutableRecordNumbers implements Re
      * @param offset an offset to be added to this table.
      * @return the record number associated to the offset.
      */
-    int addRecord(RecordType type, int offset) {
-        int recordNumber;
-
-        synchronized (lock) {
-            recordNumber = records.size();
-            records.put(recordNumber, new RecordEntry(type, offset));
+    synchronized int addRecord(RecordType type, int offset) {
+        if (recordEntries.length <= size * 2) {
+            recordEntries = copyOf(recordEntries, recordEntries.length * 2);
+            fill(recordEntries, recordEntries.length/2, recordEntries.length, -1);
         }
-
-        return recordNumber;
+        recordEntries[2 * size] = offset;
+        recordEntries[2 * size + 1] = type.ordinal();
+        return size++;
     }
 
 }

Modified: jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/MutableRecordNumbersTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/MutableRecordNumbersTest.java?rev=1765555&r1=1765554&r2=1765555&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/MutableRecordNumbersTest.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/MutableRecordNumbersTest.java Wed Oct 19 08:37:25 2016
@@ -53,7 +53,7 @@ public class MutableRecordNumbersTest {
 
         Map<Integer, Integer> expected = new HashMap<>();
 
-        for (int i = 0; i < 10; i++) {
+        for (int i = 0; i < 100000; i++) {
             expected.put(table.addRecord(RecordType.VALUE, i), i);
         }