jackrabbit-oak-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ju...@apache.org
Subject svn commit: r1448610 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/plugins/segment/ test/java/org/apache/jackrabbit/oak/plugins/segment/
Date Thu, 21 Feb 2013 11:48:15 GMT
Author: jukka
Date: Thu Feb 21 11:48:15 2013
New Revision: 1448610

URL: http://svn.apache.org/r1448610
Log:
OAK-632: SegmentMK: Efficient updates of flat nodes

First (messy) draft of HAMT update code

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MemoryStore.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoStore.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreBranch.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
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/CompareAgainstBaseStateTest.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/RecordTest.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentSizeTest.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MemoryStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MemoryStore.java?rev=1448610&r1=1448609&r2=1448610&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MemoryStore.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MemoryStore.java
Thu Feb 21 11:48:15 2013
@@ -16,7 +16,6 @@
  */
 package org.apache.jackrabbit.oak.plugins.segment;
 
-import java.util.Map;
 import java.util.UUID;
 import java.util.concurrent.ConcurrentMap;
 
@@ -34,7 +33,7 @@ public class MemoryStore implements Segm
             Maps.newConcurrentMap();
 
     public MemoryStore(NodeState root) {
-        SegmentWriter writer = new SegmentWriter(this);
+        SegmentWriter writer = new SegmentWriter(this, new SegmentReader(this));
         journals.put("root", writer.writeNode(root));
         writer.flush();
     }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoStore.java?rev=1448610&r1=1448609&r2=1448610&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoStore.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/MongoStore.java
