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 mr...@apache.org on 2014/04/08 16:11:01 UTC

svn commit: r1585735 - in /jackrabbit/oak/branches/1.0: ./ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/ oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/

Author: mreutegg
Date: Tue Apr  8 14:11:01 2014
New Revision: 1585735

URL: http://svn.apache.org/r1585735
Log:
OAK-1692: Document split may drop revisions

Merge fix from trunk.

Modified:
    jackrabbit/oak/branches/1.0/   (props changed)
    jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeState.java
    jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
    jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/NodeDocument.java
    jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentSplitTest.java

Propchange: jackrabbit/oak/branches/1.0/
------------------------------------------------------------------------------
  Merged /jackrabbit/oak/trunk:r1585719

Modified: jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeState.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeState.java?rev=1585735&r1=1585734&r2=1585735&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeState.java (original)
+++ jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeState.java Tue Apr  8 14:11:01 2014
@@ -42,6 +42,7 @@ import org.apache.jackrabbit.oak.plugins
 import org.apache.jackrabbit.oak.spi.state.AbstractChildNodeEntry;
 import org.apache.jackrabbit.oak.spi.state.AbstractNodeState;
 import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
+import org.apache.jackrabbit.oak.spi.state.EqualsDiff;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;
@@ -110,7 +111,7 @@ class DocumentNodeState extends Abstract
         } else if (that instanceof ModifiedNodeState) {
             ModifiedNodeState modified = (ModifiedNodeState) that;
             if (modified.getBaseState() == this) {
-                return false;
+                return EqualsDiff.equals(this, modified);
             }
         }
         if (that instanceof NodeState) {

Modified: jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java?rev=1585735&r1=1585734&r2=1585735&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java (original)
+++ jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java Tue Apr  8 14:11:01 2014
@@ -1413,9 +1413,11 @@ public final class DocumentNodeStore
                 if (before != null) {
                     NodeDocument after = store.find(Collection.NODES, op.getId());
                     if (after != null) {
-                        LOG.info("Split operation on {}. Size before: {}, after: {}",
+                        LOG.debug("Split operation on {}. Size before: {}, after: {}",
                                 id, before.getMemory(), after.getMemory());
                     }
+                } else {
+                    LOG.debug("Split operation created {}", op.getId());
                 }
             }
             it.remove();

Modified: jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/NodeDocument.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/NodeDocument.java?rev=1585735&r1=1585734&r2=1585735&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/NodeDocument.java (original)
+++ jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/NodeDocument.java Tue Apr  8 14:11:01 2014
@@ -958,9 +958,11 @@ public final class NodeDocument extends 
             NodeDocument oldDoc = new NodeDocument(store);
             UpdateUtils.applyChanges(oldDoc, old, context.getRevisionComparator());
             setSplitDocProps(this, oldDoc, old, high);
-            // only split if half of the data can be moved to old document
+            // only split if enough of the data can be moved to old document
             if (oldDoc.getMemory() > getMemory() * SPLIT_RATIO) {
                 splitOps.add(old);
+            } else {
+                main = null;
             }
         }
 

Modified: jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentSplitTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentSplitTest.java?rev=1585735&r1=1585734&r2=1585735&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentSplitTest.java (original)
+++ jackrabbit/oak/branches/1.0/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentSplitTest.java Tue Apr  8 14:11:01 2014
@@ -23,6 +23,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Random;
 import java.util.Set;
+import java.util.TreeSet;
 
 import com.google.common.base.Predicate;
 import com.google.common.collect.ImmutableList;
@@ -42,11 +43,17 @@ import com.google.common.collect.Sets;
 
 import static org.apache.jackrabbit.oak.plugins.document.Collection.NODES;
 import static org.apache.jackrabbit.oak.plugins.document.MongoBlobGCTest.randomStream;
+import static org.apache.jackrabbit.oak.plugins.document.NodeDocument.NUM_REVS_THRESHOLD;
+import static org.apache.jackrabbit.oak.plugins.document.NodeDocument.PREV_SPLIT_FACTOR;
+import static org.apache.jackrabbit.oak.plugins.document.NodeDocument.SPLIT_RATIO;
 import static org.apache.jackrabbit.oak.plugins.document.NodeDocument.SplitDocType;
+import static org.apache.jackrabbit.oak.plugins.document.UpdateOp.Operation.Type.REMOVE_MAP_ENTRY;
+import static org.apache.jackrabbit.oak.plugins.document.UpdateOp.Operation.Type.SET_MAP_ENTRY;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 /**
  * Check correct splitting of documents (OAK-926 & OAK-1342).
@@ -479,6 +486,67 @@ public class DocumentSplitTest extends B
         }
     }
 
+    @Test
+    public void cascadingWithSplitRatio() {
+        String id = Utils.getIdFromPath("/test");
+        mk.commit("/", "+\"test\":{}", null, null);
+        DocumentStore store = mk.getDocumentStore();
+        int clusterId = mk.getNodeStore().getClusterId();
+
+        UpdateOp op = new UpdateOp(id, false);
+        // create some baggage
+        for (int i = 0; i < NUM_REVS_THRESHOLD / SPLIT_RATIO; i++) {
+            Revision r = Revision.newRevision(2);
+            op.setMapEntry("prop", r, "test value");
+            NodeDocument.setRevision(op, r, "c");
+        }
+        // these will be considered for a split
+        for (int i = 0; i < NUM_REVS_THRESHOLD; i++) {
+            Revision r = Revision.newRevision(clusterId);
+            op.setMapEntry("prop", r, "value");
+            NodeDocument.setRevision(op, r, "c");
+        }
+        // some fake previous doc references to trigger UpdateOp
+        // for an intermediate document
+        TreeSet<Revision> prev = Sets.newTreeSet(mk.getNodeStore().getRevisionComparator());
+        for (int i = 0; i < PREV_SPLIT_FACTOR; i++) {
+            Revision low = Revision.newRevision(clusterId);
+            Revision high = Revision.newRevision(clusterId);
+            prev.add(high);
+            NodeDocument.setPrevious(op, new Range(high, low, 0));
+        }
+        store.findAndUpdate(NODES, op);
+
+        NodeDocument doc = store.find(NODES, id);
+        assertNotNull(doc);
+        List<UpdateOp> splitOps = Lists.newArrayList(doc.split(mk.getNodeStore()));
+        assertEquals(2, splitOps.size());
+        // first update op is for the new intermediate doc
+        op = splitOps.get(0);
+        String newPrevId = Utils.getPreviousIdFor("/test", prev.last(), 1);
+        assertEquals(newPrevId, op.getId());
+        // second update op is for the main document
+        op = splitOps.get(1);
+        assertEquals(id, op.getId());
+        for (Map.Entry<UpdateOp.Key, UpdateOp.Operation> entry : op.getChanges().entrySet()) {
+            Revision r = entry.getKey().getRevision();
+            assertNotNull(r);
+            assertEquals(clusterId, r.getClusterId());
+            if (entry.getKey().getName().equals("_prev")) {
+                if (entry.getValue().type == REMOVE_MAP_ENTRY) {
+                    assertTrue(prev.contains(r));
+                } else if (entry.getValue().type == SET_MAP_ENTRY) {
+                    assertEquals(newPrevId, Utils.getPreviousIdFor("/test", r, 1));
+                } else {
+                    fail("unexpected update operation " + entry);
+                }
+            } else {
+                fail("unexpected update operation " + entry);
+            }
+        }
+
+    }
+
     private void syncMKs(List<DocumentMK> mks, int idx) {
         mks.get(idx).runBackgroundOperations();
         for (int i = 0; i < mks.size(); i++) {