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 ju...@apache.org on 2013/03/04 15:07:05 UTC
svn commit: r1452313 - in /jackrabbit/oak/trunk/oak-core/src:
main/java/org/apache/jackrabbit/oak/plugins/segment/
test/java/org/apache/jackrabbit/oak/plugins/segment/
Author: jukka
Date: Mon Mar 4 14:07:04 2013
New Revision: 1452313
URL: http://svn.apache.org/r1452313
Log:
OAK-654: MapBranch size preconditions can fail
Add a test case and fix the problem.
Modified:
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/SegmentWriter.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/RecordTest.java
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=1452313&r1=1452312&r2=1452313&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 Mon Mar 4 14:07:04 2013
@@ -24,8 +24,6 @@ import static java.lang.Integer.numberOf
import java.util.UUID;
-import com.google.common.base.Preconditions;
-
abstract class MapRecord extends Record {
/**
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=1452313&r1=1452312&r2=1452313&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 Mon Mar 4 14:07:04 2013
@@ -48,6 +48,7 @@ import org.apache.jackrabbit.oak.spi.sta
import org.apache.jackrabbit.oak.spi.state.NodeState;
import com.google.common.base.Charsets;
+import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.io.ByteStreams;
@@ -290,19 +291,42 @@ public class SegmentWriter {
}
int newSize = 0;
+ List<MapRecord> newBuckets = Lists.newArrayList();
RecordId[] bucketIds = ((MapBranch) base).getBuckets();
for (int i = 0; i < BUCKETS_PER_LEVEL; i++) {
MapRecord newBucket = writeMapBucket(
bucketIds[i], buckets.get(i), level + 1);
if (newBucket != null) {
+ newBuckets.add(newBucket);
bucketIds[i] = newBucket.getRecordId();
newSize += newBucket.size();
} else {
bucketIds[i] = null;
}
}
-
- return writeMapBranch(level, newSize, bucketIds);
+
+ // OAK-654: what if the updated map is smaller?
+ if (newSize > MapRecord.BUCKETS_PER_LEVEL) {
+ return writeMapBranch(level, newSize, bucketIds);
+ } else if (newSize == 0) {
+ if (level == 0) {
+ RecordId id = prepare(4);
+ writeInt(0);
+ return new MapLeaf(store, id, 0, 0);
+ } else {
+ return null;
+ }
+ } else if (newBuckets.size() == 1) {
+ return newBuckets.iterator().next();
+ } else {
+ // FIXME: ugly hack, flush() shouldn't be needed here
+ flush();
+ List<MapEntry> list = Lists.newArrayList();
+ for (MapRecord record : newBuckets) {
+ Iterables.addAll(list, record.getEntries());
+ }
+ return writeMapLeaf(level, list);
+ }
}
} else if (entries.size() <= MapRecord.BUCKETS_PER_LEVEL
|| level == MapRecord.MAX_NUMBER_OF_LEVELS) {
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=1452313&r1=1452312&r2=1452313&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 Mon Mar 4 14:07:04 2013
@@ -294,4 +294,23 @@ public class RecordTest {
assertEquals(before, after);
}
+ @Test
+ public void testManyMapDeletes() {
+ NodeBuilder builder = MemoryNodeState.EMPTY_NODE.builder();
+ for (int i = 0; i < 1000; i++) {
+ builder.child("test" + i);
+ }
+ NodeState before = writer.writeNode(builder.getNodeState());
+ writer.flush();
+ assertEquals(builder.getNodeState(), before);
+
+ builder = before.builder();
+ for (int i = 0; i < 900; i++) {
+ builder.removeNode("test" + i);
+ }
+ NodeState after = writer.writeNode(builder.getNodeState());
+ writer.flush();
+ assertEquals(builder.getNodeState(), after);
+ }
+
}