GG-11044 - Implement page evictions from PageMemory for the case when data size 
is bigger than allocated memory.

Fix.


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

Branch: refs/heads/ignite-db-x-10884
Commit: 99915a6d8e22e01eff4244bc56b2be5be033bb7e
Parents: d2fedf6
Author: dkarachentsev <[email protected]>
Authored: Fri Apr 22 16:51:10 2016 +0300
Committer: dkarachentsev <[email protected]>
Committed: Fri Apr 22 16:51:10 2016 +0300

----------------------------------------------------------------------
 .../internal/pagemem/impl/PageMemoryImpl.java   | 58 ++++++++++++++++++--
 1 file changed, 52 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/99915a6d/modules/core/src/main/java/org/apache/ignite/internal/pagemem/impl/PageMemoryImpl.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/impl/PageMemoryImpl.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/impl/PageMemoryImpl.java
index 62a4e72..5ee8bf3 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/impl/PageMemoryImpl.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/impl/PageMemoryImpl.java
@@ -22,6 +22,7 @@ import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.util.ArrayList;
+import java.util.BitSet;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
@@ -944,11 +945,13 @@ public class  PageMemoryImpl implements PageMemory {
 
         final int cap = seg.loadedPages.capacity();
 
-        assert seg.loadedPages.size() >= RANDOM_PAGES_EVICT_NUM;
-
         if (seg.acquiredPages.size() >= seg.loadedPages.size())
             throw new OutOfMemoryException("No not acquired pages left for 
segment. Unable to evict.");
 
+        // With big number of random picked pages we may fall into infinite 
loop, because
+        // every time the same page may be found.
+        SimpleLongSet ignored = null;
+
         while (true) {
             for (int i = 0; i < RANDOM_PAGES_EVICT_NUM; i++) {
                 // We need to lookup for pages only in current segment for 
thread safety,
@@ -958,7 +961,10 @@ public class  PageMemoryImpl implements PageMemory {
 
                 assert addr != INVALID_REL_PTR;
 
-                pageRelAddrs[i] = addr;
+                if (ignored != null && ignored.contains(addr))
+                    i--;
+                else
+                    pageRelAddrs[i] = addr;
             }
 
             final long relEvictAddr = findSuitablePageRelAddr(pageRelAddrs);
@@ -967,16 +973,31 @@ public class  PageMemoryImpl implements PageMemory {
 
             final long absEvictAddr = absolute(relEvictAddr);
 
-            assert absEvictAddr != dbMetaPageIdPtr;
-
             final FullPageId fullPageId = readFullPageId(absEvictAddr);
 
+            final long metaPageId = mem.readLong(dbMetaPageIdPtr);
+
+            if (fullPageId.pageId() == metaPageId && fullPageId.cacheId() == 
0) {
+                if (ignored == null)
+                    ignored = new SimpleLongSet();
+
+                ignored.add(relEvictAddr);
+
+                continue;
+            }
+
             assert seg.writeLock().isHeldByCurrentThread();
 
             if (!seg.acquiredPages.containsKey(fullPageId))
                 seg.loadedPages.remove(fullPageId);
-            else
+            else {
+                if (ignored == null)
+                    ignored = new SimpleLongSet();
+
+                ignored.add(relEvictAddr);
+
                 continue;
+            }
 
             // Force flush data and free page.
             if (isDirty(absEvictAddr)) {
@@ -1039,6 +1060,31 @@ public class  PageMemoryImpl implements PageMemory {
     }
 
     /**
+     * Long set based on BitSet.
+     */
+    private static class SimpleLongSet {
+        /** */
+        final BitSet bitSet = new BitSet();
+
+        /**
+         * Add value to set.
+         *
+         * @param val Value.
+         */
+        void add(final long val) {
+            bitSet.set((int)(val % Integer.MAX_VALUE));
+        }
+
+        /**
+         * @param val Value to check.
+         * @return {@code True} if set contains value.
+         */
+        boolean contains(final long val) {
+            return bitSet.get((int)(val % Integer.MAX_VALUE));
+        }
+    }
+
+    /**
      *
      */
     private class Segment extends ReentrantReadWriteLock {

Reply via email to