This is an automated email from the ASF dual-hosted git repository.

nizhikov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 6b32ff03fa0 IGNITE-17025 Adjust inline size for fixed size index items 
(#10038)
6b32ff03fa0 is described below

commit 6b32ff03fa0663abec08a3974a792caca3fc5141
Author: Nikolay <[email protected]>
AuthorDate: Thu May 26 12:17:36 2022 +0300

    IGNITE-17025 Adjust inline size for fixed size index items (#10038)
---
 .../index/sorted/inline/InlineIndexKeyType.java    |  5 ++
 .../query/index/sorted/inline/InlineIndexTree.java | 34 +++++++--
 .../inline/types/NullableInlineIndexKeyType.java   |  5 ++
 .../processors/query/h2/IgniteH2Indexing.java      |  2 +-
 .../query/h2/index/client/ClientIndexFactory.java  | 25 ++++---
 .../cache/query/IndexQueryInlineSizesTest.java     |  9 ++-
 .../processors/query/SqlSystemViewsSelfTest.java   |  2 +-
 .../inlinecolumn/ComputeInlineSizeTest.java        | 80 +++++++++++++++++++++-
 8 files changed, 142 insertions(+), 20 deletions(-)

diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/sorted/inline/InlineIndexKeyType.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/sorted/inline/InlineIndexKeyType.java
index d6f90d1a733..31be38abb65 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/sorted/inline/InlineIndexKeyType.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/sorted/inline/InlineIndexKeyType.java
@@ -89,4 +89,9 @@ public interface InlineIndexKeyType {
      * than given respectively, or -2 if inlined part is not enough to compare.
      */
     public int compare(long pageAddr, int off, int maxSize, IndexKey v);
+
+    /**
+     * @return Size of key, in bytes. {@code -1} means variable length of key.
+     */
+    public short keySize();
 }
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/sorted/inline/InlineIndexTree.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/sorted/inline/InlineIndexTree.java
index 8af90a56bb5..48024a3dc2c 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/sorted/inline/InlineIndexTree.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/sorted/inline/InlineIndexTree.java
@@ -187,8 +187,13 @@ public class InlineIndexTree extends BPlusTree<IndexRow, 
IndexRow> {
             rowHnd = rowHndFactory.create(def, keyTypeSettings);
 
             inlineSize = computeInlineSize(
-                rowHnd.inlineIndexKeyTypes(), rowHnd.indexKeyDefinitions(),
-                configuredInlineSize, maxInlineSize);
+                def.idxName().fullName(),
+                rowHnd.inlineIndexKeyTypes(),
+                rowHnd.indexKeyDefinitions(),
+                configuredInlineSize,
+                maxInlineSize,
+                log
+            );
 
             setIos(inlineSize, mvccEnabled);
         }
@@ -417,17 +422,21 @@ public class InlineIndexTree extends BPlusTree<IndexRow, 
IndexRow> {
     }
 
     /**
+     * @param name Index name.
      * @param keyTypes Index key types.
      * @param keyDefs Index key definitions.
      * @param cfgInlineSize Inline size from index config.
      * @param maxInlineSize Max inline size from cache config.
+     * @param log Logger.
      * @return Inline size.
      */
     public static int computeInlineSize(
+        String name,
         List<InlineIndexKeyType> keyTypes,
         List<IndexKeyDefinition> keyDefs,
         int cfgInlineSize,
-        int maxInlineSize
+        int maxInlineSize,
+        IgniteLogger log
     ) {
         if (cfgInlineSize == 0)
             return 0;
@@ -435,8 +444,7 @@ public class InlineIndexTree extends BPlusTree<IndexRow, 
IndexRow> {
         if (F.isEmpty(keyTypes))
             return 0;
 
-        if (cfgInlineSize != -1)
-            return Math.min(PageIO.MAX_PAYLOAD_SIZE, cfgInlineSize);
+        boolean fixedSize = true;
 
         int propSize = maxInlineSize == -1
             ? 
IgniteSystemProperties.getInteger(IgniteSystemProperties.IGNITE_MAX_INDEX_PAYLOAD_SIZE,
 IGNITE_MAX_INDEX_PAYLOAD_SIZE_DEFAULT)
@@ -447,6 +455,8 @@ public class InlineIndexTree extends BPlusTree<IndexRow, 
IndexRow> {
         for (int i = 0; i < keyTypes.size(); i++) {
             InlineIndexKeyType keyType = keyTypes.get(i);
 
+            fixedSize &= keyType.keySize() != -1;
+
             int sizeInc = keyType.inlineSize();
 
             if (sizeInc < 0) {
@@ -467,6 +477,20 @@ public class InlineIndexTree extends BPlusTree<IndexRow, 
IndexRow> {
             }
         }
 
+        if (cfgInlineSize != -1) {
+            cfgInlineSize = Math.min(PageIO.MAX_PAYLOAD_SIZE, cfgInlineSize);
+
+            if (fixedSize && size < cfgInlineSize) {
+                log.warning("Explicit INLINE_SIZE for fixed size index item is 
too big. " +
+                    "This will lead to wasting of space inside index pages. 
Ignoring " +
+                    "[index=" + name + ", explicitInlineSize=" + cfgInlineSize 
+ ", realInlineSize=" + size + ']');
+
+                return size;
+            }
+
+            return cfgInlineSize;
+        }
+
         return Math.min(PageIO.MAX_PAYLOAD_SIZE, size);
     }
 
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/sorted/inline/types/NullableInlineIndexKeyType.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/sorted/inline/types/NullableInlineIndexKeyType.java
index 6f8c208a0f5..a39b71f8e39 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/sorted/inline/types/NullableInlineIndexKeyType.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/sorted/inline/types/NullableInlineIndexKeyType.java
@@ -144,6 +144,11 @@ public abstract class NullableInlineIndexKeyType<T extends 
IndexKey> implements
         return put0(pageAddr, off, (T)key, maxSize);
     }
 
+    /** {@inheritDoc} */
+    @Override public short keySize() {
+        return keySize;
+    }
+
     /**
      * Puts given value into inline index tree.
      *
diff --git 
a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
 
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
index d32beccbf80..c1d01562083 100644
--- 
a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
+++ 
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java
@@ -501,7 +501,7 @@ public class IgniteH2Indexing implements GridQueryIndexing {
                 tbl.cacheInfo().config().getSqlIndexMaxInlineSize());
 
             org.apache.ignite.internal.cache.query.index.Index index =
-                ctx.indexProcessor().createIndex(tbl.cacheContext(), 
ClientIndexFactory.INSTANCE, d);
+                ctx.indexProcessor().createIndex(tbl.cacheContext(), new 
ClientIndexFactory(log), d);
 
             InlineIndex idx = index.unwrap(InlineIndex.class);
 
diff --git 
a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/index/client/ClientIndexFactory.java
 
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/index/client/ClientIndexFactory.java
index 836795157a7..6204791f009 100644
--- 
a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/index/client/ClientIndexFactory.java
+++ 
b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/index/client/ClientIndexFactory.java
@@ -20,6 +20,7 @@ package 
org.apache.ignite.internal.processors.query.h2.index.client;
 import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.List;
+import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.internal.cache.query.index.Index;
 import org.apache.ignite.internal.cache.query.index.IndexDefinition;
 import org.apache.ignite.internal.cache.query.index.IndexFactory;
@@ -31,17 +32,19 @@ import 
org.apache.ignite.internal.cache.query.index.sorted.inline.InlineIndexTre
 import org.apache.ignite.internal.processors.cache.GridCacheContext;
 
 /**
- * Factory fot client index.
+ * Factory for client index.
  */
 public class ClientIndexFactory implements IndexFactory {
-    /** Instance. */
-    public static final ClientIndexFactory INSTANCE = new ClientIndexFactory();
-
     /** Dummy key types. */
     private static final IndexKeyTypeSettings DUMMY_SETTINGS = new 
IndexKeyTypeSettings();
 
-    /** Forbidden constructor. */
-    private ClientIndexFactory() {}
+    /** Logger. */
+    private final IgniteLogger log;
+
+    /** */
+    public ClientIndexFactory(IgniteLogger log) {
+        this.log = log;
+    }
 
     /** {@inheritDoc} */
     @Override public Index createIndex(GridCacheContext<?, ?> cctx, 
IndexDefinition definition) {
@@ -51,8 +54,14 @@ public class ClientIndexFactory implements IndexFactory {
 
         List<InlineIndexKeyType> keyTypes = 
InlineIndexKeyTypeRegistry.types(keyDefs.values(), DUMMY_SETTINGS);
 
-        int inlineSize = InlineIndexTree.computeInlineSize(keyTypes, new 
ArrayList<>(keyDefs.values()),
-            def.getCfgInlineSize(), def.getMaxInlineSize());
+        int inlineSize = InlineIndexTree.computeInlineSize(
+            definition.idxName().fullName(),
+            keyTypes,
+            new ArrayList<>(keyDefs.values()),
+            def.getCfgInlineSize(),
+            def.getMaxInlineSize(),
+            log
+        );
 
         return new ClientInlineIndex(def.idxName().idxName(), inlineSize);
     }
diff --git 
a/modules/indexing/src/test/java/org/apache/ignite/cache/query/IndexQueryInlineSizesTest.java
 
b/modules/indexing/src/test/java/org/apache/ignite/cache/query/IndexQueryInlineSizesTest.java
index 16cbef102b3..000b30c327b 100644
--- 
a/modules/indexing/src/test/java/org/apache/ignite/cache/query/IndexQueryInlineSizesTest.java
+++ 
b/modules/indexing/src/test/java/org/apache/ignite/cache/query/IndexQueryInlineSizesTest.java
@@ -79,7 +79,9 @@ public class IndexQueryInlineSizesTest extends 
GridCommonAbstractTest {
     /** */
     @Test
     public void testFixedInlineKeys() throws Exception {
-        try (Index idx = new Index(inlineSize, "fld1, fld2")) {
+        // fld1 int, fld2 int, _key int. Inline int size is 5 (1 tag, 4 value) 
-> full inlined value is 15 bytes.
+        // If INLINE_SIZE > 15 it will be ignored. Real inline size will be 15 
bytes.
+        try (Index idx = new Index(inlineSize, "fld1, fld2", inlineSize > 15 ? 
15 : inlineSize)) {
             check((low, high) -> new IndexQuery<Integer, 
BinaryObject>(VALUE_TYPE, idx.idxName)
                 .setCriteria(gt("fld1", low), lt("fld2", high)));
         }
@@ -106,7 +108,10 @@ public class IndexQueryInlineSizesTest extends 
GridCommonAbstractTest {
     /** */
     @Test
     public void testNonInlinedKeys() throws Exception {
-        try (Index idx = new Index(inlineSize, "fld1, fld4")) {
+        // fld1 int can be inlined, fld4 decimal can't be inlined.
+        // Maximum possible inline size for fld1 is 5 bytes.
+        // If INLINE_SIZE > 5 it will be ignored. Real inline size will be 5 
bytes.
+        try (Index idx = new Index(inlineSize, "fld1, fld4", inlineSize > 5 ? 
5 : inlineSize)) {
             check((low, high) -> new IndexQuery<Integer, 
BinaryObject>(VALUE_TYPE, idx.idxName)
                 .setCriteria(gt("fld1", low), lt("fld4", new 
BigDecimal(high))));
         }
diff --git 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/SqlSystemViewsSelfTest.java
 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/SqlSystemViewsSelfTest.java
index f4b4e4aaa76..8b2acad4b39 100644
--- 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/SqlSystemViewsSelfTest.java
+++ 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/SqlSystemViewsSelfTest.java
@@ -294,7 +294,7 @@ public class SqlSystemViewsSelfTest extends 
AbstractIndexingCommonTest {
                 {-825022849, "SQL_PUBLIC_AFF_CACHE", "PUBLIC", "AFF_CACHE", 
"_key_PK_hash", "HASH",
                     "\"ID1\" ASC, \"ID2\" ASC, \"ID2\" ASC", false, true, 
null},
 
-                {707660652, "SQL_PUBLIC_CACHE_SQL", "PUBLIC", "CACHE_SQL", 
"IDX_2", "BTREE", "\"ID\" DESC, \"ID\" ASC", false, false, 13},
+                {707660652, "SQL_PUBLIC_CACHE_SQL", "PUBLIC", "CACHE_SQL", 
"IDX_2", "BTREE", "\"ID\" DESC, \"ID\" ASC", false, false, 10},
                 {707660652, "SQL_PUBLIC_CACHE_SQL", "PUBLIC", "CACHE_SQL", 
"__SCAN_", "SCAN", null, false, false, null},
                 {707660652, "SQL_PUBLIC_CACHE_SQL", "PUBLIC", "CACHE_SQL", 
"_key_PK", "BTREE", "\"ID\" ASC", true, true, 5},
                 {707660652, "SQL_PUBLIC_CACHE_SQL", "PUBLIC", "CACHE_SQL", 
"_key_PK_hash", "HASH", "\"ID\" ASC", false, true, null},
diff --git 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/database/inlinecolumn/ComputeInlineSizeTest.java
 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/database/inlinecolumn/ComputeInlineSizeTest.java
index 4a1a857e87e..d1e185a6c5f 100644
--- 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/database/inlinecolumn/ComputeInlineSizeTest.java
+++ 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/database/inlinecolumn/ComputeInlineSizeTest.java
@@ -26,12 +26,27 @@ import 
org.apache.ignite.cache.query.annotations.QuerySqlField;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.internal.IgniteEx;
 import org.apache.ignite.internal.cache.query.index.Index;
+import org.apache.ignite.internal.cache.query.index.IndexName;
 import 
org.apache.ignite.internal.cache.query.index.sorted.inline.InlineIndexImpl;
+import 
org.apache.ignite.internal.cache.query.index.sorted.inline.InlineIndexKeyType;
 import 
org.apache.ignite.internal.cache.query.index.sorted.inline.InlineIndexTree;
+import 
org.apache.ignite.internal.cache.query.index.sorted.inline.types.BooleanInlineIndexKeyType;
+import 
org.apache.ignite.internal.cache.query.index.sorted.inline.types.ByteInlineIndexKeyType;
+import 
org.apache.ignite.internal.cache.query.index.sorted.inline.types.DateInlineIndexKeyType;
+import 
org.apache.ignite.internal.cache.query.index.sorted.inline.types.DoubleInlineIndexKeyType;
+import 
org.apache.ignite.internal.cache.query.index.sorted.inline.types.FloatInlineIndexKeyType;
+import 
org.apache.ignite.internal.cache.query.index.sorted.inline.types.IntegerInlineIndexKeyType;
+import 
org.apache.ignite.internal.cache.query.index.sorted.inline.types.LongInlineIndexKeyType;
+import 
org.apache.ignite.internal.cache.query.index.sorted.inline.types.ShortInlineIndexKeyType;
+import 
org.apache.ignite.internal.cache.query.index.sorted.inline.types.TimeInlineIndexKeyType;
+import 
org.apache.ignite.internal.cache.query.index.sorted.inline.types.TimestampInlineIndexKeyType;
+import 
org.apache.ignite.internal.cache.query.index.sorted.inline.types.UuidInlineIndexKeyType;
 import org.apache.ignite.internal.processors.cache.GridCacheContext;
 import org.apache.ignite.internal.processors.cache.IgniteInternalCache;
 import 
org.apache.ignite.internal.processors.cache.index.AbstractIndexingCommonTest;
 import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.lang.IgniteBiTuple;
 import org.junit.Test;
 
 /** Tests for the computation inline size. */
@@ -83,11 +98,70 @@ public class ComputeInlineSizeTest extends 
AbstractIndexingCommonTest {
         for (String s: Arrays.asList("str", "strprec", "bytes", "bytesprec", 
"strprecbig"))
             bld.append(String.format("create index PERSON_%s_IDX on TABLE 
(%s); ", s.toUpperCase(), s));
 
-        query(new SqlFieldsQuery(bld.toString()));
+        query(bld.toString());
 
         checkIdxsInlineSizes();
     }
 
+    /** */
+    @Test
+    public void testTooBigInlineNotUsed() {
+        InlineIndexKeyType idIdxType = new LongInlineIndexKeyType();
+
+        Collection<IgniteBiTuple<String, InlineIndexKeyType>> fixLenTypes = 
Arrays.asList(
+            F.t("BOOLEAN", new BooleanInlineIndexKeyType()),
+            F.t("TINYINT", new ByteInlineIndexKeyType()),
+            F.t("DATE", new DateInlineIndexKeyType()),
+            F.t("DOUBLE", new DoubleInlineIndexKeyType()),
+            F.t("REAL", new FloatInlineIndexKeyType()),
+            F.t("INT", new IntegerInlineIndexKeyType()),
+            F.t("BIGINT", new LongInlineIndexKeyType()),
+            F.t("SMALLINT", new ShortInlineIndexKeyType()),
+            F.t("TIME", new TimeInlineIndexKeyType()),
+            F.t("TIMESTAMP", new TimestampInlineIndexKeyType()),
+            F.t("UUID", new UuidInlineIndexKeyType())
+        );
+
+        StringBuilder tbl = new StringBuilder("CREATE TABLE T1 (ID LONG 
PRIMARY KEY, _VARCHAR VARCHAR");
+
+        for (IgniteBiTuple<String, InlineIndexKeyType> type : fixLenTypes)
+            tbl.append(String.format(", _%s %s", type.get1(), type.get1()));
+
+        tbl.append(")");
+
+        query(tbl.toString());
+
+        checkIndexInlineSize("VARCHAR", 1000);
+
+        for (IgniteBiTuple<String, InlineIndexKeyType> type0 : fixLenTypes) {
+            checkIndexInlineSize(type0.get1(), type0.get2().inlineSize() + 
idIdxType.inlineSize());
+
+            checkIndexInlineSize(type0.get1() + ", _VARCHAR", 1000);
+
+            for (IgniteBiTuple<String, InlineIndexKeyType> type1 : 
fixLenTypes) {
+                if (type0 == type1)
+                    continue;
+
+                checkIndexInlineSize(
+                    type0.get1() + ", _" + type1.get1(),
+                    type0.get2().inlineSize() + type1.get2().inlineSize() + 
idIdxType.inlineSize()
+                );
+            }
+        }
+    }
+
+    /** */
+    private void checkIndexInlineSize(String cols, int expInlineSz) {
+        query(String.format("CREATE INDEX IDX1 ON T1(_%s) INLINE_SIZE 1000", 
cols));
+
+        InlineIndexImpl idx = (InlineIndexImpl)
+            ignite.context().indexProcessor().index(new 
IndexName("SQL_PUBLIC_T1", "PUBLIC", "T1", "IDX1"));
+
+        assertEquals(cols, expInlineSz, idx.inlineSize());
+
+        query("DROP INDEX IDX1");
+    }
+
     /** */
     private void checkIdxsInlineSizes() {
         Collection<Index> idx = 
ignite.context().indexProcessor().indexes(context());
@@ -121,8 +195,8 @@ public class ComputeInlineSizeTest extends 
AbstractIndexingCommonTest {
     }
 
     /** */
-    private void query(SqlFieldsQuery qry) {
-        ignite.context().query().querySqlFields(qry, false, false);
+    private void query(String qry) {
+        ignite.context().query().querySqlFields(new SqlFieldsQuery(qry), 
false, false);
     }
 
     /** */

Reply via email to