You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2017/05/04 11:32:53 UTC

[49/60] [abbrv] ignite git commit: IGNITE-4989 Assertion error in BPlusTree#finishTail - Fixes #1894.

IGNITE-4989 Assertion error in BPlusTree#finishTail - Fixes #1894.

Signed-off-by: Sergi Vladykin <se...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/85f5309d
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/85f5309d
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/85f5309d

Branch: refs/heads/ignite-5075-cacheStart
Commit: 85f5309db0b12f3dc1c843463537518e05c0fd80
Parents: 28870dc
Author: EdShangGG <es...@gridgain.com>
Authored: Wed May 3 15:07:54 2017 +0300
Committer: Sergi Vladykin <se...@gmail.com>
Committed: Wed May 3 15:07:54 2017 +0300

----------------------------------------------------------------------
 .../cache/database/tree/BPlusTree.java          |  6 +-
 .../processors/database/BPlusTreeSelfTest.java  | 75 ++++++++++++++++++++
 2 files changed, 80 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/85f5309d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/BPlusTree.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/BPlusTree.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/BPlusTree.java
index 648f35a..a4c09d5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/BPlusTree.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/BPlusTree.java
@@ -443,6 +443,10 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure implements
             throws IgniteCheckedException {
             assert lvl == 0 : lvl; // Leaf.
 
+            // Check the triangle invariant.
+            if (io.getForward(leafAddr) != r.fwdId)
+                return RETRY;
+
             final int cnt = io.getCount(leafAddr);
 
             assert cnt <= Short.MAX_VALUE: cnt;
@@ -3384,7 +3388,7 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure implements
 
             if (tail.lvl == 0) {
                 // At the bottom level we can't have a tail without a sibling, it means we have higher levels.
-                assert tail.sibling != null;
+                assert tail.sibling != null : tail;
 
                 return NOT_FOUND; // Lock upper level, we are at the bottom now.
             }

http://git-wip-us.apache.org/repos/asf/ignite/blob/85f5309d/modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeSelfTest.java
index 0254c4c..a46242c 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeSelfTest.java
@@ -27,8 +27,10 @@ import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicLongArray;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.concurrent.locks.Lock;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.configuration.MemoryPolicyConfiguration;
@@ -1225,6 +1227,79 @@ public class BPlusTreeSelfTest extends GridCommonAbstractTest {
     }
 
     /**
+     *
+     */
+    public void testConcurrentGrowDegenerateTreeAndConcurrentRemove() throws Exception {
+        //calculate tree size when split happens
+        final TestTree t = createTestTree(true);
+        long i = 0;
+
+        for (; ; i++) {
+            t.put(i);
+
+            if (t.rootLevel() > 0)  //split happened
+                break;
+        }
+
+        final long treeStartSize = i;
+
+        final AtomicReference<Throwable> failed = new AtomicReference<>();
+
+        for (int k = 0; k < 100; k++) {
+            final TestTree tree = createTestTree(true);
+
+            final AtomicBoolean start = new AtomicBoolean();
+
+            final AtomicInteger ready = new AtomicInteger();
+
+            Thread first = new Thread(new Runnable() {
+                @Override public void run() {
+                    ready.incrementAndGet();
+
+                    while (!start.get()); //waiting without blocking
+
+                    try {
+                        tree.remove(treeStartSize / 2L);
+                    }
+                    catch (Throwable th) {
+                        failed.set(th);
+                    }
+                }
+            });
+
+            Thread second = new Thread(new Runnable() {
+                @Override public void run() {
+                    ready.incrementAndGet();
+
+                    while (!start.get()); //waiting without blocking
+
+                    try {
+                        tree.put(treeStartSize + 1);
+                    }
+                    catch (Throwable th) {
+                        failed.set(th);
+                    }
+                }
+            });
+
+            for (int j = 0; j < treeStartSize; j++)
+                tree.put((long)j);
+
+            first.start();
+            second.start();
+
+            while (ready.get() != 2);
+
+            start.set(true);
+
+            first.join();
+            second.join();
+
+            assertNull(failed.get());
+        }
+    }
+
+    /**
      * @param canGetRow Can get row from inner page.
      * @throws Exception If failed.
      */