You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2018/04/05 12:43:50 UTC

ignite git commit: IGNITE-8139: SQL: Size limit for SQL on-heap row cache. This closes #3752.

Repository: ignite
Updated Branches:
  refs/heads/master 1dded3ae8 -> 635e9a697


IGNITE-8139: SQL: Size limit for SQL on-heap row cache. This closes #3752.


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

Branch: refs/heads/master
Commit: 635e9a69720f882ff5b5786c4d9e608f78c2defd
Parents: 1dded3a
Author: devozerov <vo...@gridgain.com>
Authored: Thu Apr 5 15:43:44 2018 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Thu Apr 5 15:43:44 2018 +0300

----------------------------------------------------------------------
 .../configuration/CacheConfiguration.java       | 37 +++++++++++
 .../processors/query/h2/H2RowCache.java         | 21 ++++--
 .../processors/query/h2/H2RowCacheRegistry.java |  2 +-
 .../cache/index/H2RowCacheSelfTest.java         | 69 +++++++++++++++++++-
 .../ApiParity/CacheConfigurationParityTest.cs   |  3 +-
 5 files changed, 123 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/635e9a69/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java b/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
index 2769b81..2e35f37 100644
--- a/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
+++ b/modules/core/src/main/java/org/apache/ignite/configuration/CacheConfiguration.java
@@ -184,6 +184,9 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
     /** Default value for events disabled flag. */
     public static final boolean DFLT_EVENTS_DISABLED = false;
 
+    /** Default SQL on-heap cache size. */
+    public static final int DFLT_SQL_ONHEAP_CACHE_MAX_SIZE = 0;
+
     /** Cache name. */
     private String name;
 
@@ -216,6 +219,9 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
     /** Use on-heap cache for rows for SQL queries. */
     private boolean sqlOnheapCache;
 
+    /** SQL on-heap cache max size. */
+    private int sqlOnheapCacheMaxSize = DFLT_SQL_ONHEAP_CACHE_MAX_SIZE;
+
     /** Eviction filter. */
     private EvictionFilter<?, ?> evictFilter;
 
@@ -459,6 +465,7 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
         storeConcurrentLoadAllThreshold = cc.getStoreConcurrentLoadAllThreshold();
         maxQryIterCnt = cc.getMaxQueryIteratorsCount();
         sqlOnheapCache = cc.isSqlOnheapCacheEnabled();
+        sqlOnheapCacheMaxSize = cc.getSqlOnheapCacheMaxSize();
         evtsDisabled = cc.isEventsDisabled();
     }
 
@@ -665,6 +672,36 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
     }
 
     /**
+     * Gets maximum SQL on-heap cache. Measured in number of rows. When maximum size is reached oldest cached rows
+     * will be evicted.
+     * <p>
+     * Zero or negative value stand for unlimited size.
+     * <p>
+     * Defaults to {@link #DFLT_SQL_ONHEAP_CACHE_MAX_SIZE}.
+     *
+     * @return SQL on-heap cache max size.
+     */
+    public int getSqlOnheapCacheMaxSize() {
+        return sqlOnheapCacheMaxSize;
+    }
+
+    /**
+     * Sets maximum SQL on-heap cache. Measured in number of rows. When maximum size is reached oldest cached rows
+     * will be evicted.
+     * <p>
+     * Zero or negative value stand for unlimited size.
+     * <p>
+     * Defaults to {@link #DFLT_SQL_ONHEAP_CACHE_MAX_SIZE}.
+     *
+     * @return {@code this} for chaining.
+     */
+    public CacheConfiguration<K, V> setSqlOnheapCacheMaxSize(int sqlOnheapCacheMaxSize) {
+        this.sqlOnheapCacheMaxSize = sqlOnheapCacheMaxSize;
+
+        return this;
+    }
+
+    /**
      * @return Near enabled flag.
      */
     public NearCacheConfiguration<K, V> getNearConfiguration() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/635e9a69/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2RowCache.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2RowCache.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2RowCache.java
