Repository: ignite
Updated Branches:
  refs/heads/master 53e24e177 -> df238634d


IGNITE-7019 Cluster can not survive after IgniteOOM

Signed-off-by: Anton Vinogradov <a...@apache.org>


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

Branch: refs/heads/master
Commit: df238634d6d0db42b4a78e94a53cd58f6dda2082
Parents: 53e24e1
Author: Dmitriy Sorokin <sbt.sorokin....@gmail.com>
Authored: Mon Feb 12 12:53:35 2018 +0300
Committer: Anton Vinogradov <a...@apache.org>
Committed: Mon Feb 12 12:53:35 2018 +0300

----------------------------------------------------------------------
 .../cache/persistence/DataStructure.java        | 14 ++++++-
 .../cache/persistence/freelist/PagesList.java   | 44 ++++++++++++++------
 .../cache/persistence/tree/BPlusTree.java       | 14 +++++++
 .../cache/persistence/tree/reuse/ReuseBag.java  |  5 +++
 4 files changed, 64 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/df238634/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStructure.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStructure.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStructure.java
index 1d4b812..663a139 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStructure.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStructure.java
@@ -91,14 +91,26 @@ public abstract class DataStructure implements 
PageLockListener {
     }
 
     /**
+     * Shorthand for {@code allocatePage(bag, true)}.
+     *
      * @param bag Reuse bag.
      * @return Allocated page.
      * @throws IgniteCheckedException If failed.
      */
     protected final long allocatePage(ReuseBag bag) throws 
