You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by se...@apache.org on 2017/03/01 19:23:35 UTC
[1/2] ignite git commit: ignite-3477-index2 SQL inline indexes
(simple types, Strings, Bytes)
Repository: ignite
Updated Branches:
refs/heads/ignite-3477 ee28b9cb8 -> c4490ddce
ignite-3477-index2 SQL inline indexes (simple types, Strings, Bytes)
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/78c2a7f4
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/78c2a7f4
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/78c2a7f4
Branch: refs/heads/ignite-3477
Commit: 78c2a7f410d9086d836e4c5596cb47187b52c95d
Parents: ee28b9c
Author: Konstantin Dudkov <kd...@ya.ru>
Authored: Wed Mar 1 16:54:45 2017 +0300
Committer: Konstantin Dudkov <kd...@ya.ru>
Committed: Wed Mar 1 16:54:45 2017 +0300
----------------------------------------------------------------------
.../configuration/CacheConfiguration.java | 28 ++
.../core/src/test/java/FullTextIndexTest.java | 316 +++++++++++++++
.../testframework/junits/GridAbstractTest.java | 2 +-
.../processors/query/h2/database/H2Tree.java | 120 +++++-
.../query/h2/database/H2TreeIndex.java | 167 ++------
.../query/h2/database/InlineIndexHelper.java | 400 ++++++++++++++++---
.../query/h2/database/io/H2ExtrasInnerIO.java | 12 +-
.../query/h2/database/io/H2ExtrasLeafIO.java | 9 +-
.../processors/query/h2/opt/GridH2Table.java | 2 +-
.../query/h2/database/H2TreeIndexTest.java | 59 ---
.../h2/database/InlineIndexHelperTest.java | 316 ++++++++++++++-
11 files changed, 1153 insertions(+), 278 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/78c2a7f4/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 6c56fc5..c41be0c2 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
@@ -136,6 +136,9 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
/** Default cache size to use with eviction policy. */
public static final int DFLT_CACHE_SIZE = 100000;
+ /** Default maximum inline size for sql indexes. */
+ public static final int DFLT_SQL_INDEX_MAX_INLINE_SIZE = -1;
+
/** Initial default near cache size. */
public static final int DFLT_NEAR_START_SIZE = DFLT_START_SIZE / 4;
@@ -321,6 +324,9 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
/** Maximum number of concurrent asynchronous operations. */
private int maxConcurrentAsyncOps = DFLT_MAX_CONCURRENT_ASYNC_OPS;
+ /** Maximum inline size for sql indexes. */
+ private int sqlIndexMaxInlineSize = DFLT_SQL_INDEX_MAX_INLINE_SIZE;
+
/** Write-behind feature. */
private boolean writeBehindEnabled = DFLT_WRITE_BEHIND_ENABLED;
@@ -461,6 +467,7 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
longQryWarnTimeout = cc.getLongQueryWarningTimeout();
offHeapMaxMem = cc.getOffHeapMaxMemory();
maxConcurrentAsyncOps = cc.getMaxConcurrentAsyncOperations();
+ sqlIndexMaxInlineSize = cc.getSqlIndexMaxInlineSize();
name = cc.getName();
nearCfg = cc.getNearConfiguration();
nodeFilter = cc.getNodeFilter();
@@ -1286,6 +1293,27 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
}
/**
+ * Gets maximum inline size for sql indexes. If -1 returned then
+ * {@code IgniteSystemProperties.IGNITE_MAX_INDEX_PAYLOAD_SIZE} system property is used.
+ * <p>
+ * If not set, default value is {@link #DFLT_SQL_INDEX_MAX_INLINE_SIZE}.
+ *
+ * @return Maximum payload size for offheap indexes.
+ */
+ public int getSqlIndexMaxInlineSize() {
+ return sqlIndexMaxInlineSize;
+ }
+
+ /**
+ * Sets maximum inline size for sql indexes.
+ *
+ * @param sqlIndexMaxInlineSize Maximum inline size for sql indexes.
+ */
+ public void setSqlIndexMaxInlineSize(int sqlIndexMaxInlineSize) {
+ this.sqlIndexMaxInlineSize = sqlIndexMaxInlineSize;
+ }
+
+ /**
* Flag indicating whether Ignite should use write-behind behaviour for the cache store.
* By default write-behind is disabled which is defined via {@link #DFLT_WRITE_BEHIND_ENABLED}
* constant.
http://git-wip-us.apache.org/repos/asf/ignite/blob/78c2a7f4/modules/core/src/test/java/FullTextIndexTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/FullTextIndexTest.java b/modules/core/src/test/java/FullTextIndexTest.java
new file mode 100644
index 0000000..05a9541
--- /dev/null
+++ b/modules/core/src/test/java/FullTextIndexTest.java
@@ -0,0 +1,316 @@
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import javax.cache.Cache;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cache.QueryEntity;
+import org.apache.ignite.cache.QueryIndex;
+import org.apache.ignite.cache.QueryIndexType;
+import org.apache.ignite.cache.query.QueryCursor;
+import org.apache.ignite.cache.query.SqlQuery;
+import org.apache.ignite.cache.query.TextQuery;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder;
+import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+
+/**
+ * Created by amashenkov on 17.02.17.
+ */
+public class FullTextIndexTest extends GridCommonAbstractTest {
+ /** */
+ private static final TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true);
+
+ /**
+ * @return Ignite instance.
+ */
+ protected Ignite ignite() {
+ return grid(0);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTest() throws Exception {
+ super.afterTest();
+
+ ignite().cache(null).removeAll();
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void beforeTestsStarted() throws Exception {
+ super.beforeTestsStarted();
+
+ startGridsMultiThreaded(1);
+ }
+
+ /** {@inheritDoc} */
+ @Override protected void afterTestsStopped() throws Exception {
+ super.afterTestsStopped();
+
+ stopAllGrids();
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings("unchecked")
+ @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception {
+ IgniteConfiguration c = super.getConfiguration(gridName);
+
+ c.setDiscoverySpi(new TcpDiscoverySpi().setForceServerMode(true).setIpFinder(ipFinder));
+
+ // Otherwise noop swap space will be chosen on Windows.
+// c.setSwapSpaceSpi(new FileSwapSpaceSpi());
+
+ CacheConfiguration cc = defaultCacheConfiguration();
+
+ List<QueryEntity> entityList = new ArrayList<>();
+
+ QueryEntity qryEntity = new QueryEntity();
+
+ qryEntity.setKeyType(Integer.class.getName());
+ qryEntity.setValueType(ObjectValue.class.getName());
+ qryEntity.addQueryField("strVal", String.class.getName(), null);
+
+ QueryIndex index = new QueryIndex(); // Default index type
+ index.setFieldNames(Collections.singletonList("strVal"), true);
+
+ qryEntity.setIndexes(Arrays.asList(index));
+
+ entityList.add(qryEntity);
+
+ qryEntity = new QueryEntity();
+
+ qryEntity.setKeyType(Integer.class.getName());
+ qryEntity.setValueType(ObjectValue2.class.getName());
+ qryEntity.addQueryField("strVal", String.class.getName(), null);
+
+ index = new QueryIndex();
+ index.setIndexType(QueryIndexType.FULLTEXT);
+ index.setFieldNames(Collections.singletonList("strVal"), true);
+
+ qryEntity.setIndexes(Arrays.asList(index));
+
+ entityList.add(qryEntity);
+
+ qryEntity = new QueryEntity();
+
+ qryEntity.setKeyType(Integer.class.getName());
+ qryEntity.setValueType(String.class.getName());
+
+// index = new QueryIndex();
+// index.setIndexType(QueryIndexType.SORTED);
+
+ qryEntity.setIndexes(Arrays.asList(index));
+
+ entityList.add(qryEntity);
+
+ cc.setQueryEntities(entityList);
+
+ c.setCacheConfiguration(cc);
+
+ return c;
+ }
+
+ /**
+ * JUnit.
+ *
+ * @throws Exception In case of error.
+ */
+ public void testObjectSortedIndex() throws Exception {
+ IgniteCache<Integer, ObjectValue> cache = ignite().cache(null);
+
+ cache.put(1, new ObjectValue("value 1"));
+ cache.put(2, new ObjectValue("value 2"));
+ cache.put(3, new ObjectValue("value 3"));
+
+ QueryCursor<Cache.Entry<Integer, ObjectValue>> qry
+ = cache.query(new SqlQuery<Integer, ObjectValue>(ObjectValue.class, "strVal like ?").setArgs("value%"));
+
+ int expCnt = 3;
+
+ List<Cache.Entry<Integer, ObjectValue>> results = qry.getAll();
+
+ assertEquals(expCnt, results.size());
+
+ qry = cache.query(new SqlQuery<Integer, ObjectValue>(ObjectValue.class, "strVal > ?").setArgs("value 1"));
+
+ results = qry.getAll();
+
+ assertEquals(expCnt - 1, results.size());
+
+ qry = cache.query(new TextQuery<Integer, ObjectValue>(ObjectValue.class, "value"));
+
+ results = qry.getAll();
+
+ assertEquals(0, results.size());
+ }
+
+ /**
+ * JUnit.
+ *
+ * @throws Exception In case of error.
+ */
+ public void testObjectTextIndex() throws Exception {
+ IgniteCache<Integer, ObjectValue2> cache = ignite(0).cache(null);
+
+ cache.put(1, new ObjectValue2("value 1"));
+ cache.put(2, new ObjectValue2("value 2"));
+ cache.put(3, new ObjectValue2("value 3"));
+
+ QueryCursor<Cache.Entry<Integer, ObjectValue2>> qry
+ = cache.query(new SqlQuery<Integer, ObjectValue2>(ObjectValue2.class, "strVal like ?").setArgs("value%"));
+
+ int expCnt = 3;
+
+ List<Cache.Entry<Integer, ObjectValue2>> results = qry.getAll();
+
+ assertEquals(expCnt, results.size());
+
+ qry = cache.query(new SqlQuery<Integer, ObjectValue2>(ObjectValue2.class, "strVal > ?").setArgs("value 1"));
+
+ results = qry.getAll();
+
+ assertEquals(expCnt - 1, results.size());
+
+ qry = cache.query(new TextQuery<Integer, ObjectValue2>(ObjectValue2.class, "value"));
+
+ results = qry.getAll();
+
+ assertEquals(3, results.size());
+ }
+
+ /**
+ * JUnit.
+ *
+ * @throws Exception In case of error.
+ */
+ public void testStringDefaultIndex() throws Exception {
+ IgniteCache<Integer, String> cache = ignite(0).cache(null);
+
+ cache.put(1, "value 1");
+ cache.put(2, "value 2");
+ cache.put(3, "value 3");
+
+ QueryCursor<Cache.Entry<Integer, String>> qry
+ = cache.query(new SqlQuery<Integer, String>(String.class, "_val like ?").setArgs("value%"));
+
+ int expCnt = 3;
+
+ List<Cache.Entry<Integer, String>> results = qry.getAll();
+
+ assertEquals(expCnt, results.size());
+
+ qry = cache.query(new SqlQuery<Integer, String>(String.class, "_val > ?").setArgs("value 1"));
+
+ results = qry.getAll();
+
+ assertEquals(expCnt - 1, results.size());
+
+ qry = cache.query(new TextQuery<Integer, String>(String.class, "value"));
+
+ results = qry.getAll();
+
+ // There is no way to disable FULLTEXT index. So, next line will fails.
+ assertEquals(0, results.size());
+ }
+
+ /**
+ * Another test value object.
+ */
+ private static class ObjectValue {
+ /** Value. */
+ private String strVal;
+
+ /**
+ * @param strVal String value.
+ */
+ ObjectValue(String strVal) {
+ this.strVal = strVal;
+ }
+
+ /**
+ * Gets value.
+ *
+ * @return Value.
+ */
+ public String value() {
+ return strVal;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ ObjectValue other = (ObjectValue)o;
+
+ return strVal == null ? other.strVal == null : strVal.equals(other.strVal);
+
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ return strVal != null ? strVal.hashCode() : 0;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(ObjectValue.class, this);
+ }
+ }
+
+ /**
+ * Another test value object.
+ */
+ private static class ObjectValue2 {
+ /** Value. */
+ private String strVal;
+
+ /**
+ * @param strVal String value.
+ */
+ ObjectValue2(String strVal) {
+ this.strVal = strVal;
+ }
+
+ /**
+ * Gets value.
+ *
+ * @return Value.
+ */
+ public String value() {
+ return strVal;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean equals(Object o) {
+ if (this == o)
+ return true;
+
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ ObjectValue2 other = (ObjectValue2)o;
+
+ return strVal == null ? other.strVal == null : strVal.equals(other.strVal);
+
+ }
+
+ /** {@inheritDoc} */
+ @Override public int hashCode() {
+ return strVal != null ? strVal.hashCode() : 0;
+ }
+
+ /** {@inheritDoc} */
+ @Override public String toString() {
+ return S.toString(ObjectValue2.class, this);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/78c2a7f4/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
index b45e173..3be511e 100644
--- a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
@@ -1263,7 +1263,7 @@ public abstract class GridAbstractTest extends TestCase {
public String getTestGridName() {
String[] parts = getClass().getName().split("\\.");
- return parts[parts.length - 2] + '.' + parts[parts.length - 1];
+ return "tg1";
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/78c2a7f4/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2Tree.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2Tree.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2Tree.java
index d9b820a..842f035 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2Tree.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2Tree.java
@@ -17,6 +17,8 @@
package org.apache.ignite.internal.processors.query.h2.database;
+import java.util.Comparator;
+import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.pagemem.Page;
@@ -31,6 +33,8 @@ import org.apache.ignite.internal.processors.query.h2.database.io.H2ExtrasLeafIO
import org.apache.ignite.internal.processors.query.h2.opt.GridH2Row;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.h2.result.SearchRow;
+import org.h2.table.IndexColumn;
+import org.h2.value.Value;
/**
*/
@@ -41,6 +45,22 @@ public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> {
/** */
private final int inlineSize;
+ /** */
+ private final List<InlineIndexHelper> inlineIdxs;
+
+ /** */
+ private final IndexColumn[] cols;
+
+ /** */
+ private final int[] columnIds;
+
+ /** */
+ private final Comparator<Value> comp = new Comparator<Value>() {
+ @Override public int compare(Value o1, Value o2) {
+ return compareValues(o1, o2);
+ }
+ };
+
/**
* @param name Tree name.
* @param reuseList Reuse list.
@@ -62,6 +82,8 @@ public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> {
H2RowFactory rowStore,
long metaPageId,
boolean initNew,
+ IndexColumn[] cols,
+ List<InlineIndexHelper> inlineIdxs,
int inlineSize
) throws IgniteCheckedException {
super(name, cacheId, pageMem, wal, globalRmvId, metaPageId, reuseList);
@@ -76,6 +98,13 @@ public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> {
assert rowStore != null;
this.rowStore = rowStore;
+ this.inlineIdxs = inlineIdxs;
+ this.cols = cols;
+
+ this.columnIds = new int[cols.length];
+
+ for (int i = 0; i < cols.length; i++)
+ columnIds[i] = cols[i].column.getColumnId();
setIos(H2ExtrasInnerIO.getVersions(inlineSize), H2ExtrasLeafIO.getVersions(inlineSize));
@@ -123,6 +152,95 @@ public abstract class H2Tree extends BPlusTree<SearchRow, GridH2Row> {
}
}
}
-}
+ /** {@inheritDoc} */
+ @Override protected int compare(BPlusIO<SearchRow> io, long pageAddr, int idx,
+ SearchRow row) throws IgniteCheckedException {
+ if (inlineSize() == 0)
+ return compareRows(getRow(io, pageAddr, idx), row);
+ else {
+ int off = io.offset(idx);
+
+ int fieldOff = 0;
+
+ int lastIdxUsed = 0;
+
+ for (int i = 0; i < inlineIdxs.size(); i++) {
+ InlineIndexHelper inlineIdx = inlineIdxs.get(i);
+
+ Value v2 = row.getValue(inlineIdx.columnIndex());
+
+ if (v2 == null)
+ return 0;
+
+ int c = inlineIdx.compare(pageAddr, off + fieldOff, inlineSize() - fieldOff, v2, comp);
+
+ if (c == -2)
+ break;
+
+ lastIdxUsed++;
+ if (c != 0)
+ return c;
+
+ fieldOff += inlineIdx.fullSize(pageAddr, off + fieldOff);
+
+ if (fieldOff > inlineSize())
+ break;
+ }
+
+ if (lastIdxUsed == cols.length)
+ return 0;
+
+ SearchRow rowData = getRow(io, pageAddr, idx);
+
+ for (int i = lastIdxUsed, len = cols.length; i < len; i++) {
+ IndexColumn col = cols[i];
+ int idx0 = col.column.getColumnId();
+
+ Value v2 = row.getValue(idx0);
+ if (v2 == null) {
+ // Can't compare further.
+ return 0;
+ }
+
+ Value v1 = rowData.getValue(idx0);
+
+ int c = compareValues(v1, v2);
+ if (c != 0)
+ return InlineIndexHelper.fixSort(c, col.sortType);
+ }
+
+ return 0;
+ }
+ }
+
+ /**
+ * Compare two rows.
+ *
+ * @param r1 Row 1.
+ * @param r2 Row 2.
+ * @return Compare result.
+ */
+ private int compareRows(GridH2Row r1, SearchRow r2) {
+ if (r1 == r2)
+ return 0;
+
+ for (int i = 0, len = cols.length; i < len; i++) {
+ int idx = columnIds[i];
+ Value v1 = r1.getValue(idx);
+ Value v2 = r2.getValue(idx);
+ if (v1 == null || v2 == null) {
+ // can't compare further
+ return 0;
+ }
+ int c = compareValues(v1, v2);
+ if (c != 0)
+ return InlineIndexHelper.fixSort(c, cols[i].sortType);
+ }
+ return 0;
+ }
+
+ /** Compares two Values. */
+ public abstract int compareValues(Value v1, Value v2);
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/78c2a7f4/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndex.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndex.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndex.java
index 2e9940b..4be40af 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndex.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndex.java
@@ -26,7 +26,6 @@ import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.database.IgniteCacheDatabaseSharedManager;
import org.apache.ignite.internal.processors.cache.database.RootPage;
import org.apache.ignite.internal.processors.cache.database.tree.BPlusTree;
-import org.apache.ignite.internal.processors.cache.database.tree.io.BPlusIO;
import org.apache.ignite.internal.processors.cache.database.tree.io.PageIO;
import org.apache.ignite.internal.processors.query.h2.H2Cursor;
import org.apache.ignite.internal.processors.query.h2.opt.GridH2IndexBase;
@@ -53,10 +52,7 @@ import org.jetbrains.annotations.Nullable;
*/
public class H2TreeIndex extends GridH2IndexBase {
/** Default value for {@code IGNITE_MAX_INDEX_PAYLOAD_SIZE} */
- public static final int IGNITE_MAX_INDEX_PAYLOAD_SIZE_DEFAULT = 0;
-
- /** PageContext for use in IO's */
- private static final ThreadLocal<H2TreeIndex> currentIndex = new ThreadLocal<>();
+ public static final int IGNITE_MAX_INDEX_PAYLOAD_SIZE_DEFAULT = 10;
/** */
private final H2Tree tree;
@@ -92,80 +88,22 @@ public class H2TreeIndex extends GridH2IndexBase {
initBaseIndex(tbl, 0, name, cols,
pk ? IndexType.createPrimaryKey(false, false) : IndexType.createNonUnique(false, false, false));
- name = tbl.rowDescriptor().type().typeId() + "_" + name;
+ name = tbl.rowDescriptor() == null ? "_" + name : tbl.rowDescriptor().type().typeId() + "_" + name;
name = BPlusTree.treeName(name, "H2Tree");
if (cctx.affinityNode()) {
IgniteCacheDatabaseSharedManager dbMgr = cctx.shared().database();
- RootPage page = cctx.offheap().rootPageForIndex(name);
+ RootPage page = getMetaPage(name);
inlineIdxs = getAvailableInlineColumns(cols);
tree = new H2Tree(name, cctx.offheap().reuseListForIndex(name), cctx.cacheId(),
dbMgr.pageMemory(), cctx.shared().wal(), cctx.offheap().globalRemoveId(),
- tbl.rowFactory(), page.pageId().pageId(), page.isAllocated(), computeInlineSize(inlineIdxs, inlineSize)) {
- @Override protected int compare(BPlusIO<SearchRow> io, long pageAddr, int idx, SearchRow row)
- throws IgniteCheckedException {
- if (inlineSize() == 0)
- return compareRows(getRow(io, pageAddr, idx), row);
- else {
- int off = io.offset(idx);
-
- int fieldOff = 0;
-
- int lastIdxUsed = 0;
-
- for (int i = 0; i < inlineIdxs.size(); i++) {
- InlineIndexHelper inlineIdx = inlineIdxs.get(i);
-
- Value v2 = row.getValue(inlineIdx.columnIndex());
-
- if (v2 == null)
- return 0;
-
- Value v1 = inlineIdx.get(pageAddr, off + fieldOff, inlineSize() - fieldOff);
-
- if (v1 == null)
- break;
-
- int c = compareValues(v1, v2, inlineIdx.sortType());
-
- if (!canRelyOnCompare(c, v1, v2, inlineIdx))
- break;
-
- lastIdxUsed++;
-
- if (c != 0)
- return c;
-
- fieldOff += inlineIdx.fullSize(pageAddr, off + fieldOff);
-
- if (fieldOff > inlineSize())
- break;
- }
-
- SearchRow rowData = getRow(io, pageAddr, idx);
-
- for (int i = lastIdxUsed, len = indexColumns.length; i < len; i++) {
- int idx0 = columnIds[i];
-
- Value v2 = row.getValue(idx0);
- if (v2 == null) {
- // Can't compare further.
- return 0;
- }
-
- Value v1 = rowData.getValue(idx0);
-
- int c = compareValues(v1, v2, indexColumns[i].sortType);
- if (c != 0)
- return c;
- }
-
- return 0;
- }
+ tbl.rowFactory(), page.pageId().pageId(), page.isAllocated(), cols, inlineIdxs, computeInlineSize(inlineIdxs, inlineSize)) {
+ @Override public int compareValues(Value v1, Value v2) {
+ return v1 == v2 ? 0 : table.compareTypeSafe(v1, v2);
}
};
}
@@ -183,8 +121,6 @@ public class H2TreeIndex extends GridH2IndexBase {
* @return List of {@link InlineIndexHelper} objects.
*/
private List<InlineIndexHelper> getAvailableInlineColumns(IndexColumn[] cols) {
-
- // todo: null
List<InlineIndexHelper> res = new ArrayList<>();
for (int i = 0; i < cols.length; i++) {
@@ -201,45 +137,6 @@ public class H2TreeIndex extends GridH2IndexBase {
return res;
}
- /**
- * @return Tree updated in current thread.
- */
- public static H2TreeIndex getCurrentIndex() {
- return currentIndex.get();
- }
-
- /**
- * @param a First value.
- * @param b Second Value.
- * @param sortType Sort type.
- * @return Compare result.
- */
- private int compareValues(Value a, Value b, int sortType) {
- if (a == b)
- return 0;
-
- int comp = table.compareTypeSafe(a, b);
-
- if ((sortType & SortOrder.DESCENDING) != 0)
- comp = -comp;
-
- return comp;
- }
-
- /**
- * @return Tree.
- */
- public H2Tree tree() {
- return tree;
- }
-
- /**
- * @return InlineIndexHelper list.
- */
- public List<InlineIndexHelper> inlineIndexes() {
- return inlineIdxs;
- }
-
/** {@inheritDoc} */
@Override public Cursor find(Session ses, SearchRow lower, SearchRow upper) {
try {
@@ -272,7 +169,7 @@ public class H2TreeIndex extends GridH2IndexBase {
/** {@inheritDoc} */
@Override public GridH2Row put(GridH2Row row) {
try {
- currentIndex.set(this);
+ InlineIndexHelper.setCurrentInlineIndexes(inlineIdxs);
return tree.put(row);
}
@@ -280,14 +177,14 @@ public class H2TreeIndex extends GridH2IndexBase {
throw DbException.convert(e);
}
finally {
- currentIndex.remove();
+ InlineIndexHelper.clearCurrentInlineIndexes();
}
}
/** {@inheritDoc} */
@Override public boolean putx(GridH2Row row) {
try {
- currentIndex.set(this);
+ InlineIndexHelper.setCurrentInlineIndexes(inlineIdxs);
return tree.putx(row);
}
@@ -295,35 +192,35 @@ public class H2TreeIndex extends GridH2IndexBase {
throw DbException.convert(e);
}
finally {
- currentIndex.remove();
+ InlineIndexHelper.clearCurrentInlineIndexes();
}
}
/** {@inheritDoc} */
@Override public GridH2Row remove(SearchRow row) {
try {
- currentIndex.set(this);
+ InlineIndexHelper.setCurrentInlineIndexes(inlineIdxs);
return tree.remove(row);
}
catch (IgniteCheckedException e) {
throw DbException.convert(e);
}
finally {
- currentIndex.remove();
+ InlineIndexHelper.clearCurrentInlineIndexes();
}
}
/** {@inheritDoc} */
@Override public void removex(SearchRow row) {
try {
- currentIndex.set(this);
+ InlineIndexHelper.setCurrentInlineIndexes(inlineIdxs);
tree.removex(row);
}
catch (IgniteCheckedException e) {
throw DbException.convert(e);
}
finally {
- currentIndex.remove();
+ InlineIndexHelper.clearCurrentInlineIndexes();
}
}
@@ -336,7 +233,6 @@ public class H2TreeIndex extends GridH2IndexBase {
int mul = getDistributedMultiplier(ses, filters, filter);
return mul * baseCost;
-
}
/** {@inheritDoc} */
@@ -421,10 +317,10 @@ public class H2TreeIndex extends GridH2IndexBase {
* @return Inline size.
*/
private int computeInlineSize(List<InlineIndexHelper> inlineIdxs, int cfgInlineSize) {
- int maxSize = PageIO.MAX_PAYLOAD_SIZE;
+ int confSize = cctx.config().getSqlIndexMaxInlineSize();
- int propSize = IgniteSystemProperties.getInteger(IgniteSystemProperties.IGNITE_MAX_INDEX_PAYLOAD_SIZE,
- IGNITE_MAX_INDEX_PAYLOAD_SIZE_DEFAULT);
+ int propSize = confSize == -1 ? IgniteSystemProperties.getInteger(IgniteSystemProperties.IGNITE_MAX_INDEX_PAYLOAD_SIZE,
+ IGNITE_MAX_INDEX_PAYLOAD_SIZE_DEFAULT) : confSize;
if (cfgInlineSize == 0)
return 0;
@@ -448,33 +344,18 @@ public class H2TreeIndex extends GridH2IndexBase {
size += idxHelper.size() + 1;
}
- return Math.min(maxSize, size);
+ return Math.min(PageIO.MAX_PAYLOAD_SIZE, size);
}
else
- return Math.min(maxSize, cfgInlineSize);
+ return Math.min(PageIO.MAX_PAYLOAD_SIZE, cfgInlineSize);
}
/**
- * @param c Compare result.
- * @param shortVal Short value.
- * @param v2 Second value;
- * @param inlineIdx Index helper.
- * @return {@code true} if we can rely on compare result.
+ * @param name Name.
+ * @return RootPage for meta page.
+ * @throws IgniteCheckedException
*/
- protected static boolean canRelyOnCompare(int c, Value shortVal, Value v2, InlineIndexHelper inlineIdx) {
- if (inlineIdx.type() == Value.STRING) {
- if (c == 0 && shortVal.getType() != Value.NULL && v2.getType() != Value.NULL)
- return false;
-
- if (shortVal.getType() != Value.NULL
- && v2.getType() != Value.NULL
- && ((c < 0 && inlineIdx.sortType() == SortOrder.ASCENDING) || (c > 0 && inlineIdx.sortType() == SortOrder.DESCENDING))
- && shortVal.getString().length() <= v2.getString().length()) {
- // Can't rely on compare, should use full string.
- return false;
- }
- }
-
- return true;
+ private RootPage getMetaPage(String name) throws IgniteCheckedException {
+ return cctx.offheap().rootPageForIndex(name);
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/78c2a7f4/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/InlineIndexHelper.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/InlineIndexHelper.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/InlineIndexHelper.java
index ff44df5..9492241 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/InlineIndexHelper.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/InlineIndexHelper.java
@@ -20,16 +20,29 @@ package org.apache.ignite.internal.processors.query.h2.database;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
+import java.util.Comparator;
import java.util.List;
import org.apache.ignite.internal.pagemem.PageUtils;
+import org.h2.result.SortOrder;
import org.h2.table.IndexColumn;
import org.h2.value.Value;
import org.h2.value.ValueBoolean;
import org.h2.value.ValueByte;
+import org.h2.value.ValueBytes;
+import org.h2.value.ValueDate;
+import org.h2.value.ValueDouble;
+import org.h2.value.ValueFloat;
import org.h2.value.ValueInt;
import org.h2.value.ValueLong;
import org.h2.value.ValueNull;
+import org.h2.value.ValueShort;
import org.h2.value.ValueString;
+import org.h2.value.ValueStringFixed;
+import org.h2.value.ValueStringIgnoreCase;
+import org.h2.value.ValueTime;
+import org.h2.value.ValueTimestamp;
+import org.h2.value.ValueTimestampUtc;
+import org.h2.value.ValueUuid;
/**
* Helper class for in-page indexes.
@@ -37,6 +50,9 @@ import org.h2.value.ValueString;
public class InlineIndexHelper {
private static final Charset CHARSET = StandardCharsets.UTF_8;
+ /** PageContext for use in IO's */
+ private static final ThreadLocal<List<InlineIndexHelper>> currentIndex = new ThreadLocal<>();
+
/** */
public static final List<Integer> AVAILABLE_TYPES = Arrays.asList(
Value.BOOLEAN,
@@ -44,7 +60,18 @@ public class InlineIndexHelper {
Value.SHORT,
Value.INT,
Value.LONG,
- Value.STRING
+ Value.LONG,
+ Value.FLOAT,
+ Value.DOUBLE,
+ Value.DATE,
+ Value.TIME,
+ Value.TIMESTAMP,
+ Value.TIMESTAMP_UTC,
+ Value.UUID,
+ Value.STRING,
+ Value.STRING_FIXED,
+ Value.STRING_IGNORECASE,
+ Value.BYTES
);
/** */
@@ -56,6 +83,9 @@ public class InlineIndexHelper {
/** */
private final int sortType;
+ /** */
+ private final short size;
+
/**
* @param type Index type (see {@link Value}).
* @param colIdx Index column index.
@@ -65,6 +95,63 @@ public class InlineIndexHelper {
this.type = type;
this.colIdx = colIdx;
this.sortType = sortType;
+
+ switch (type) {
+ case Value.BOOLEAN:
+ case Value.BYTE:
+ this.size = 1;
+ break;
+
+ case Value.SHORT:
+ this.size = 2;
+ break;
+
+ case Value.INT:
+ this.size = 4;
+ break;
+
+ case Value.LONG:
+ this.size = 8;
+ break;
+
+ case Value.FLOAT:
+ this.size = 4;
+ break;
+
+ case Value.DOUBLE:
+ this.size = 8;
+ break;
+
+ case Value.DATE:
+ this.size = 8;
+ break;
+
+ case Value.TIME:
+ this.size = 8;
+ break;
+
+ case Value.TIMESTAMP:
+ this.size = 16;
+ break;
+
+ case Value.TIMESTAMP_UTC:
+ this.size = 8;
+ break;
+
+ case Value.UUID:
+ this.size = 16;
+ break;
+
+ case Value.STRING:
+ case Value.STRING_FIXED:
+ case Value.STRING_IGNORECASE:
+ case Value.BYTES:
+ this.size = -1;
+ break;
+
+ default:
+ throw new UnsupportedOperationException("no get operation for fast index type " + type);
+ }
}
/**
@@ -89,29 +176,31 @@ public class InlineIndexHelper {
}
/**
- * @return Value size.
+ * @return Page context for current thread.
*/
- public short size() {
- switch (type) {
- case Value.BOOLEAN:
- case Value.BYTE:
- return 1;
-
- case Value.SHORT:
- return 2;
-
- case Value.INT:
- return 4;
+ public static List<InlineIndexHelper> getCurrentInlineIndexes() {
+ return currentIndex.get();
+ }
- case Value.LONG:
- return 8;
+ /**
+ * Sets page context for current thread.
+ */
+ public static void setCurrentInlineIndexes(List<InlineIndexHelper> inlineIdxs) {
+ currentIndex.set(inlineIdxs);
+ }
- case Value.STRING:
- return -1;
+ /**
+ * Clears current context.
+ */
+ public static void clearCurrentInlineIndexes() {
+ currentIndex.remove();
+ }
- default:
- throw new UnsupportedOperationException("no get operation for fast index type " + type);
- }
+ /**
+ * @return Value size.
+ */
+ public short size() {
+ return size;
}
/**
@@ -125,20 +214,10 @@ public class InlineIndexHelper {
if (type == Value.NULL)
return 1;
- switch (type) {
- case Value.BOOLEAN:
- case Value.BYTE:
- case Value.INT:
- case Value.SHORT:
- case Value.LONG:
- return size() + 1;
-
- case Value.STRING:
- return PageUtils.getShort(pageAddr, off + 1) + 3;
-
- default:
- throw new UnsupportedOperationException("no get operation for fast index type " + type);
- }
+ if (size > 0)
+ return size + 1;
+ else
+ return PageUtils.getShort(pageAddr, off + 1) + 3;
}
/**
@@ -147,7 +226,7 @@ public class InlineIndexHelper {
* @return Value.
*/
public Value get(long pageAddr, int off, int maxSize) {
- if (size() > 0 && size() + 1 > maxSize)
+ if (size > 0 && size + 1 > maxSize)
return null;
int type = PageUtils.getByte(pageAddr, off);
@@ -169,7 +248,7 @@ public class InlineIndexHelper {
return ValueByte.get(PageUtils.getByte(pageAddr, off + 1));
case Value.SHORT:
- return ValueInt.get(PageUtils.getShort(pageAddr, off + 1));
+ return ValueShort.get(PageUtils.getShort(pageAddr, off + 1));
case Value.INT:
return ValueInt.get(PageUtils.getInt(pageAddr, off + 1));
@@ -177,15 +256,103 @@ public class InlineIndexHelper {
case Value.LONG:
return ValueLong.get(PageUtils.getLong(pageAddr, off + 1));
+ case Value.FLOAT: {
+ return ValueFloat.get(Float.intBitsToFloat(PageUtils.getInt(pageAddr, off + 1)));
+ }
+
+ case Value.DOUBLE: {
+ return ValueDouble.get(Double.longBitsToDouble(PageUtils.getLong(pageAddr, off + 1)));
+ }
+
+ case Value.TIME:
+ return ValueTime.fromNanos(PageUtils.getLong(pageAddr, off + 1));
+
+ case Value.DATE:
+ return ValueDate.fromDateValue(PageUtils.getLong(pageAddr, off + 1));
+
+ case Value.TIMESTAMP:
+ return ValueTimestamp.fromDateValueAndNanos(PageUtils.getLong(pageAddr, off + 1), PageUtils.getLong(pageAddr, off + 9));
+
+ case Value.TIMESTAMP_UTC:
+ return ValueTimestampUtc.fromNanos(PageUtils.getLong(pageAddr, off + 1));
+
+ case Value.UUID:
+ return ValueUuid.get(PageUtils.getLong(pageAddr, off + 1), PageUtils.getLong(pageAddr, off + 9));
+
case Value.STRING:
- short size = PageUtils.getShort(pageAddr, off + 1);
- return ValueString.get(new String(PageUtils.getBytes(pageAddr, off + 3, size), CHARSET));
+ return ValueString.get(new String(readBytes(pageAddr, off), CHARSET));
+
+ case Value.STRING_FIXED:
+ return ValueStringFixed.get(new String(readBytes(pageAddr, off), CHARSET));
+
+ case Value.STRING_IGNORECASE:
+ return ValueStringIgnoreCase.get(new String(readBytes(pageAddr, off), CHARSET));
+
+ case Value.BYTES:
+ return ValueBytes.get(readBytes(pageAddr, off));
default:
throw new UnsupportedOperationException("no get operation for fast index type " + type);
}
}
+ /** Read variable length bytearray */
+ private static byte[] readBytes(long pageAddr, int off) {
+ int size = PageUtils.getShort(pageAddr, off + 1) & 0x7FFF;
+ return PageUtils.getBytes(pageAddr, off + 3, size);
+ }
+
+ /**
+ * @param pageAddr Page address.
+ * @param off Offset.
+ * @return {@code True} if string is not truncated on save.
+ */
+ protected boolean isValueFull(long pageAddr, int off) {
+ switch (type) {
+ case Value.BOOLEAN:
+ case Value.BYTE:
+ case Value.INT:
+ case Value.SHORT:
+ case Value.LONG:
+ return true;
+
+ case Value.STRING:
+ case Value.STRING_FIXED:
+ case Value.STRING_IGNORECASE:
+ case Value.BYTES:
+ return (PageUtils.getShort(pageAddr, off + 1) & 0x8000) == 0;
+
+ default:
+ throw new UnsupportedOperationException("no get operation for fast index type " + type);
+ }
+ }
+
+ /**
+ * @param pageAddr Page address.
+ * @param off Offset.
+ * @param maxSize Maximum size to read.
+ * @param v Value to compare.
+ * @param comp Comparator.
+ * @return Compare result (-2 means we can't compare).
+ */
+ public int compare(long pageAddr, int off, int maxSize, Value v, Comparator<Value> comp) {
+ Value v1 = get(pageAddr, off, maxSize);
+
+ if (v1 == null)
+ return -2;
+
+ int c = comp.compare(v1, v);
+ assert c > -2;
+
+ if (size > 0)
+ return fixSort(c, sortType());
+
+ if (isValueFull(pageAddr, off) || canRelyOnCompare(c, v1, v))
+ return fixSort(c, sortType());
+
+ return -2;
+ }
+
/**
* @param pageAddr Page address.
* @param off Offset.
@@ -193,8 +360,14 @@ public class InlineIndexHelper {
* @return NUmber of bytes saved.
*/
public int put(long pageAddr, int off, Value val, int maxSize) {
- if (size() > 0 && size() + 1 > maxSize)
+ if (size > 0 && size + 1 > maxSize)
+ return 0;
+
+ if (size < 0 && maxSize < 4) {
+ // can't fit vartype field
+ PageUtils.putByte(pageAddr, off, (byte)Value.UNKNOWN);
return 0;
+ }
if (val.getType() == Value.NULL) {
PageUtils.putByte(pageAddr, off, (byte)Value.NULL);
@@ -208,34 +381,79 @@ public class InlineIndexHelper {
case Value.BOOLEAN:
PageUtils.putByte(pageAddr, off, (byte)val.getType());
PageUtils.putByte(pageAddr, off + 1, (byte)(val.getBoolean() ? 1 : 0));
- return size() + 1;
+ return size + 1;
case Value.BYTE:
PageUtils.putByte(pageAddr, off, (byte)val.getType());
PageUtils.putByte(pageAddr, off + 1, val.getByte());
- return size() + 1;
+ return size + 1;
case Value.SHORT:
PageUtils.putByte(pageAddr, off, (byte)val.getType());
PageUtils.putShort(pageAddr, off + 1, val.getShort());
- return size() + 1;
+ return size + 1;
case Value.INT:
PageUtils.putByte(pageAddr, off, (byte)val.getType());
PageUtils.putInt(pageAddr, off + 1, val.getInt());
- return size() + 1;
+ return size + 1;
case Value.LONG:
PageUtils.putByte(pageAddr, off, (byte)val.getType());
PageUtils.putLong(pageAddr, off + 1, val.getLong());
- return size() + 1;
+ return size + 1;
+
+ case Value.FLOAT: {
+ PageUtils.putByte(pageAddr, off, (byte)val.getType());
+ PageUtils.putInt(pageAddr, off + 1, Float.floatToIntBits(val.getFloat()));
+ return size + 1;
+ }
+
+ case Value.DOUBLE: {
+ PageUtils.putByte(pageAddr, off, (byte)val.getType());
+ PageUtils.putLong(pageAddr, off + 1, Double.doubleToLongBits(val.getDouble()));
+ return size + 1;
+ }
+
+ case Value.TIME:
+ PageUtils.putByte(pageAddr, off, (byte)val.getType());
+ PageUtils.putLong(pageAddr, off + 1, ((ValueTime)val).getNanos());
+ return size + 1;
+
+ case Value.DATE:
+ PageUtils.putByte(pageAddr, off, (byte)val.getType());
+ PageUtils.putLong(pageAddr, off + 1, ((ValueDate)val).getDateValue());
+ return size + 1;
+
+ case Value.TIMESTAMP:
+ PageUtils.putByte(pageAddr, off, (byte)val.getType());
+ PageUtils.putLong(pageAddr, off + 1, ((ValueTimestamp)val).getDateValue());
+ PageUtils.putLong(pageAddr, off + 9, ((ValueTimestamp)val).getTimeNanos());
+ return size + 1;
+
+ case Value.TIMESTAMP_UTC:
+ PageUtils.putByte(pageAddr, off, (byte)val.getType());
+ PageUtils.putLong(pageAddr, off + 1, ((ValueTimestampUtc)val).getUtcDateTimeNanos());
+ return size + 1;
+
+ case Value.UUID:
+ PageUtils.putByte(pageAddr, off, (byte)val.getType());
+ PageUtils.putLong(pageAddr, off + 1, ((ValueUuid)val).getHigh());
+ PageUtils.putLong(pageAddr, off + 9, ((ValueUuid)val).getLow());
+ return size + 1;
case Value.STRING:
- byte[] s;
- if (val.getString().getBytes(CHARSET).length + 3 <= maxSize)
- s = val.getString().getBytes(CHARSET);
- else
- s = toBytes(val.getString(), maxSize - 3);
+ case Value.STRING_FIXED:
+ case Value.STRING_IGNORECASE: {
+ short size;
+
+ byte[] s = val.getString().getBytes(CHARSET);
+ if (s.length + 3 <= maxSize)
+ size = (short)s.length;
+ else {
+ s = trimUTF8(s, maxSize - 3);
+ size = (short)(s.length | 0x8000);
+ }
if (s == null) {
// Can't fit anything to
@@ -244,10 +462,30 @@ public class InlineIndexHelper {
}
else {
PageUtils.putByte(pageAddr, off, (byte)val.getType());
- PageUtils.putShort(pageAddr, off + 1, (short)s.length);
+ PageUtils.putShort(pageAddr, off + 1, size);
PageUtils.putBytes(pageAddr, off + 3, s);
return s.length + 3;
}
+ }
+
+ case Value.BYTES: {
+ byte[] s;
+ short size;
+
+ PageUtils.putByte(pageAddr, off, (byte)val.getType());
+
+ if (val.getBytes().length + 3 <= maxSize) {
+ size = (short)val.getBytes().length;
+ PageUtils.putShort(pageAddr, off + 1, size);
+ PageUtils.putBytes(pageAddr, off + 3, val.getBytes());
+ }
+ else {
+ size = (short)((maxSize - 3) | 0x8000);
+ PageUtils.putShort(pageAddr, off + 1, size);
+ PageUtils.putBytes(pageAddr, off + 3, Arrays.copyOfRange(val.getBytes(), 0, maxSize - 3));
+ }
+ return size + 3;
+ }
default:
throw new UnsupportedOperationException("no get operation for fast index type " + type);
@@ -257,17 +495,16 @@ public class InlineIndexHelper {
/**
* Convert String to byte[] with size limit, according to UTF-8 encoding.
*
- * @param s String.
+ * @param bytes byte[].
* @param limit Size limit.
* @return byte[].
*/
- public static byte[] toBytes(String s, int limit) {
- byte[] bytes = s.getBytes(CHARSET);
+ public static byte[] trimUTF8(byte[] bytes, int limit) {
if (bytes.length <= limit)
return bytes;
- for (int i = bytes.length - 1; i > 0; i--) {
- if ((bytes[i] & 0xc0) != 0x80 && i <= limit) {
+ for (int i = limit; i > 0; i--) {
+ if ((bytes[i] & 0xc0) != 0x80) {
byte[] res = new byte[i];
System.arraycopy(bytes, 0, res, 0, i);
return res;
@@ -276,4 +513,57 @@ public class InlineIndexHelper {
return null;
}
+
+ /**
+ * @param c Compare result.
+ * @param shortVal Short value.
+ * @param v2 Second value;
+ * @return {@code true} if we can rely on compare result.
+ */
+ protected boolean canRelyOnCompare(int c, Value shortVal, Value v2) {
+ switch (type) {
+ case Value.STRING:
+ case Value.STRING_FIXED:
+ case Value.STRING_IGNORECASE:
+ case Value.BYTES:
+ if (shortVal.getType() == Value.NULL || v2.getType() == Value.NULL)
+ return true;
+
+ if (c == 0 && shortVal.getType() != Value.NULL && v2.getType() != Value.NULL)
+ return false;
+
+ int l1;
+ int l2;
+
+ if (type == Value.BYTES) {
+ l1 = shortVal.getBytes().length;
+ l2 = v2.getBytes().length;
+ }
+ else {
+ l1 = shortVal.getString().length();
+ l2 = v2.getString().length();
+ }
+
+ if (c < 0 && l1 <= l2) {
+ // Can't rely on compare, should use full value.
+ return false;
+ }
+
+ return true;
+
+ default:
+ return true;
+ }
+ }
+
+ /**
+ * Perform sort order correction.
+ *
+ * @param c Compare result.
+ * @param sortType Sort type.
+ * @return Fixed compare result.
+ */
+ public static int fixSort(int c, int sortType) {
+ return sortType == SortOrder.ASCENDING ? c : -c;
+ }
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/78c2a7f4/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2ExtrasInnerIO.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2ExtrasInnerIO.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2ExtrasInnerIO.java
index 00ba54e..5e6a36f 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2ExtrasInnerIO.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2ExtrasInnerIO.java
@@ -26,7 +26,6 @@ import org.apache.ignite.internal.processors.cache.database.tree.io.BPlusInnerIO
import org.apache.ignite.internal.processors.cache.database.tree.io.IOVersions;
import org.apache.ignite.internal.processors.cache.database.tree.io.PageIO;
import org.apache.ignite.internal.processors.query.h2.database.H2Tree;
-import org.apache.ignite.internal.processors.query.h2.database.H2TreeIndex;
import org.apache.ignite.internal.processors.query.h2.database.InlineIndexHelper;
import org.apache.ignite.internal.processors.query.h2.opt.GridH2Row;
import org.h2.result.SearchRow;
@@ -82,18 +81,15 @@ public class H2ExtrasInnerIO extends BPlusInnerIO<SearchRow> {
assert row0.link != 0 : row0;
- H2TreeIndex currIdx = H2TreeIndex.getCurrentIndex();
+ List<InlineIndexHelper> inlineIdxs = InlineIndexHelper.getCurrentInlineIndexes();
- assert currIdx != null;
+ assert inlineIdxs != null : "no inline index helpers";
- List<InlineIndexHelper> inlineIdx = currIdx.inlineIndexes();
-
- assert inlineIdx != null;
int fieldOff = 0;
- for (int i = 0; i < inlineIdx.size(); i++) {
- InlineIndexHelper idx = inlineIdx.get(i);
+ for (int i = 0; i < inlineIdxs.size(); i++) {
+ InlineIndexHelper idx = inlineIdxs.get(i);
int size = idx.put(pageAddr, off + fieldOff, row.getValue(idx.columnIndex()), payloadSize - fieldOff);
http://git-wip-us.apache.org/repos/asf/ignite/blob/78c2a7f4/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2ExtrasLeafIO.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2ExtrasLeafIO.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2ExtrasLeafIO.java
index 45558cf..c4bb387 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2ExtrasLeafIO.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/io/H2ExtrasLeafIO.java
@@ -26,7 +26,6 @@ import org.apache.ignite.internal.processors.cache.database.tree.io.BPlusLeafIO;
import org.apache.ignite.internal.processors.cache.database.tree.io.IOVersions;
import org.apache.ignite.internal.processors.cache.database.tree.io.PageIO;
import org.apache.ignite.internal.processors.query.h2.database.H2Tree;
-import org.apache.ignite.internal.processors.query.h2.database.H2TreeIndex;
import org.apache.ignite.internal.processors.query.h2.database.InlineIndexHelper;
import org.apache.ignite.internal.processors.query.h2.opt.GridH2Row;
import org.h2.result.SearchRow;
@@ -82,13 +81,9 @@ public class H2ExtrasLeafIO extends BPlusLeafIO<SearchRow> {
assert row0.link != 0;
- H2TreeIndex currIdx = H2TreeIndex.getCurrentIndex();
+ List<InlineIndexHelper> inlineIdxs = InlineIndexHelper.getCurrentInlineIndexes();
- assert currIdx != null;
-
- List<InlineIndexHelper> inlineIdxs = currIdx.inlineIndexes();
-
- assert inlineIdxs != null;
+ assert inlineIdxs != null : "no inline index helpers";
int fieldOff = 0;
http://git-wip-us.apache.org/repos/asf/ignite/blob/78c2a7f4/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java
index 30219dc..b93bd5e 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java
@@ -579,7 +579,7 @@ public class GridH2Table extends TableBase {
* @throws IgniteCheckedException If failed.
*/
@SuppressWarnings("LockAcquiredButNotSafelyReleased")
- boolean doUpdate(final GridH2Row row, boolean del) throws IgniteCheckedException {
+ public boolean doUpdate(final GridH2Row row, boolean del) throws IgniteCheckedException {
// Here we assume that each key can't be updated concurrently and case when different indexes
// getting updated from different threads with different rows with the same key is impossible.
GridUnsafeMemory mem = desc == null ? null : desc.memory();
http://git-wip-us.apache.org/repos/asf/ignite/blob/78c2a7f4/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndexTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndexTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndexTest.java
deleted file mode 100644
index 064da45..0000000
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/database/H2TreeIndexTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.query.h2.database;
-
-import junit.framework.TestCase;
-import org.h2.result.SortOrder;
-import org.h2.value.Value;
-import org.h2.value.ValueNull;
-import org.h2.value.ValueString;
-
-/**
- * Simple tests for {@link H2TreeIndex}.
- */
-public class H2TreeIndexTest extends TestCase {
-
- /** Test on String values compare */
- public void testRelyOnCompare() {
-
- InlineIndexHelper ha = new InlineIndexHelper(Value.STRING, 0, SortOrder.ASCENDING);
- InlineIndexHelper hd = new InlineIndexHelper(Value.STRING, 0, SortOrder.DESCENDING);
-
- // same size
- assertFalse(H2TreeIndex.canRelyOnCompare(0, ValueString.get("aabb"), ValueString.get("aabb"), ha));
- assertFalse(H2TreeIndex.canRelyOnCompare(0, ValueString.get("aabb"), ValueString.get("aabb"), hd));
-
- // second string is shorter
- assertTrue(H2TreeIndex.canRelyOnCompare(1, ValueString.get("aabb"), ValueString.get("aab"), ha));
- assertTrue(H2TreeIndex.canRelyOnCompare(-1, ValueString.get("aabb"), ValueString.get("aab"), hd));
-
- // second string is longer
- assertTrue(H2TreeIndex.canRelyOnCompare(1, ValueString.get("aabb"), ValueString.get("aaaaaa"), ha));
- assertTrue(H2TreeIndex.canRelyOnCompare(-1, ValueString.get("aabb"), ValueString.get("aaaaaa"), hd));
-
- assertFalse(H2TreeIndex.canRelyOnCompare(-1, ValueString.get("aab"), ValueString.get("aabbbbb"), ha));
- assertFalse(H2TreeIndex.canRelyOnCompare(1, ValueString.get("aab"), ValueString.get("aabbbbb"), hd));
-
- // one is null
- assertTrue(H2TreeIndex.canRelyOnCompare(1, ValueString.get("aabb"), ValueNull.INSTANCE, ha));
- assertTrue(H2TreeIndex.canRelyOnCompare(-1, ValueNull.INSTANCE, ValueString.get("aab"), ha));
- assertTrue(H2TreeIndex.canRelyOnCompare(0, ValueNull.INSTANCE, ValueNull.INSTANCE, ha));
-
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/78c2a7f4/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/database/InlineIndexHelperTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/database/InlineIndexHelperTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/database/InlineIndexHelperTest.java
index f65f0fa..bcbca1a 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/database/InlineIndexHelperTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/database/InlineIndexHelperTest.java
@@ -17,30 +17,340 @@
package org.apache.ignite.internal.processors.query.h2.database;
+import java.sql.Date;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Arrays;
+import java.util.UUID;
import junit.framework.TestCase;
+import org.apache.commons.io.Charsets;
+import org.apache.ignite.internal.mem.unsafe.UnsafeMemoryProvider;
+import org.apache.ignite.internal.pagemem.FullPageId;
+import org.apache.ignite.internal.pagemem.Page;
+import org.apache.ignite.internal.pagemem.PageIdAllocator;
+import org.apache.ignite.internal.pagemem.PageMemory;
+import org.apache.ignite.internal.pagemem.impl.PageMemoryNoStoreImpl;
+import org.apache.ignite.logger.java.JavaLogger;
+import org.h2.result.SortOrder;
+import org.h2.value.CompareMode;
+import org.h2.value.Value;
+import org.h2.value.ValueBoolean;
+import org.h2.value.ValueByte;
+import org.h2.value.ValueBytes;
+import org.h2.value.ValueDate;
+import org.h2.value.ValueDouble;
+import org.h2.value.ValueFloat;
+import org.h2.value.ValueInt;
+import org.h2.value.ValueLong;
+import org.h2.value.ValueNull;
+import org.h2.value.ValueShort;
+import org.h2.value.ValueString;
+import org.h2.value.ValueTime;
+import org.h2.value.ValueTimestamp;
+import org.h2.value.ValueTimestampUtc;
+import org.h2.value.ValueUuid;
/**
* Simple tests for {@link InlineIndexHelper}.
*/
public class InlineIndexHelperTest extends TestCase {
+ /** */
+ private static final int CACHE_ID = 42;
+
+ /** */
+ private static final int PAGE_SIZE = 1024;
+
+ /** */
+ private static final long MB = 1024;
+
+ /** */
+ private static final int CPUS = Runtime.getRuntime().availableProcessors();
/** Test utf-8 string cutting. */
public void testConvert() {
// 8 bytes total: 1b, 1b, 3b, 3b.
- byte[] bytes = InlineIndexHelper.toBytes("00\u20ac\u20ac", 7);
+ byte[] bytes = InlineIndexHelper.trimUTF8("00\u20ac\u20ac".getBytes(Charsets.UTF_8), 7);
assertEquals(5, bytes.length);
String s = new String(bytes);
assertEquals(3, s.length());
+
+ bytes = InlineIndexHelper.trimUTF8("aaaaaa".getBytes(Charsets.UTF_8), 4);
+ assertEquals(4, bytes.length);
}
/** Limit is too small to cut */
- public void testShort() {
+ public void testStringCut() {
// 6 bytes total: 3b, 3b.
- byte[] bytes = InlineIndexHelper.toBytes("\u20ac\u20ac", 2);
+ byte[] bytes = InlineIndexHelper.trimUTF8("\u20ac\u20ac".getBytes(Charsets.UTF_8), 2);
assertNull(bytes);
}
+ /** Test on String values compare */
+ public void testRelyOnCompare() {
+ InlineIndexHelper ha = new InlineIndexHelper(Value.STRING, 0, SortOrder.ASCENDING);
+
+ // same size
+ assertFalse(getRes(ha, "aabb", "aabb"));
+
+ // second string is shorter
+ assertTrue(getRes(ha, "aabb", "aac"));
+ assertTrue(getRes(ha, "aabb", "aaa"));
+
+ // second string is longer
+ assertTrue(getRes(ha, "aabb", "aaaaaa"));
+ assertFalse(getRes(ha, "aaa", "aaaaaa"));
+
+ // one is null
+ assertTrue(getRes(ha, "a", null));
+ assertTrue(getRes(ha, null, "a"));
+ assertTrue(getRes(ha, null, null));
+ }
+
+ /** Test on Bytes values compare */
+ public void testRelyOnCompareBytes() {
+ InlineIndexHelper ha = new InlineIndexHelper(Value.BYTES, 0, SortOrder.ASCENDING);
+
+ // same size
+ assertFalse(getResBytes(ha, new byte[] {1, 2, 3, 4}, new byte[] {1, 2, 3, 4}));
+
+ // second aray is shorter
+ assertTrue(getResBytes(ha, new byte[] {1, 2, 2, 2}, new byte[] {1, 1, 2}));
+ assertTrue(getResBytes(ha, new byte[] {1, 1, 1, 2}, new byte[] {1, 1, 2}));
+
+ // second array is longer
+ assertTrue(getResBytes(ha, new byte[] {1, 2}, new byte[] {1, 1, 1}));
+ assertFalse(getResBytes(ha, new byte[] {1, 1}, new byte[] {1, 1, 2}));
+
+ // one is null
+ assertTrue(getResBytes(ha, new byte[] {1, 2, 3, 4}, null));
+ assertTrue(getResBytes(ha, null, new byte[] {1, 2, 3, 4}));
+ assertTrue(getResBytes(ha, null, null));
+ }
+
+ /** */
+ public void testStringTruncate() throws Exception {
+ long[] sizes = new long[CPUS];
+
+ for (int i = 0; i < sizes.length; i++)
+ sizes[i] = 1024 * MB / CPUS;
+
+ PageMemory pageMem = new PageMemoryNoStoreImpl(new JavaLogger(),
+ new UnsafeMemoryProvider(sizes),
+ null,
+ PAGE_SIZE,
+ false);
+
+ pageMem.start();
+ Page page = null;
+
+ try {
+ FullPageId fullId = new FullPageId(pageMem.allocatePage(CACHE_ID, 1, PageIdAllocator.FLAG_DATA), CACHE_ID);
+ page = pageMem.page(fullId.cacheId(), fullId.pageId());
+ long pageAddr = page.getForReadPointer();
+
+ int off = 0;
+
+ InlineIndexHelper ih = new InlineIndexHelper(Value.STRING, 1, 0);
+ ih.put(pageAddr, off, ValueString.get("aaaaaaa"), 3 + 5);
+
+ assertFalse(ih.isValueFull(pageAddr, off));
+
+ assertEquals("aaaaa", ih.get(pageAddr, off, 3 + 5).getString());
+
+ ih.put(pageAddr, off, ValueString.get("aaa"), 3 + 5);
+
+ assertTrue(ih.isValueFull(pageAddr, off));
+
+ assertEquals("aaa", ih.get(pageAddr, off, 3 + 5).getString());
+ }
+ finally {
+ if (page != null)
+ pageMem.releasePage(page);
+ pageMem.stop();
+ }
+ }
+
+ /** */
+ public void testBytes() throws Exception {
+ long[] sizes = new long[CPUS];
+
+ for (int i = 0; i < sizes.length; i++)
+ sizes[i] = 1024 * MB / CPUS;
+
+ PageMemory pageMem = new PageMemoryNoStoreImpl(new JavaLogger(),
+ new UnsafeMemoryProvider(sizes),
+ null,
+ PAGE_SIZE,
+ false);
+
+ pageMem.start();
+ Page page = null;
+
+ try {
+ FullPageId fullId = new FullPageId(pageMem.allocatePage(CACHE_ID, 1, PageIdAllocator.FLAG_DATA), CACHE_ID);
+ page = pageMem.page(fullId.cacheId(), fullId.pageId());
+ long pageAddr = page.getForReadPointer();
+
+ int off = 0;
+
+ InlineIndexHelper ih = new InlineIndexHelper(Value.BYTES, 1, 0);
+
+ ih.put(pageAddr, off, ValueBytes.get(new byte[] {1, 2, 3, 4, 5}), 3 + 3);
+
+ assertFalse(ih.isValueFull(pageAddr, off));
+
+ assertTrue(Arrays.equals(new byte[] {1, 2, 3}, ih.get(pageAddr, off, 3 + 5).getBytes()));
+
+ ih.put(pageAddr, off, ValueBytes.get(new byte[] {1, 2, 3, 4, 5}), 3 + 5);
+
+ assertTrue(ih.isValueFull(pageAddr, off));
+
+ assertTrue(Arrays.equals(new byte[] {1, 2, 3, 4, 5}, ih.get(pageAddr, off, 3 + 5).getBytes()));
+ }
+ finally {
+ if (page != null)
+ pageMem.releasePage(page);
+ pageMem.stop();
+ }
+ }
+
+ /** */
+ public void testNull() throws Exception {
+ testPutGet(ValueInt.get(-1), ValueNull.INSTANCE, ValueInt.get(3));
+ }
+
+ /** */
+ public void testBoolean() throws Exception {
+ testPutGet(ValueBoolean.get(true), ValueBoolean.get(false), ValueBoolean.get(true));
+ }
+
+ /** */
+ public void testByte() throws Exception {
+ testPutGet(ValueByte.get((byte)-1), ValueByte.get((byte)2), ValueByte.get((byte)3));
+ }
+
+ /** */
+ public void testShort() throws Exception {
+ testPutGet(ValueShort.get((short)-32000), ValueShort.get((short)2), ValueShort.get((short)3));
+ }
+
+ /** */
+ public void testInt() throws Exception {
+ testPutGet(ValueInt.get(-1), ValueInt.get(2), ValueInt.get(3));
+ }
+
+ /** */
+ public void testLong() throws Exception {
+ testPutGet(ValueLong.get(-1), ValueLong.get(2), ValueLong.get(3));
+ }
+
+ /** */
+ public void testFloat() throws Exception {
+ testPutGet(ValueFloat.get(1.1f), ValueFloat.get(2.2f), ValueFloat.get(1.1f));
+ }
+
+ /** */
+ public void testDouble() throws Exception {
+ testPutGet(ValueDouble.get(1.1f), ValueDouble.get(2.2f), ValueDouble.get(1.1f));
+ }
+
+ /** */
+ public void testDate() throws Exception {
+ testPutGet(ValueDate.get(Date.valueOf("2017-02-20")),
+ ValueDate.get(Date.valueOf("2017-02-21")),
+ ValueDate.get(Date.valueOf("2017-02-19")));
+ }
+
+ /** */
+ public void testTime() throws Exception {
+ testPutGet(ValueTime.get(Time.valueOf("10:01:01")),
+ ValueTime.get(Time.valueOf("11:02:02")),
+ ValueTime.get(Time.valueOf("12:03:03")));
+ }
+
+ /** */
+ public void testTimestamp() throws Exception {
+ testPutGet(ValueTimestamp.get(Timestamp.valueOf("2017-02-20 10:01:01")),
+ ValueTimestamp.get(Timestamp.valueOf("2017-02-20 10:01:01")),
+ ValueTimestamp.get(Timestamp.valueOf("2017-02-20 10:01:01")));
+ }
+
+ /** */
+ public void testTimestampUTC() throws Exception {
+ testPutGet(ValueTimestampUtc.fromMillis(System.currentTimeMillis()),
+ ValueTimestampUtc.fromMillis(System.currentTimeMillis() + 100),
+ ValueTimestampUtc.fromMillis(System.currentTimeMillis() + 200));
+ }
+
+ /** */
+ public void testUUID() throws Exception {
+ testPutGet(ValueUuid.get(UUID.randomUUID().toString()),
+ ValueUuid.get(UUID.randomUUID().toString()),
+ ValueUuid.get(UUID.randomUUID().toString()));
+ }
+
+ /** */
+ private void testPutGet(Value v1, Value v2, Value v3) throws Exception {
+ long[] sizes = new long[CPUS];
+
+ for (int i = 0; i < sizes.length; i++)
+ sizes[i] = 1024 * MB / CPUS;
+
+ PageMemory pageMem = new PageMemoryNoStoreImpl(new JavaLogger(),
+ new UnsafeMemoryProvider(sizes),
+ null,
+ PAGE_SIZE,
+ false);
+
+ pageMem.start();
+ Page page = null;
+
+ try {
+ FullPageId fullId = new FullPageId(pageMem.allocatePage(CACHE_ID, 1, PageIdAllocator.FLAG_DATA), CACHE_ID);
+ page = pageMem.page(fullId.cacheId(), fullId.pageId());
+ long pageAddr = page.getForReadPointer();
+
+ int off = 0;
+ int max = 255;
+
+ InlineIndexHelper ih = new InlineIndexHelper(v1.getType(), 1, 0);
+
+ off += ih.put(pageAddr, off, v1, max - off);
+ off += ih.put(pageAddr, off, v2, max - off);
+ off += ih.put(pageAddr, off, v3, max - off);
+
+ Value v11 = ih.get(pageAddr, 0, max);
+ Value v22 = ih.get(pageAddr, ih.fullSize(pageAddr, 0), max);
+
+ assertEquals(v1.getObject(), v11.getObject());
+ assertEquals(v2.getObject(), v22.getObject());
+ }
+ finally {
+ if (page != null)
+ pageMem.releasePage(page);
+ pageMem.stop();
+ }
+ }
+
+ /** */
+ private boolean getRes(InlineIndexHelper ha, String s1, String s2) {
+ Value v1 = s1 == null ? ValueNull.INSTANCE : ValueString.get(s1);
+ Value v2 = s2 == null ? ValueNull.INSTANCE : ValueString.get(s2);
+
+ int c = v1.compareTypeSafe(v2, CompareMode.getInstance(CompareMode.DEFAULT, 0));
+ return ha.canRelyOnCompare(c, v1, v2);
+ }
+
+ /** */
+ private boolean getResBytes(InlineIndexHelper ha, byte[] b1, byte[] b2) {
+ Value v1 = b1 == null ? ValueNull.INSTANCE : ValueBytes.get(b1);
+ Value v2 = b2 == null ? ValueNull.INSTANCE : ValueBytes.get(b2);
+
+ int c = v1.compareTypeSafe(v2, CompareMode.getInstance(CompareMode.DEFAULT, 0));
+ return ha.canRelyOnCompare(c, v1, v2);
+ }
+
}
\ No newline at end of file
[2/2] ignite git commit: ignite-3477 - minor
Posted by se...@apache.org.
ignite-3477 - minor
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/c4490ddc
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/c4490ddc
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/c4490ddc
Branch: refs/heads/ignite-3477
Commit: c4490ddce4a836fd41fa6d65d3fbfd7b94e56995
Parents: 78c2a7f
Author: Sergi Vladykin <se...@gmail.com>
Authored: Wed Mar 1 22:23:26 2017 +0300
Committer: Sergi Vladykin <se...@gmail.com>
Committed: Wed Mar 1 22:23:26 2017 +0300
----------------------------------------------------------------------
.../org/apache/ignite/testframework/junits/GridAbstractTest.java | 2 +-
.../ignite/internal/processors/query/h2/opt/GridH2Table.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/c4490ddc/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
index 3be511e..b45e173 100644
--- a/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/testframework/junits/GridAbstractTest.java
@@ -1263,7 +1263,7 @@ public abstract class GridAbstractTest extends TestCase {
public String getTestGridName() {
String[] parts = getClass().getName().split("\\.");
- return "tg1";
+ return parts[parts.length - 2] + '.' + parts[parts.length - 1];
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/c4490ddc/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java
index b93bd5e..30219dc 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2Table.java
@@ -579,7 +579,7 @@ public class GridH2Table extends TableBase {
* @throws IgniteCheckedException If failed.
*/
@SuppressWarnings("LockAcquiredButNotSafelyReleased")
- public boolean doUpdate(final GridH2Row row, boolean del) throws IgniteCheckedException {
+ boolean doUpdate(final GridH2Row row, boolean del) throws IgniteCheckedException {
// Here we assume that each key can't be updated concurrently and case when different indexes
// getting updated from different threads with different rows with the same key is impossible.
GridUnsafeMemory mem = desc == null ? null : desc.memory();