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
};