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);
}
/** */