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 2013/11/11 10:50:43 UTC

svn commit: r1540650 - in /jackrabbit/oak/trunk/oak-core/src: main/java/org/apache/jackrabbit/oak/plugins/mongomk/NodeDocument.java test/java/org/apache/jackrabbit/oak/plugins/mongomk/DocumentSplitTest.java

Author: mreutegg
Date: Mon Nov 11 09:50:43 2013
New Revision: 1540650

URL: http://svn.apache.org/r1540650
Log:
OAK-1165: Too frequent document splits

Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/NodeDocument.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/DocumentSplitTest.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/NodeDocument.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/NodeDocument.java?rev=1540650&r1=1540649&r2=1540650&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/NodeDocument.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/mongomk/NodeDocument.java Mon Nov 11 09:50:43 2013
@@ -70,14 +70,20 @@ public class NodeDocument extends Docume
 
     /**
      * A document size threshold after which a split is forced even if
-     * {@link #REVISIONS_SPLIT_OFF_SIZE} is not reached.
+     * {@link #NUM_REVS_THRESHOLD} is not reached.
      */
-    static final int FORCE_SPLIT_THRESHOLD = 256 * 1024;
+    static final int DOC_SIZE_THRESHOLD = 256 * 1024;
 
     /**
      * Only split off at least this number of revisions.
      */
-    static final int REVISIONS_SPLIT_OFF_SIZE = 100;
+    static final int NUM_REVS_THRESHOLD = 100;
+
+    /**
+     * The split ratio. Only split data to an old document when at least
+     * 30% of the data can be moved.
+     */
+    static final float SPLIT_RATIO = 0.3f;
 
     /**
      * Revision collision markers set by commits with modifications, which
@@ -575,8 +581,8 @@ public class NodeDocument extends Docume
     public Iterable<UpdateOp> split(@Nonnull RevisionContext context) {
         // only consider if there are enough commits,
         // unless document is really big
-        if (getLocalRevisions().size() + getLocalCommitRoot().size() <= REVISIONS_SPLIT_OFF_SIZE
-                && getMemory() < FORCE_SPLIT_THRESHOLD) {
+        if (getLocalRevisions().size() + getLocalCommitRoot().size() <= NUM_REVS_THRESHOLD
+                && getMemory() < DOC_SIZE_THRESHOLD) {
             return Collections.emptyList();
         }
         String id = getId();
@@ -640,7 +646,8 @@ public class NodeDocument extends Docume
             numValues += splitMap.size();
         }
         if (high != null && low != null
-                && (numValues >= REVISIONS_SPLIT_OFF_SIZE || getMemory() > FORCE_SPLIT_THRESHOLD)) {
+                && (numValues >= NUM_REVS_THRESHOLD
+                    || getMemory() > DOC_SIZE_THRESHOLD)) {
             // enough revisions to split off
             splitOps = new ArrayList<UpdateOp>(2);
             // move to another document
@@ -656,8 +663,15 @@ public class NodeDocument extends Docume
                     old.setMapEntry(property, r, entry.getValue());
                 }
             }
-            splitOps.add(old);
-            splitOps.add(main);
+            // check size of old document
+            NodeDocument oldDoc = new NodeDocument(store);
+            MemoryDocumentStore.applyChanges(oldDoc, old,
+                    context.getRevisionComparator());
+            // only split if half of the data can be moved to old document
+            if (oldDoc.getMemory() > getMemory() * SPLIT_RATIO) {
+                splitOps.add(old);
+                splitOps.add(main);
+            }
         }
         return splitOps;
     }

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/DocumentSplitTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/DocumentSplitTest.java?rev=1540650&r1=1540649&r2=1540650&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/DocumentSplitTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/mongomk/DocumentSplitTest.java Mon Nov 11 09:50:43 2013
@@ -45,7 +45,7 @@ public class DocumentSplitTest extends B
         revisions.addAll(doc.getLocalRevisions().keySet());
         revisions.add(Revision.fromString(mk.commit("/", "+\"foo\":{}+\"bar\":{}", null, null)));
         // create nodes
-        while (revisions.size() <= NodeDocument.REVISIONS_SPLIT_OFF_SIZE) {
+        while (revisions.size() <= NodeDocument.NUM_REVS_THRESHOLD) {
             revisions.add(Revision.fromString(mk.commit("/", "+\"foo/node-" + revisions.size() + "\":{}" +
                     "+\"bar/node-" + revisions.size() + "\":{}", null, null)));
         }
@@ -77,7 +77,7 @@ public class DocumentSplitTest extends B
         assertNotNull(doc);
         revisions.addAll(doc.getLocalRevisions().keySet());
         boolean create = false;
-        while (revisions.size() <= NodeDocument.REVISIONS_SPLIT_OFF_SIZE) {
+        while (revisions.size() <= NodeDocument.NUM_REVS_THRESHOLD) {
             if (create) {
                 revisions.add(Revision.fromString(mk.commit("/", "+\"foo\":{}", null, null)));
             } else {
@@ -114,7 +114,7 @@ public class DocumentSplitTest extends B
         Set<Revision> commitRoots = Sets.newHashSet();
         commitRoots.addAll(doc.getLocalCommitRoot().keySet());
         // create nodes
-        while (commitRoots.size() <= NodeDocument.REVISIONS_SPLIT_OFF_SIZE) {
+        while (commitRoots.size() <= NodeDocument.NUM_REVS_THRESHOLD) {
             commitRoots.add(Revision.fromString(mk.commit("/", "^\"foo/prop\":" +
                     commitRoots.size() + "^\"bar/prop\":" + commitRoots.size(), null, null)));
         }
@@ -138,7 +138,7 @@ public class DocumentSplitTest extends B
         assertNotNull(doc);
         Set<Revision> revisions = Sets.newHashSet();
         // create nodes
-        while (revisions.size() <= NodeDocument.REVISIONS_SPLIT_OFF_SIZE) {
+        while (revisions.size() <= NodeDocument.NUM_REVS_THRESHOLD) {
             revisions.add(Revision.fromString(mk.commit("/", "^\"foo/prop\":" +
                     revisions.size(), null, null)));
         }
@@ -180,7 +180,7 @@ public class DocumentSplitTest extends B
         builder.setDocumentStore(ds).setBlobStore(bs).setAsyncDelay(0);
         MongoMK mk3 = builder.setClusterId(3).open();
 
-        for (int i = 0; i < NodeDocument.REVISIONS_SPLIT_OFF_SIZE; i++) {
+        for (int i = 0; i < NodeDocument.NUM_REVS_THRESHOLD; i++) {
             mk1.commit("/", "^\"test/prop1\":" + i, null, null);
             mk2.commit("/", "^\"test/prop2\":" + i, null, null);
             mk3.commit("/", "^\"test/prop3\":" + i, null, null);
@@ -195,7 +195,7 @@ public class DocumentSplitTest extends B
         Map<Revision, String> revs = doc.getLocalRevisions();
         assertEquals(3, revs.size());
         revs = doc.getValueMap("_revisions");
-        assertEquals(3 * NodeDocument.REVISIONS_SPLIT_OFF_SIZE, revs.size());
+        assertEquals(3 * NodeDocument.NUM_REVS_THRESHOLD, revs.size());
         Revision previous = null;
         for (Map.Entry<Revision, String> entry : revs.entrySet()) {
             if (previous != null) {