You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2017/03/02 07:51:43 UTC

[2/3] ignite git commit: ignite-db-x fix memory leak on destroy cache

ignite-db-x fix memory leak on destroy cache


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

Branch: refs/heads/ignite-3477
Commit: fa3eab3391794d08d61c84d8d4530ec51959b34e
Parents: 718da72
Author: Dmitriy Govorukhin <dg...@gridgain.com>
Authored: Tue Feb 28 20:04:06 2017 +0300
Committer: Dmitriy Govorukhin <dg...@gridgain.com>
Committed: Tue Feb 28 20:04:06 2017 +0300

----------------------------------------------------------------------
 .../cache/IgniteCacheOffheapManagerImpl.java    | 33 +++++++++++++++++++-
 .../cache/database/tree/BPlusTree.java          | 18 +++++++++++
 .../cache/database/tree/io/BPlusIO.java         |  9 ++++++
 3 files changed, 59 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/fa3eab33/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
index 5df99b6..aa6fb94 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
@@ -23,6 +23,7 @@ import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
 import javax.cache.Cache;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteException;
@@ -68,6 +69,7 @@ import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.lang.IgniteClosure;
+import org.apache.ignite.lang.IgniteInClosure;
 import org.apache.ignite.lang.IgnitePredicate;
 import org.jetbrains.annotations.Nullable;
 
@@ -1071,7 +1073,28 @@ public class IgniteCacheOffheapManagerImpl extends GridCacheManagerAdapter imple
 
         /** {@inheritDoc} */
         @Override public void destroy() throws IgniteCheckedException {
-            dataTree.destroy();
+            final AtomicReference<IgniteCheckedException> exception = new AtomicReference<>();
+
+            dataTree.destroy(new IgniteInClosure<CacheSearchRow>() {
+                @Override public void apply(CacheSearchRow row) {
+                    try {
+                        rowStore.removeRow(row.link());
+                    }
+                    catch (IgniteCheckedException e) {
+                        U.error(log, "Fail remove row [link=" + row.link() + "]");
+
+                        IgniteCheckedException ex = exception.get();
+
+                        if (ex == null)
+                            exception.set(e);
+                        else
+                            ex.addSuppressed(e);
+                    }
+                }
+            });
+
+            if (exception.get() != null)
+                throw new IgniteCheckedException("Fail destroy store", exception.get());
         }
 
         /** {@inheritDoc} */
@@ -1595,6 +1618,14 @@ public class IgniteCacheOffheapManagerImpl extends GridCacheManagerAdapter imple
         @Override public int getHash(long pageAddr, int idx) {
             return PageUtils.getInt(pageAddr, offset(idx) + 8);
         }
+
+        /** {@inheritDoc} */
+        @Override public void visit(long pageAddr, IgniteInClosure<CacheSearchRow> c) {
+            int cnt = getCount(pageAddr);
+
+            for (int i = 0; i < cnt; i++)
+                c.apply(new CacheDataRowAdapter(getLink(pageAddr, i)));
+        }
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/fa3eab33/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 aa61fbd..f1c16aa 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
@@ -63,6 +63,7 @@ import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.SB;
 import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteInClosure;
 
 import static org.apache.ignite.internal.processors.cache.database.tree.BPlusTree.Bool.DONE;
 import static org.apache.ignite.internal.processors.cache.database.tree.BPlusTree.Bool.FALSE;
@@ -1795,6 +1796,20 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure implements
      * @throws IgniteCheckedException If failed.
      */
     public final long destroy() throws IgniteCheckedException {
+        return destroy(null);
+    }
+
+    /**
+     * Destroys tree. This method is allowed to be invoked only when the tree is out of use (no concurrent operations
+     * are trying to read or update the tree after destroy beginning).
+     *
+     * @param c Visitor closure. Visits only leaf pages.
+     * @return Number of pages recycled from this tree. If the tree was destroyed by someone else concurrently returns
+     *     {@code 0}, otherwise it should return at least {@code 2} (for meta page and root page), unless this tree is
+     *     used as metadata storage, or {@code -1} if we don't have a reuse list and did not do recycling at all.
+     * @throws IgniteCheckedException If failed.
+     */
+    public final long destroy(IgniteInClosure<L> c) throws IgniteCheckedException {
         if (!markDestroyed())
             return 0;
 
@@ -1819,6 +1834,9 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure implements
                             try {
                                 BPlusIO<L> io = io(pageAddr);
 
+                                if (c != null && io.isLeaf())
+                                    io.visit(pageAddr, c);
+
                                 long fwdPageId = io.getForward(pageAddr);
 
                                 bag.addFreePage(recyclePage(pageId, page, pageAddr));

http://git-wip-us.apache.org/repos/asf/ignite/blob/fa3eab33/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/io/BPlusIO.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/io/BPlusIO.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/io/BPlusIO.java
index bcf2908..fe1a0d0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/io/BPlusIO.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/io/BPlusIO.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.processors.cache.database.tree.io;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.internal.pagemem.PageUtils;
 import org.apache.ignite.internal.processors.cache.database.tree.BPlusTree;
+import org.apache.ignite.lang.IgniteInClosure;
 
 /**
  * Abstract IO routines for B+Tree pages.
@@ -391,4 +392,12 @@ public abstract class BPlusIO<L> extends PageIO {
     private static void putBytes(long pageAddr, int pos, byte[] bytes) {
         PageUtils.putBytes(pageAddr, pos, bytes);
     }
+
+    /**
+     * @param pageAddr Page address.
+     * @param c Closure.
+     */
+    public void visit(long pageAddr, IgniteInClosure<L> c) {
+        // No-op.
+    }
 }