IgniteCheckedException {
+        return allocatePage(bag, true);
+    }
+
+    /**
+     * @param bag Reuse Bag.
+     * @param useRecycled Use recycled page.
+     * @return Allocated page.
+     * @throws IgniteCheckedException If failed.
+     */
+    protected final long allocatePage(ReuseBag bag, boolean useRecycled) 
throws IgniteCheckedException {
         long pageId = bag != null ? bag.pollFreePage() : 0;
 
-        if (pageId == 0 && reuseList != null)
+        if (pageId == 0 && useRecycled && reuseList != null)
             pageId = reuseList.takeRecycledPage();
 
         if (pageId == 0)

http://git-wip-us.apache.org/repos/asf/ignite/blob/df238634/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java
index 54ffb3e..ed77674 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java
@@ -404,12 +404,13 @@ public abstract class PagesList extends DataStructure {
      * Adds stripe to the given bucket.
      *
      * @param bucket Bucket.
+     * @param bag Reuse bag.
      * @param reuse {@code True} if possible to use reuse list.
      * @throws IgniteCheckedException If failed.
      * @return Tail page ID.
      */
-    private Stripe addStripe(int bucket, boolean reuse) throws 
IgniteCheckedException {
-        long pageId = reuse ? allocatePage(null) : allocatePageNoReuse();
+    private Stripe addStripe(int bucket, ReuseBag bag, boolean reuse) throws 
IgniteCheckedException {
+        long pageId = allocatePage(bag, reuse);
 
         init(pageId, PagesListNodeIO.VERSIONS.latest());
 
@@ -500,10 +501,11 @@ public abstract class PagesList extends DataStructure {
 
     /**
      * @param bucket Bucket.
+     * @param bag Reuse bag.
      * @return Page ID where the given page
      * @throws IgniteCheckedException If failed.
      */
-    private Stripe getPageForPut(int bucket) throws IgniteCheckedException {
+    private Stripe getPageForPut(int bucket, ReuseBag bag) throws 
IgniteCheckedException {
         // Striped pool optimization.
         IgniteThread igniteThread = IgniteThread.current();
 
@@ -515,7 +517,7 @@ public abstract class PagesList extends DataStructure {
             assert stripeIdx != -1 : igniteThread;
 
             while (tails == null || stripeIdx >= tails.length) {
-                addStripe(bucket, true);
+                addStripe(bucket, bag, true);
 
                 tails = getBucket(bucket);
             }
@@ -524,7 +526,7 @@ public abstract class PagesList extends DataStructure {
         }
 
         if (tails == null)
-            return addStripe(bucket, true);
+            return addStripe(bucket, bag, true);
 
         return randomTail(tails);
     }
@@ -613,16 +615,25 @@ public abstract class PagesList extends DataStructure {
         assert bag == null ^ dataAddr == 0L;
 
         for (int lockAttempt = 0; ;) {
-            Stripe stripe = getPageForPut(bucket);
+            Stripe stripe = getPageForPut(bucket, bag);
+
+            // No need to continue if bag has been utilized at getPageForPut.
+            if (bag != null && bag.isEmpty())
+                return;
 
             final long tailId = stripe.tailId;
             final long tailPage = acquirePage(tailId);
 
             try {
-                long tailAddr = writeLockPage(tailId, tailPage, bucket, 
lockAttempt++); // Explicit check.
+                long tailAddr = writeLockPage(tailId, tailPage, bucket, 
lockAttempt++, bag); // Explicit check.
 
-                if (tailAddr == 0L)
-                    continue;
+                if (tailAddr == 0L) {
+                    // No need to continue if bag has been utilized at 
writeLockPage.
+                    if (bag != null && bag.isEmpty())
+                        return;
+                    else
+                        continue;
+                }
 
                 assert PageIO.getPageId(tailAddr) == tailId : "pageId = " + 
PageIO.getPageId(tailAddr) + ", tailId = " + tailId;
                 assert PageIO.getType(tailAddr) == PageIO.T_PAGE_LIST_NODE;
@@ -826,6 +837,9 @@ public abstract class PagesList extends DataStructure {
         ReuseBag bag,
         int bucket
     ) throws IgniteCheckedException {
+        assert bag != null : "bag is null";
+        assert !bag.isEmpty() : "bag is empty";
+
         if (io.getNextId(pageAddr) != 0L)
             return false; // Splitted.
 
@@ -963,10 +977,11 @@ public abstract class PagesList extends DataStructure {
      * @param page Page pointer.
      * @param bucket Bucket.
      * @param lockAttempt Lock attempts counter.
+     * @param bag Reuse bag.
      * @return Page address if page is locked of {@code null} if can retry 
lock.
      * @throws IgniteCheckedException If failed.
      */
-    private long writeLockPage(long pageId, long page, int bucket, int 
lockAttempt)
+    private long writeLockPage(long pageId, long page, int bucket, int 
lockAttempt, ReuseBag bag)
         throws IgniteCheckedException {
         // Striped pool optimization.
         IgniteThread igniteThread = IgniteThread.current();
@@ -986,7 +1001,7 @@ public abstract class PagesList extends DataStructure {
             Stripe[] stripes = getBucket(bucket);
 
             if (stripes == null || stripes.length < MAX_STRIPES_PER_BUCKET) {
-                addStripe(bucket, !isReuseBucket(bucket));
+                addStripe(bucket, bag, !isReuseBucket(bucket));
 
                 return 0L;
             }
@@ -1012,7 +1027,7 @@ public abstract class PagesList extends DataStructure {
             final long tailPage = acquirePage(tailId);
 
             try {
-                long tailAddr = writeLockPage(tailId, tailPage, bucket, 
lockAttempt++); // Explicit check.
+                long tailAddr = writeLockPage(tailId, tailPage, bucket, 
lockAttempt++, null); // Explicit check.
 
                 if (tailAddr == 0L)
                     continue;
@@ -1471,6 +1486,11 @@ public abstract class PagesList extends DataStructure {
         }
 
         /** {@inheritDoc} */
+        @Override public boolean isEmpty() {
+            return pageId == 0L;
+        }
+
+        /** {@inheritDoc} */
         @Override public String toString() {
             return S.toString(SingletonReuseBag.class, this, "pageId", 
U.hexLong(pageId));
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/df238634/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/BPlusTree.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/BPlusTree.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/BPlusTree.java
index 6b87d32..a520dce 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/BPlusTree.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/BPlusTree.java
@@ -3312,6 +3312,20 @@ public abstract class BPlusTree<L, T extends L> extends 
DataStructure implements
         }
 
         /** {@inheritDoc} */
+        @Override public boolean isEmpty() {
+            if (freePages == null)
+                return true;
+
+            if (freePages.getClass() == GridLongList.class) {
+                GridLongList list = ((GridLongList)freePages);
+
+                return list.isEmpty();
+            }
+
+            return false;
+        }
+
+        /** {@inheritDoc} */
         @Override boolean notFound(BPlusIO<L> io, long pageAddr, int idx, int 
lvl) {
             if (lvl == 0) {
                 assert tail == null;

http://git-wip-us.apache.org/repos/asf/ignite/blob/df238634/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/reuse/ReuseBag.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/reuse/ReuseBag.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/reuse/ReuseBag.java
index 843eccf..aa716a4 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/reuse/ReuseBag.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/reuse/ReuseBag.java
@@ -30,4 +30,9 @@ public interface ReuseBag {
      * @return Free page ID for reuse or {@code 0} if empty.
      */
     public long pollFreePage();
+
+    /**
+     * @return {@code true} if no contained page IDs for reuse.
+     */
+    public boolean isEmpty();
 }

Reply via email to