Index: oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/MutableRecordNumbers.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/MutableRecordNumbers.java (date 1476352382000) +++ oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/MutableRecordNumbers.java (date 1476721152000) @@ -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 records = Maps.newLinkedHashMap(); + public MutableRecordNumbers() { + recordEntries = new int[16384]; + fill(recordEntries, -1); + } @Override public int getOffset(int recordNumber) { - RecordEntry entry = records.get(recordNumber); + int recordEntry; + recordEntry = recordNumber * 2 >= recordEntries.length + ? -1 + : recordEntries[recordNumber * 2]; - if (entry != null) { - return entry.getOffset(); - } - - synchronized (lock) { - entry = records.get(recordNumber); - - if (entry != null) { - return entry.getOffset(); + if (recordEntry == -1) { + synchronized (this) { + recordEntry = recordEntries[recordNumber * 2]; } - - return -1; } + return recordEntry; } @Override - public Iterator iterator() { - Map recordNumbers; + public synchronized Iterator iterator() { + return new AbstractIterator() { + int[] entries = copyOf(recordEntries, size * 2); + int index = 0; - synchronized (lock) { - recordNumbers = Maps.newLinkedHashMap(this.records); - } + @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; + } - return new RecordNumbersIterator(recordNumbers.entrySet().iterator()); + @Override + public int getOffset() { + return offset; + } + + @Override + public RecordType getType() { + return type; + } + }; + } else { + return endOfData(); + } + } + }; } /** @@ -66,10 +92,8 @@ * * @return the size of this table. */ - public int size() { - synchronized (lock) { - return records.size(); - } + public synchronized int size() { + return size; } /** @@ -79,15 +103,14 @@ * @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++; } } Index: oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/MutableRecordNumbersTest.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/MutableRecordNumbersTest.java (date 1476352382000) +++ oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/MutableRecordNumbersTest.java (date 1476721152000) @@ -53,7 +53,7 @@ Map 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); }