IGNITE-6004: Added QuerySqlField.inlineSize property. This closes #2420.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/621380db Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/621380db Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/621380db Branch: refs/heads/ignite-5947 Commit: 621380dbec5d1b9dcff626bb1686ad75361f7ed8 Parents: 305c0f4 Author: tledkov-gridgain <[email protected]> Authored: Tue Aug 15 11:19:37 2017 +0300 Committer: devozerov <[email protected]> Committed: Tue Aug 15 11:20:56 2017 +0300 ---------------------------------------------------------------------- .../org/apache/ignite/cache/QueryEntity.java | 15 +- .../org/apache/ignite/cache/QueryIndex.java | 5 +- .../query/annotations/QueryGroupIndex.java | 20 +++ .../cache/query/annotations/QuerySqlField.java | 23 +++ .../cache/query/QueryEntityTypeDescriptor.java | 17 +- ...ridCacheQuerySqlFieldInlineSizeSelfTest.java | 160 +++++++++++++++++++ .../IgniteCacheQuerySelfTestSuite.java | 3 + 7 files changed, 226 insertions(+), 17 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/621380db/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java b/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java index 5180100..6440b48 100644 --- a/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java +++ b/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java @@ -419,6 +419,7 @@ public class QueryEntity implements Serializable { sortedIdx.setFields(fields); sortedIdx.setName(idxEntry.getKey()); + sortedIdx.setInlineSize(idx.inlineSize()); idxs.add(sortedIdx); } @@ -480,7 +481,7 @@ public class QueryEntity implements Serializable { String idxName = cls.getSimpleName() + "_" + QueryUtils.VAL_FIELD_NAME + "_idx"; type.addIndex(idxName, QueryUtils.isGeometryClass(cls) ? - QueryIndexType.GEOSPATIAL : QueryIndexType.SORTED); + QueryIndexType.GEOSPATIAL : QueryIndexType.SORTED, QueryIndex.DFLT_INLINE_SIZE); type.addFieldToIndex(idxName, QueryUtils.VAL_FIELD_NAME, 0, false); } @@ -500,13 +501,13 @@ public class QueryEntity implements Serializable { QueryGroupIndex grpIdx = cls.getAnnotation(QueryGroupIndex.class); if (grpIdx != null) - type.addIndex(grpIdx.name(), QueryIndexType.SORTED); + type.addIndex(grpIdx.name(), QueryIndexType.SORTED, grpIdx.inlineSize()); QueryGroupIndex.List grpIdxList = cls.getAnnotation(QueryGroupIndex.List.class); if (grpIdxList != null && !F.isEmpty(grpIdxList.value())) { for (QueryGroupIndex idx : grpIdxList.value()) - type.addIndex(idx.name(), QueryIndexType.SORTED); + type.addIndex(idx.name(), QueryIndexType.SORTED, idx.inlineSize()); } } @@ -559,11 +560,17 @@ public class QueryEntity implements Serializable { idxName = cls.getSimpleName() + "_" + idxName; desc.addIndex(idxName, QueryUtils.isGeometryClass(prop.type()) ? - QueryIndexType.GEOSPATIAL : QueryIndexType.SORTED); + QueryIndexType.GEOSPATIAL : QueryIndexType.SORTED, sqlAnn.inlineSize()); desc.addFieldToIndex(idxName, prop.fullName(), 0, sqlAnn.descending()); } + if ((!F.isEmpty(sqlAnn.groups()) || !F.isEmpty(sqlAnn.orderedGroups())) + && sqlAnn.inlineSize() != QueryIndex.DFLT_INLINE_SIZE) { + throw new CacheException("Inline size cannot be set on a field with group index [" + + "type=" + cls.getName() + ", property=" + prop.fullName() + ']'); + } + if (!F.isEmpty(sqlAnn.groups())) { for (String group : sqlAnn.groups()) desc.addFieldToIndex(group, prop.fullName(), 0, false); http://git-wip-us.apache.org/repos/asf/ignite/blob/621380db/modules/core/src/main/java/org/apache/ignite/cache/QueryIndex.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/QueryIndex.java b/modules/core/src/main/java/org/apache/ignite/cache/QueryIndex.java index 6e73049..ac7dd8e 100644 --- a/modules/core/src/main/java/org/apache/ignite/cache/QueryIndex.java +++ b/modules/core/src/main/java/org/apache/ignite/cache/QueryIndex.java @@ -38,6 +38,9 @@ public class QueryIndex implements Serializable { /** */ private static final QueryIndexType DFLT_IDX_TYP = QueryIndexType.SORTED; + /** Default index inline size. */ + public static final int DFLT_INLINE_SIZE = -1; + /** Index name. */ private String name; @@ -49,7 +52,7 @@ public class QueryIndex implements Serializable { private QueryIndexType type = DFLT_IDX_TYP; /** */ - private int inlineSize = -1; + private int inlineSize = DFLT_INLINE_SIZE; /** * Creates an empty index. Should be populated via setters. http://git-wip-us.apache.org/repos/asf/ignite/blob/621380db/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QueryGroupIndex.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QueryGroupIndex.java b/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QueryGroupIndex.java index b1fefae..a947d0f 100644 --- a/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QueryGroupIndex.java +++ b/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QueryGroupIndex.java @@ -21,6 +21,8 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.apache.ignite.cache.QueryIndex; +import org.apache.ignite.configuration.CacheConfiguration; /** * Describes group index. @@ -36,6 +38,24 @@ public @interface QueryGroupIndex { String name(); /** + * Index inline size in bytes. When enabled part of indexed value will be placed directly to index pages, + * thus minimizing data page accesses, thus incraesing query performance. + * <p> + * Allowed values: + * <ul> + * <li>{@code -1} (default) - determine inline size automatically (see below)</li> + * <li>{@code 0} - index inline is disabled (not recommended)</li> + * <li>positive value - fixed index inline</li> + * </ul> + * When set to {@code -1}, Ignite will try to detect inline size automatically. It will be no more than + * {@link CacheConfiguration#getSqlIndexMaxInlineSize()}. Index inline will be enabled for all fixed-length types, + * but <b>will not be enabled</b> for {@code String}. + * + * @return Index inline size in bytes. + */ + int inlineSize() default QueryIndex.DFLT_INLINE_SIZE; + + /** * List of group indexes for type. */ @SuppressWarnings("PublicInnerClass") http://git-wip-us.apache.org/repos/asf/ignite/blob/621380db/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QuerySqlField.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QuerySqlField.java b/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QuerySqlField.java index 94dbea1..64aaa3a 100644 --- a/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QuerySqlField.java +++ b/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QuerySqlField.java @@ -22,6 +22,8 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.apache.ignite.cache.QueryIndex; +import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.internal.processors.cache.query.CacheQuery; /** @@ -88,6 +90,27 @@ public @interface QuerySqlField { String name() default ""; /** + * Index inline size in bytes. When enabled part of indexed value will be placed directly to index pages, + * thus minimizing data page accesses, thus incraesing query performance. + * <p> + * Allowed values: + * <ul> + * <li>{@code -1} (default) - determine inline size automatically (see below)</li> + * <li>{@code 0} - index inline is disabled (not recommended)</li> + * <li>positive value - fixed index inline</li> + * </ul> + * When set to {@code -1}, Ignite will try to detect inline size automatically. It will be no more than + * {@link CacheConfiguration#getSqlIndexMaxInlineSize()}. Index inline will be enabled for all fixed-length types, + * but <b>will not be enabled</b> for {@code String}. + * <p> + * When index group is used, inline size must be defined in {@link QueryGroupIndex#inlineSize()}. Any value + * except of {@code -1} defined on a specific column will lead to exception. + * + * @return Index inline size in bytes. + */ + int inlineSize() default QueryIndex.DFLT_INLINE_SIZE; + + /** * Describes group of index and position of field in this group. * <p> * Opposite to {@link #groups()} this annotation gives control over order of fields in a group index. http://git-wip-us.apache.org/repos/asf/ignite/blob/621380db/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityTypeDescriptor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityTypeDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityTypeDescriptor.java index 47ab263..837a08f 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityTypeDescriptor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityTypeDescriptor.java @@ -24,6 +24,7 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import javax.cache.CacheException; +import org.apache.ignite.cache.QueryIndex; import org.apache.ignite.cache.QueryIndexType; import org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor; import org.apache.ignite.internal.util.tostring.GridToStringExclude; @@ -78,6 +79,9 @@ public class QueryEntityTypeDescriptor { * @return Index descriptor. */ public QueryEntityIndexDescriptor addIndex(String idxName, QueryIndexType type, int inlineSize) { + if (inlineSize < 0 && inlineSize != QueryIndex.DFLT_INLINE_SIZE) + throw new CacheException("Illegal inline size [idxName=" + idxName + ", inlineSize=" + inlineSize + ']'); + QueryEntityIndexDescriptor idx = new QueryEntityIndexDescriptor(type, inlineSize); if (indexes.put(idxName, idx) != null) @@ -87,17 +91,6 @@ public class QueryEntityTypeDescriptor { } /** - * Adds index. - * - * @param idxName Index name. - * @param type Index type. - * @return Index descriptor. - */ - public QueryEntityIndexDescriptor addIndex(String idxName, QueryIndexType type) { - return addIndex(idxName, type, -1); - } - - /** * Adds field to index. * * @param idxName Index name. @@ -110,7 +103,7 @@ public class QueryEntityTypeDescriptor { QueryEntityIndexDescriptor desc = indexes.get(idxName); if (desc == null) - desc = addIndex(idxName, QueryIndexType.SORTED); + desc = addIndex(idxName, QueryIndexType.SORTED, QueryIndex.DFLT_INLINE_SIZE); desc.addField(field, orderNum, descending); } http://git-wip-us.apache.org/repos/asf/ignite/blob/621380db/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheQuerySqlFieldInlineSizeSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheQuerySqlFieldInlineSizeSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheQuerySqlFieldInlineSizeSelfTest.java new file mode 100644 index 0000000..a257160 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheQuerySqlFieldInlineSizeSelfTest.java @@ -0,0 +1,160 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.processors.cache; + +import java.util.concurrent.Callable; +import javax.cache.CacheException; +import org.apache.ignite.cache.QueryEntity; +import org.apache.ignite.cache.QueryIndex; +import org.apache.ignite.cache.query.annotations.QueryGroupIndex; +import org.apache.ignite.cache.query.annotations.QuerySqlField; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.testframework.GridTestUtils; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; + +/** + * Tests cache configuration with inlineSize property of the QuerySqlField annotation. + */ +@SuppressWarnings({"ThrowableResultOfMethodCallIgnored", "unchecked", "unused"}) +public class GridCacheQuerySqlFieldInlineSizeSelfTest extends GridCommonAbstractTest { + /** + * @throws Exception If failed. + */ + public void testSingleFieldIndexes() throws Exception { + CacheConfiguration ccfg = defaultCacheConfiguration(); + + ccfg.setIndexedTypes(Integer.class, TestValueSingleFieldIndexes.class); + + assertEquals(1, ccfg.getQueryEntities().size()); + + QueryEntity ent = (QueryEntity)ccfg.getQueryEntities().iterator().next(); + + assertEquals(2, ent.getIndexes().size()); + + for (QueryIndex idx : ent.getIndexes()) { + if(idx.getFields().containsKey("val0")) + assertEquals(10, idx.getInlineSize()); + else if(idx.getFields().containsKey("val1")) + assertEquals(20, idx.getInlineSize()); + } + } + + /** + * @throws Exception If failed. + */ + public void testGroupIndex() throws Exception { + CacheConfiguration ccfg = defaultCacheConfiguration(); + + ccfg.setIndexedTypes(Integer.class, TestValueGroupIndex.class); + + assertEquals(1, ccfg.getQueryEntities().size()); + + QueryEntity ent = (QueryEntity)ccfg.getQueryEntities().iterator().next(); + + assertEquals(1, ent.getIndexes().size()); + + QueryIndex idx = ent.getIndexes().iterator().next(); + + assertEquals(10, idx.getInlineSize()); + } + + /** + * @throws Exception If failed. + */ + public void testGroupIndexInvalidAnnotaion() throws Exception { + final CacheConfiguration ccfg = defaultCacheConfiguration(); + + GridTestUtils.assertThrows(log, new Callable<Object>() { + @Override public Object call() throws Exception { + ccfg.setIndexedTypes(Integer.class, TestValueGroupIndexInvalidAnnotation.class); + + return null; + } + }, CacheException.class, "Inline size cannot be set on a field with group index"); + } + + /** + * @throws Exception If failed. + */ + public void testNegativeInlineSize() throws Exception { + final CacheConfiguration ccfg = defaultCacheConfiguration(); + + GridTestUtils.assertThrows( + log, new Callable<Object>() { + + @Override public Object call() throws Exception { + ccfg.setIndexedTypes(Integer.class, TestValueNegativeInlineSize.class); + + return null; + } + }, + CacheException.class, + "Illegal inline size [idxName=TestValueNegativeInlineSize_val_idx, inlineSize=-10]" + ); + } + + /** + * + */ + static class TestValueSingleFieldIndexes { + /** */ + @QuerySqlField(index = true, inlineSize = 10) + String val0; + + /** */ + @QuerySqlField(index = true, inlineSize = 20) + String val1; + } + + /** + * + */ + @QueryGroupIndex(name="idx", inlineSize = 10) + static class TestValueGroupIndex { + /** */ + @QuerySqlField(orderedGroups = @QuerySqlField.Group(name = "idx", order = 0)) + String val0; + + /** */ + @QuerySqlField(orderedGroups = @QuerySqlField.Group(name = "idx", order = 1)) + String val1; + } + + /** + * + */ + @QueryGroupIndex(name="idx") + static class TestValueGroupIndexInvalidAnnotation { + /** */ + @QuerySqlField(orderedGroups = @QuerySqlField.Group(name = "idx", order = 0)) + String val0; + + /** */ + @QuerySqlField(orderedGroups = @QuerySqlField.Group(name = "idx", order = 1), inlineSize = 10) + String val1; + } + + /** + * + */ + static class TestValueNegativeInlineSize { + /** */ + @QuerySqlField(index = true, inlineSize = -10) + String val; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/621380db/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java index decc7d5..99b0370 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java +++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java @@ -39,6 +39,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheQueryIndexDisabledSe import org.apache.ignite.internal.processors.cache.GridCacheQueryIndexingDisabledSelfTest; import org.apache.ignite.internal.processors.cache.GridCacheQueryInternalKeysSelfTest; import org.apache.ignite.internal.processors.cache.GridCacheQuerySerializationSelfTest; +import org.apache.ignite.internal.processors.cache.GridCacheQuerySqlFieldInlineSizeSelfTest; import org.apache.ignite.internal.processors.cache.IgniteBinaryObjectFieldsQuerySelfTest; import org.apache.ignite.internal.processors.cache.IgniteBinaryObjectLocalQueryArgumentsTest; import org.apache.ignite.internal.processors.cache.IgniteBinaryObjectQueryArgumentsTest; @@ -320,6 +321,8 @@ public class IgniteCacheQuerySelfTestSuite extends TestSuite { suite.addTestSuite(IgniteSqlRoutingTest.class); suite.addTestSuite(LongIndexNameTest.class); + suite.addTestSuite(GridCacheQuerySqlFieldInlineSizeSelfTest.class); + return suite; } }