index 2c3a95f..06a3251 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2RowCache.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2RowCache.java
@@ -17,9 +17,6 @@
 
 package org.apache.ignite.internal.processors.query.h2;
 
-import java.util.Iterator;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.internal.pagemem.PageIdUtils;
 import org.apache.ignite.internal.pagemem.PageMemory;
@@ -28,13 +25,20 @@ import org.apache.ignite.internal.processors.cache.GridCacheContext;
 import org.apache.ignite.internal.processors.query.GridQueryRowCacheCleaner;
 import org.apache.ignite.internal.processors.query.h2.opt.GridH2KeyValueRowOnheap;
 import org.apache.ignite.internal.util.typedef.F;
+import org.jsr166.ConcurrentLinkedHashMap;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import static org.jsr166.ConcurrentLinkedHashMap.DFLT_INIT_CAP;
+import static org.jsr166.ConcurrentLinkedHashMap.DFLT_LOAD_FACTOR;
 
 /**
  * H2 row cache.
  */
 public class H2RowCache implements GridQueryRowCacheCleaner {
     /** Cached rows. */
-    private ConcurrentHashMap<Long, GridH2KeyValueRowOnheap> rows = new ConcurrentHashMap<>();
+    private final ConcurrentLinkedHashMap<Long, GridH2KeyValueRowOnheap> rows;
 
     /** Cache group ID. */
     private final CacheGroupContext grpCtx;
@@ -45,8 +49,15 @@ public class H2RowCache implements GridQueryRowCacheCleaner {
     /**
      * @param grpCtx Cache group context.
      */
-    public H2RowCache(CacheGroupContext grpCtx) {
+    public H2RowCache(CacheGroupContext grpCtx, int maxSize) {
         this.grpCtx = grpCtx;
+
+        rows = new ConcurrentLinkedHashMap<Long, GridH2KeyValueRowOnheap>(
+            DFLT_INIT_CAP,
+            DFLT_LOAD_FACTOR,
+            Runtime.getRuntime().availableProcessors(),
+            maxSize
+        );
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/635e9a69/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2RowCacheRegistry.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2RowCacheRegistry.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2RowCacheRegistry.java
index 9b1a03c..39f3329 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2RowCacheRegistry.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2RowCacheRegistry.java
@@ -68,7 +68,7 @@ public class H2RowCacheRegistry {
 
             HashMap<Integer, H2RowCache> caches0 = copy();
 
-            H2RowCache rowCache = new H2RowCache(cctx.group());
+            H2RowCache rowCache = new H2RowCache(cctx.group(), cctx.config().getSqlOnheapCacheMaxSize());
 
             caches0.put(grpId, rowCache);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/635e9a69/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2RowCacheSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2RowCacheSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2RowCacheSelfTest.java
index f3bb719..5db8231 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2RowCacheSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2RowCacheSelfTest.java
@@ -23,11 +23,13 @@ import java.util.List;
 import java.util.Map;
 import java.util.Random;
 import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
 import javax.cache.Cache;
+
+import org.apache.ignite.IgniteCache;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteDataStreamer;
 import org.apache.ignite.cache.QueryEntity;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
 import org.apache.ignite.cache.query.SqlQuery;
 import org.apache.ignite.cache.query.annotations.QuerySqlField;
 import org.apache.ignite.configuration.CacheConfiguration;
@@ -36,10 +38,12 @@ import org.apache.ignite.internal.processors.query.h2.H2RowCache;
 import org.apache.ignite.internal.processors.query.h2.opt.GridH2KeyValueRowOnheap;
 import org.apache.ignite.testframework.GridTestUtils;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.jsr166.ConcurrentLinkedHashMap;
 
 /**
  * Tests H2RowCacheRegistry.
  */
+@SuppressWarnings({"unchecked", "ConstantConditions"})
 public class H2RowCacheSelfTest extends GridCommonAbstractTest {
     /** Keys count. */
     private static final int ENTRIES = 1_000;
@@ -141,6 +145,67 @@ public class H2RowCacheSelfTest extends GridCommonAbstractTest {
     }
 
     /**
+     * @throws Exception If failed.
+     */
+    public void testFixedSize() throws Exception {
+        int maxSize = 100;
+        String cacheName = "cacheWithLimitedSize";
+
+        CacheConfiguration ccfg = cacheConfiguration(cacheName, true).setSqlOnheapCacheMaxSize(maxSize);
+
+        IgniteCache cache = grid().getOrCreateCache(ccfg);
+
+        int grpId = grid().cachex(cacheName).context().groupId();
+
+        // Fill half.
+        for (int i = 0; i < maxSize / 2; i++)
+            cache.put(i, new Value(1));
+
+        H2RowCache rowCache = rowCache(grid(), grpId);
+
+        assertEquals(0, rowCache.size());
+
+        // Warmup cache.
+        cache.query(new SqlFieldsQuery("SELECT * FROM Value")).getAll();
+
+        assertEquals(maxSize / 2, rowCache.size());
+
+        // Query again - are there any leaks?
+        cache.query(new SqlFieldsQuery("SELECT * FROM Value")).getAll();
+
+        assertEquals(maxSize / 2, rowCache.size());
+
+        // Fill up to limit.
+        for (int i = maxSize / 2; i < maxSize; i++)
+            cache.put(i, new Value(1));
+
+        assertEquals(maxSize / 2, rowCache.size());
+
+        cache.query(new SqlFieldsQuery("SELECT * FROM Value")).getAll();
+
+        assertEquals(maxSize, rowCache.size());
+
+        // Out of limit.
+        for (int i = maxSize; i < maxSize * 2; i++)
+            cache.put(i, new Value(1));
+
+        assertEquals(maxSize, rowCache.size());
+
+        cache.query(new SqlFieldsQuery("SELECT * FROM Value")).getAll();
+
+        assertEquals(maxSize, rowCache.size());
+
+        // Delete all.
+        cache.query(new SqlFieldsQuery("DELETE FROM Value")).getAll();
+
+        assertEquals(0, rowCache.size());
+
+        cache.query(new SqlFieldsQuery("SELECT * FROM Value")).getAll();
+
+        assertEquals(0, rowCache.size());
+    }
+
+    /**
      * @throws IgniteCheckedException If failed.
      */
     private void checkDestroyCache() throws IgniteCheckedException {
@@ -287,7 +352,7 @@ public class H2RowCacheSelfTest extends GridCommonAbstractTest {
         grid().cache(cacheName)
             .query(new SqlQuery(Value.class, "_key = " + key)).getAll().size();
 
-        ConcurrentHashMap<Long, GridH2KeyValueRowOnheap> rowsMap = GridTestUtils.getFieldValue(rowCache, "rows");
+        ConcurrentLinkedHashMap<Long, GridH2KeyValueRowOnheap> rowsMap = GridTestUtils.getFieldValue(rowCache, "rows");
 
         for (Map.Entry<Long, GridH2KeyValueRowOnheap> e : rowsMap.entrySet()) {
             GridH2KeyValueRowOnheap val = e.getValue();

http://git-wip-us.apache.org/repos/asf/ignite/blob/635e9a69/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ApiParity/CacheConfigurationParityTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ApiParity/CacheConfigurationParityTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ApiParity/CacheConfigurationParityTest.cs
index 94f52ce..32509c2 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ApiParity/CacheConfigurationParityTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/ApiParity/CacheConfigurationParityTest.cs
@@ -58,7 +58,8 @@ namespace Apache.Ignite.Core.Tests.ApiParity
         {
             "NodeFilter",  // IGNITE-2890
             "EvictionPolicyFactory",  // IGNITE-6649,
-            "isSqlOnheapCacheEnabled",  // IGNITE-7379
+            "isSqlOnheapCacheEnabled",  // IGNITE-7379,
+            "SqlOnheapCacheMaxSize", // IGNITE-7379,
             "isEventsDisabled"  // IGNITE-7346
         };