Thu Feb 21 11:48:15 2013
@@ -45,7 +45,7 @@ public class MongoStore implements Segme
         this.cache = cache;
 
         if (journals.findOne(new BasicDBObject("_id", "root")) == null) {
-            SegmentWriter writer = new SegmentWriter(this);
+            SegmentWriter writer = new SegmentWriter(this, new SegmentReader(this));
             RecordId id = writer.writeNode(MemoryNodeState.EMPTY_NODE);
             writer.flush();
             journals.insert(new BasicDBObject(ImmutableMap.of(

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java?rev=1448610&r1=1448609&r2=1448610&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeState.java
Thu Feb 21 11:48:15 2013
@@ -57,6 +57,10 @@ class SegmentNodeState extends AbstractN
         return template;
     }
 
+    MapRecord getChildNodeMap() {
+        return getTemplate().getChildNodeMap(reader, recordId);
+    }
+
     @Override
     public long getPropertyCount() {
         return getTemplate().getPropertyCount();

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java?rev=1448610&r1=1448609&r2=1448610&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java
Thu Feb 21 11:48:15 2013
@@ -56,7 +56,7 @@ public class SegmentNodeStore implements
 
     @Override
     public Blob createBlob(InputStream stream) throws IOException {
-        SegmentWriter writer = new SegmentWriter(store);
+        SegmentWriter writer = new SegmentWriter(store, reader);
         RecordId recordId = writer.writeStream(stream);
         writer.flush();
         return new SegmentBlob(reader, recordId);

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreBranch.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreBranch.java?rev=1448610&r1=1448609&r2=1448610&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreBranch.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStoreBranch.java
Thu Feb 21 11:48:15 2013
@@ -59,7 +59,7 @@ class SegmentNodeStoreBranch implements 
         this.store = store;
         this.journal = journal;
         this.reader = reader;
-        this.writer = new SegmentWriter(store);
+        this.writer = new SegmentWriter(store, reader);
         this.baseId = store.getJournalHead(journal);
         this.rootId = baseId;
     }

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=1448610&r1=1448609&r2=1448610&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
Thu Feb 21 11:48:15 2013
@@ -39,7 +39,9 @@ import javax.jcr.PropertyType;
 import org.apache.jackrabbit.oak.api.Blob;
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.plugins.memory.ModifiedNodeState;
 import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
+import org.apache.jackrabbit.oak.spi.state.DefaultNodeStateDiff;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 
 import com.google.common.base.Charsets;
@@ -53,6 +55,8 @@ public class SegmentWriter {
 
     private final SegmentStore store;
 
+    private final SegmentReader reader;
+
     private final Map<String, RecordId> strings = Maps.newHashMap();
 
     private final Map<Template, RecordId> templates = Maps.newHashMap();
@@ -83,8 +87,9 @@ public class SegmentWriter {
      */
     private int position;
 
-    public SegmentWriter(SegmentStore store) {
+    public SegmentWriter(SegmentStore store, SegmentReader reader) {
         this.store = store;
+        this.reader = reader;
     }
 
     public synchronized void flush() {
@@ -175,14 +180,16 @@ public class SegmentWriter {
         return bucketId;
     }
 
-    class MapEntry implements Comparable<MapEntry> {
+    private class MapEntry implements Comparable<MapEntry> {
         private final int hashCode;
+        private final String string;
         private final RecordId key;
         private final RecordId value;
 
-        MapEntry(int hashCode, RecordId key, RecordId value) {
-            this.hashCode = hashCode;
-            this.key = key;
+        MapEntry(String key, RecordId value) {
+            this.hashCode = key.hashCode();
+            this.string = key;
+            this.key = writeString(key);
             this.value = value;
         }
 
@@ -214,13 +221,105 @@ public class SegmentWriter {
 
     }
 
-    private synchronized RecordId writeMapBucket(
-            List<MapEntry> entries, int level) {
+    private static class BucketInfo {
+        RecordId id;
+        int size;
+        BucketInfo(RecordId id, int size) {
+            this.id = id;
+            this.size = size;
+        }
+    }
+
+    private synchronized BucketInfo writeMapBucket(
+            RecordId baseId, List<MapEntry> entries, int level) {
         int size = 1 << MapRecord.LEVEL_BITS;
         int mask = size - 1;
         int shift = level * MapRecord.LEVEL_BITS;
 
-        if (entries.size() <= size) {
+        if (entries.isEmpty()) {
+            if (baseId != null) {
+                return new BucketInfo(baseId, new MapRecord(baseId).size(reader));
+            } else if (level == 0) {
+                RecordId id = prepare(4);
+                writeInt(0);
+                return new BucketInfo(id, 0);
+            } else {
+                return new BucketInfo(null, 0);
+            }
+        } else if (baseId != null) {
+            // FIXME: messy code with lots of duplication
+            MapRecord base = new MapRecord(baseId);
+            int baseSize = base.size(reader);
+            if (baseSize <= size) {
+                Map<String, RecordId> update = Maps.newHashMap();
+                for (MapRecord.Entry entry : base.getEntries(reader)) {
+                    update.put(entry.getKey(), entry.getValue());
+                }
+                for (MapEntry entry : entries) {
+                    if (entry.value != null) {
+                        update.put(entry.string, entry.value);
+                    } else {
+                        update.remove(entry.string);
+                    }
+                }
+                entries = Lists.newArrayListWithCapacity(update.size());
+                for (Map.Entry<String, RecordId> entry : update.entrySet()) {
+                    entries.add(new MapEntry(entry.getKey(), entry.getValue()));
+                }
+                return writeMapBucket(null, entries, level);
+            } else {
+                List<MapEntry>[] buckets = new List[size];
+                for (MapEntry entry : entries) {
+                    int bucketIndex = (entry.hashCode >> shift) & mask;
+                    if (buckets[bucketIndex] == null) {
+                        buckets[bucketIndex] = Lists.newArrayList();
+                    }
+                    buckets[bucketIndex].add(entry);
+                }
+
+                long baseMap = reader.readLong(baseId, 4);
+
+                int newSize = 0;
+                RecordId[] bucketIds = new RecordId[size];
+                for (int i = 0; i < buckets.length; i++) {
+                    long bucketBit = 1L << i;
+                    RecordId baseBucketId = null;
+                    if ((baseMap & bucketBit) != 0) {
+                        int index = Long.bitCount(baseMap & (bucketBit - 1));
+                        baseBucketId = reader.readRecordId(
+                                baseId, 12 + index * Segment.RECORD_ID_BYTES);
+                    }
+                    if (buckets[i] != null) {
+                        BucketInfo info = writeMapBucket(
+                                baseBucketId, buckets[i], level + 1);
+                        bucketIds[i] = info.id;
+                        newSize += info.size;
+                    } else {
+                        bucketIds[i] = baseBucketId;
+                        if (baseBucketId != null) {
+                            newSize += new MapRecord(baseBucketId).size(reader);
+                        }
+                    }
+                }
+                
+                List<RecordId> ids = Lists.newArrayList();
+                long bucketMap = 0L;
+                for (int i = 0; i < buckets.length; i++) {
+                    if (bucketIds[i] != null) {
+                        ids.add(bucketIds[i]);
+                        bucketMap |= 1L << i;
+                    }
+                }
+
+                RecordId bucketId = prepare(12, ids);
+                writeInt(newSize);
+                writeLong(bucketMap);
+                for (RecordId id : ids) {
+                    writeRecordId(id);
+                }
+                return new BucketInfo(bucketId, newSize);
+            }
+        } else if (entries.size() <= size) {
             Collections.sort(entries);
 
             List<RecordId> ids = Lists.newArrayList();
@@ -240,7 +339,7 @@ public class SegmentWriter {
             for (MapEntry entry : entries) {
                 writeRecordId(entry.value);
             }
-            return bucketId;
+            return new BucketInfo(bucketId, entries.size());
         } else {
             List<MapEntry>[] buckets = new List[size];
             for (MapEntry entry : entries) {
@@ -255,7 +354,7 @@ public class SegmentWriter {
             long bucketMap = 0L;
             for (int i = 0; i < buckets.length; i++) {
                 if (buckets[i] != null) {
-                    bucketIds.add(writeMapBucket(buckets[i], level + 1));
+                    bucketIds.add(writeMapBucket(null, buckets[i], level + 1).id);
                     bucketMap |= 1L << i;
                 }
             }
@@ -266,7 +365,7 @@ public class SegmentWriter {
             for (RecordId id : bucketIds) {
                 writeRecordId(id);
             }
-            return bucketId;
+            return new BucketInfo(bucketId, entries.size());
         }
     }
 
@@ -319,14 +418,16 @@ public class SegmentWriter {
         return thisLevel.iterator().next();
     }
 
-    public RecordId writeMap(Map<String, RecordId> map) {
+    public MapRecord writeMap(MapRecord base, Map<String, RecordId> changes) {
         List<MapEntry> entries = Lists.newArrayList();
-        for (Map.Entry<String, RecordId> entry : map.entrySet()) {
-            String key = entry.getKey();
-            entries.add(new MapEntry(
-                    key.hashCode(), writeString(key), entry.getValue()));
+        for (Map.Entry<String, RecordId> entry : changes.entrySet()) {
+            entries.add(new MapEntry(entry.getKey(), entry.getValue()));
         }
-        return writeMapBucket(entries, 0);
+        RecordId baseId = null;
+        if (base != null) {
+            baseId = base.getRecordId();
+        }
+        return new MapRecord(writeMapBucket(baseId, entries, 0).id);
     }
 
     /**
@@ -535,17 +636,50 @@ public class SegmentWriter {
             return nodeId;
         }
 
+        SegmentNodeState before = null;
+        ModifiedNodeState after = null;
+        if (state instanceof ModifiedNodeState) {
+            after = ModifiedNodeState.collapse((ModifiedNodeState) state);
+            NodeState base = after.getBaseState();
+            if (base instanceof SegmentNodeState) {
+                before = (SegmentNodeState) base;
+            }
+        }
+
         Template template = new Template(state);
 
         List<RecordId> ids = Lists.newArrayList();
         ids.add(writeTemplate(template));
 
         if (template.hasManyChildNodes()) {
-            Map<String, RecordId> childNodes = Maps.newHashMap();
-            for (ChildNodeEntry entry : state.getChildNodeEntries()) {
-                childNodes.put(entry.getName(), writeNode(entry.getNodeState()));
+            MapRecord base;
+            final Map<String, RecordId> childNodes = Maps.newHashMap();
+            if (before != null
+                    && before.getChildNodeCount() > 1
+                    && after.getChildNodeCount() > 1) {
+                base = before.getChildNodeMap();
+                after.compareAgainstBaseState(before, new DefaultNodeStateDiff() {
+                    @Override
+                    public void childNodeAdded(String name, NodeState after) {
+                        childNodes.put(name, writeNode(after));
+                    }
+                    @Override
+                    public void childNodeChanged(
+                            String name, NodeState before, NodeState after) {
+                        childNodes.put(name, writeNode(after));
+                    }
+                    @Override
+                    public void childNodeDeleted(String name, NodeState before) {
+                        childNodes.put(name, null);
+                    }
+                });
+            } else {
+                base = null;
+                for (ChildNodeEntry entry : state.getChildNodeEntries()) {
+                    childNodes.put(entry.getName(), writeNode(entry.getNodeState()));
+                }
             }
-            ids.add(writeMap(childNodes));
+            ids.add(writeMap(base, childNodes).getRecordId());
         } else if (!template.hasNoChildNodes()) {
             ids.add(writeNode(state.getChildNode(template.getChildName())));
         }

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=1448610&r1=1448609&r2=1448610&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
Thu Feb 21 11:48:15 2013
@@ -248,14 +248,19 @@ class Template {
         }
     }
 
+    MapRecord getChildNodeMap(SegmentReader reader, RecordId recordId) {
+        checkState(hasManyChildNodes());
+        return new MapRecord(
+                reader.readRecordId(recordId, Segment.RECORD_ID_BYTES));
+    }
+
     public boolean hasChildNode(
             String name, SegmentReader reader, RecordId recordId) {
         if (hasNoChildNodes()) {
             return false;
         } else if (hasManyChildNodes()) {
-            RecordId childNodesId =
-                    reader.readRecordId(recordId, Segment.RECORD_ID_BYTES);
-            return new MapRecord(childNodesId).getEntry(reader, name) != null;
+            MapRecord map = getChildNodeMap(reader, recordId);
+            return map.getEntry(reader, name) != null;
         } else {
             return name.equals(childName);
         }
@@ -266,10 +271,8 @@ class Template {
         if (hasNoChildNodes()) {
             return null;
         } else if (hasManyChildNodes()) {
-            RecordId childNodesId =
-                    reader.readRecordId(recordId, Segment.RECORD_ID_BYTES);
             RecordId childNodeId =
-                    new MapRecord(childNodesId).getEntry(reader, name);
+                    getChildNodeMap(reader, recordId).getEntry(reader, name);
             if (childNodeId != null) {
                 return new SegmentNodeState(reader, childNodeId);
             } else {
@@ -289,10 +292,8 @@ class Template {
         if (hasNoChildNodes()) {
             return Collections.emptyList();
         } else if (hasManyChildNodes()) {
-            RecordId childNodesId =
-                    reader.readRecordId(recordId, Segment.RECORD_ID_BYTES);
             return Iterables.transform(
-                    new MapRecord(childNodesId).getEntries(reader),
+                    getChildNodeMap(reader, recordId).getEntries(reader),
                     new Function<MapRecord.Entry, String>() {
                         @Override @Nullable
                         public String apply(@Nullable Entry input) {
@@ -309,10 +310,8 @@ class Template {
         if (hasNoChildNodes()) {
             return Collections.emptyList();
         } else if (hasManyChildNodes()) {
-            RecordId childNodesId =
-                    reader.readRecordId(recordId, Segment.RECORD_ID_BYTES);
             return Iterables.transform(
-                    new MapRecord(childNodesId).getEntries(reader),
+                    getChildNodeMap(reader, recordId).getEntries(reader),
                     new Function<MapRecord.Entry, ChildNodeEntry>() {
                         @Override @Nullable
                         public ChildNodeEntry apply(@Nullable Entry input) {

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/CompareAgainstBaseStateTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/CompareAgainstBaseStateTest.java?rev=1448610&r1=1448609&r2=1448610&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/CompareAgainstBaseStateTest.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/CompareAgainstBaseStateTest.java
Thu Feb 21 11:48:15 2013
@@ -31,10 +31,10 @@ public class CompareAgainstBaseStateTest
 
     private final SegmentStore store = new MemoryStore();
 
-    private final SegmentWriter writer = new SegmentWriter(store);
-
     private final SegmentReader reader = new SegmentReader(store);
 
+    private final SegmentWriter writer = new SegmentWriter(store, reader);
+
     private final NodeStateDiff diff = EasyMock.createMock(NodeStateDiff.class);
 
     private final NodeBuilder builder = MemoryNodeState.EMPTY_NODE.builder();

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/RecordTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/RecordTest.java?rev=1448610&r1=1448609&r2=1448610&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/RecordTest.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/RecordTest.java
Thu Feb 21 11:48:15 2013
@@ -49,10 +49,10 @@ public class RecordTest {
 
     private SegmentStore store = new MemoryStore();
 
-    private SegmentWriter writer = new SegmentWriter(store);
-
     private SegmentReader reader = new SegmentReader(store);
 
+    private SegmentWriter writer = new SegmentWriter(store, reader);
+
     private final Random random = new Random(0xcafefaceL);
 
     @Test
@@ -172,17 +172,17 @@ public class RecordTest {
     public void testMapRecord() {
         RecordId blockId = writer.writeBlock(bytes, 0, bytes.length);
 
-        MapRecord zero = new MapRecord(writer.writeMap(
-                ImmutableMap.<String, RecordId>of()));
-        MapRecord one = new MapRecord(writer.writeMap(
-                ImmutableMap.of("one", blockId)));
-        MapRecord two = new MapRecord(writer.writeMap(
-                ImmutableMap.of("one", blockId, "two", blockId)));
+        MapRecord zero = writer.writeMap(
+                null, ImmutableMap.<String, RecordId>of());
+        MapRecord one = writer.writeMap(
+                null, ImmutableMap.of("one", blockId));
+        MapRecord two = writer.writeMap(
+                null, ImmutableMap.of("one", blockId, "two", blockId));
         Map<String, RecordId> map = Maps.newHashMap();
         for (int i = 0; i < 1000; i++) {
             map.put("key" + i, blockId);
         }
-        MapRecord many = new MapRecord(writer.writeMap(map));
+        MapRecord many = writer.writeMap(null, map);
 
         writer.flush();
         Iterator<MapRecord.Entry> iterator;
@@ -215,11 +215,26 @@ public class RecordTest {
         iterator = many.getEntries(reader).iterator();
         for (int i = 0; i < 1000; i++) {
             assertTrue(iterator.hasNext());
-            iterator.next();
+            assertEquals(blockId, iterator.next().getValue());
             assertEquals(blockId, many.getEntry(reader, "key" + i));
         }
         assertFalse(iterator.hasNext());
         assertNull(many.getEntry(reader, "foo"));
+
+        Map<String, RecordId> changes = Maps.newHashMap();
+        changes.put("key0", null);
+        changes.put("key1000", blockId);
+        MapRecord modified = writer.writeMap(many, changes);
+        writer.flush();
+        assertEquals(1000, modified.size(reader));
+        iterator = modified.getEntries(reader).iterator();
+        for (int i = 1; i <= 1000; i++) {
+            assertTrue(iterator.hasNext());
+            assertEquals(blockId, iterator.next().getValue());
+            assertEquals(blockId, modified.getEntry(reader, "key" + i));
+        }
+        assertFalse(iterator.hasNext());
+        assertNull(many.getEntry(reader, "foo"));
     }
 
     @Test

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentSizeTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentSizeTest.java?rev=1448610&r1=1448609&r2=1448610&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentSizeTest.java
(original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/SegmentSizeTest.java
Thu Feb 21 11:48:15 2013
@@ -144,7 +144,7 @@ public class SegmentSizeTest {
 
     private int getSize(NodeBuilder builder) {
         SegmentStore store = new MemoryStore();
-        SegmentWriter writer = new SegmentWriter(store);
+        SegmentWriter writer = new SegmentWriter(store, new SegmentReader(store));
         RecordId id = writer.writeNode(builder.getNodeState());
         writer.flush();
         Segment segment = store.readSegment(id.getSegmentId());
@@ -153,7 +153,7 @@ public class SegmentSizeTest {
 
     private int getAmortizedSize(NodeBuilder builder) {
         SegmentStore store = new MemoryStore();
-        SegmentWriter writer = new SegmentWriter(store);
+        SegmentWriter writer = new SegmentWriter(store, new SegmentReader(store));
         NodeState state = builder.getNodeState();
         writer.writeNode(state);
         writer.flush();



Mime
View raw message