You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by yz...@apache.org on 2017/10/13 17:43:21 UTC
[36/50] [abbrv] ignite git commit: ignite-5918 Adding and searching
objects in index tree produces a lot of garbage
ignite-5918 Adding and searching objects in index tree produces a lot of garbage
(cherry picked from commit 0e0c2c7)
(cherry picked from commit 20739d8)
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/71cd1e91
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/71cd1e91
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/71cd1e91
Branch: refs/heads/ignite-2.1.5-p1
Commit: 71cd1e9188f59293c505dedd37c325687f3159f0
Parents: 212603e
Author: Igor Seliverstov <gv...@gmail.com>
Authored: Wed Aug 9 18:46:53 2017 +0300
Committer: Dmitriy Govorukhin <dm...@gmail.com>
Committed: Fri Sep 22 15:28:26 2017 +0300
----------------------------------------------------------------------
.../java/org/apache/ignite/IgniteCache.java | 1 -
.../query/h2/database/H2TreeIndex.java | 6 +-
.../query/h2/database/InlineIndexHelper.java | 414 ++++++++++++++++++-
.../h2/database/InlineIndexHelperTest.java | 248 +++++++++--
.../IgniteCacheWithIndexingTestSuite.java | 3 +
5 files changed, 642 insertions(+), 30 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/71cd1e91/modules/core/src/main/java/org/apache/ignite/IgniteCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteCache.java b/modules/core/src/main/java/org/apache/ignite/IgniteCache.java
index 0cf2a82..973eeab 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteCache.java
@@ -1261,7 +1261,6 @@ public interface IgniteCache<K, V> extends javax.cache.Cache<K, V>, IgniteAsyncS
public <T> IgniteFuture<Map<K, EntryProcessorResult<T>>> invokeAllAsync(Set<? extends K> keys,
EntryProcessor<K, V, T> entryProcessor, Object... args) throws TransactionException;
-
/**
* Invokes an {@link CacheEntryProcessor} against the set of {@link javax.cache.Cache.Entry}s
* specified by the set of keys.
http://git-wip-us.apache.org/repos/asf/ignite/blob/71cd1e91/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 35bfdc1..de5dc75 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
@@ -145,7 +145,11 @@ public class H2TreeIndex extends GridH2IndexBase {
if (!InlineIndexHelper.AVAILABLE_TYPES.contains(col.column.getType()))
break;
- InlineIndexHelper idx = new InlineIndexHelper(col.column.getType(), col.column.getColumnId(), col.sortType);
+ InlineIndexHelper idx = new InlineIndexHelper(
+ col.column.getType(),
+ col.column.getColumnId(),
+ col.sortType,
+ table.getCompareMode());
res.add(idx);
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/71cd1e91/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 19cf857..1789ac8 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
@@ -23,8 +23,10 @@ import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import org.apache.ignite.internal.pagemem.PageUtils;
+import org.apache.ignite.internal.util.GridUnsafe;
import org.h2.result.SortOrder;
import org.h2.table.IndexColumn;
+import org.h2.value.CompareMode;
import org.h2.value.Value;
import org.h2.value.ValueBoolean;
import org.h2.value.ValueByte;
@@ -84,16 +86,28 @@ public class InlineIndexHelper {
/** */
private final short size;
+ /** */
+ private final boolean compareBinaryUnsigned;
+
+ /** */
+ private final boolean compareStringsOptimized;
+
/**
* @param type Index type (see {@link Value}).
* @param colIdx Index column index.
* @param sortType Column sort type (see {@link IndexColumn#sortType}).
*/
- public InlineIndexHelper(int type, int colIdx, int sortType) {
+ public InlineIndexHelper(int type, int colIdx, int sortType, CompareMode compareMode) {
this.type = type;
this.colIdx = colIdx;
this.sortType = sortType;
+ this.compareBinaryUnsigned = compareMode.isBinaryUnsigned();
+
+ // Optimized strings comparison can be used only if there are no custom collators.
+ // H2 internal comparison will be used otherwise (may be slower).
+ this.compareStringsOptimized = CompareMode.OFF.equals(compareMode.getName());
+
switch (type) {
case Value.BOOLEAN:
case Value.BYTE:
@@ -330,13 +344,17 @@ public class InlineIndexHelper {
* @return Compare result (-2 means we can't compare).
*/
public int compare(long pageAddr, int off, int maxSize, Value v, Comparator<Value> comp) {
+ int c = tryCompareOptimized(pageAddr, off, maxSize, v);
+
+ if (c != Integer.MIN_VALUE)
+ return c;
+
Value v1 = get(pageAddr, off, maxSize);
if (v1 == null)
return -2;
- int c = comp.compare(v1, v);
- c = c != 0 ? c > 0 ? 1 : -1 : 0;
+ c = Integer.signum(comp.compare(v1, v));
if (size > 0)
return fixSort(c, sortType());
@@ -350,6 +368,396 @@ public class InlineIndexHelper {
/**
* @param pageAddr Page address.
* @param off Offset.
+ * @param maxSize Maximum size to read.
+ * @param v Value to compare.
+ * @return Compare result ({@code Integer.MIN_VALUE} means unsupported operation; {@code -2} - can't compare).
+ */
+ private int tryCompareOptimized(long pageAddr, int off, int maxSize, Value v) {
+ int type;
+
+ if ((size > 0 && size + 1 > maxSize)
+ || maxSize < 1
+ || (type = PageUtils.getByte(pageAddr, off)) == Value.UNKNOWN)
+ return -2;
+
+ if (type == Value.NULL)
+ return Integer.MIN_VALUE;
+
+ if (this.type != type)
+ throw new UnsupportedOperationException("Invalid fast index type: " + type);
+
+ type = Value.getHigherOrder(type, v.getType());
+
+ switch (type) {
+ case Value.BOOLEAN:
+ case Value.BYTE:
+ case Value.SHORT:
+ case Value.INT:
+ case Value.LONG:
+ case Value.FLOAT:
+ case Value.DOUBLE:
+ return compareAsPrimitive(pageAddr, off, v, type);
+
+ case Value.TIME:
+ case Value.DATE:
+ case Value.TIMESTAMP:
+ return compareAsDateTime(pageAddr, off, v, type);
+
+ case Value.STRING:
+ case Value.STRING_FIXED:
+ case Value.STRING_IGNORECASE:
+ if (compareStringsOptimized)
+ return compareAsString(pageAddr, off, v, type == Value.STRING_IGNORECASE);
+
+ break;
+
+ case Value.BYTES:
+ return compareAsBytes(pageAddr, off, v);
+ }
+
+ return Integer.MIN_VALUE;
+ }
+
+ /**
+ * @param pageAddr Page address.
+ * @param off Offset.
+ * @param v Value to compare.
+ * @param type Highest value type.
+ * @return Compare result ({@code -2} means we can't compare).
+ */
+ private int compareAsDateTime(long pageAddr, int off, Value v, int type) {
+ // only compatible types are supported now.
+ if(PageUtils.getByte(pageAddr, off) == type) {
+ switch (type) {
+ case Value.TIME:
+ long nanos1 = PageUtils.getLong(pageAddr, off + 1);
+ long nanos2 = ((ValueTime)v.convertTo(type)).getNanos();
+
+ return fixSort(Long.signum(nanos1 - nanos2), sortType());
+
+ case Value.DATE:
+ long date1 = PageUtils.getLong(pageAddr, off + 1);
+ long date2 = ((ValueDate)v.convertTo(type)).getDateValue();
+
+ return fixSort(Long.signum(date1 - date2), sortType());
+
+ case Value.TIMESTAMP:
+ ValueTimestamp v0 = (ValueTimestamp) v.convertTo(type);
+
+ date1 = PageUtils.getLong(pageAddr, off + 1);
+ date2 = v0.getDateValue();
+
+ int c = Long.signum(date1 - date2);
+
+ if (c == 0) {
+ nanos1 = PageUtils.getLong(pageAddr, off + 9);
+ nanos2 = v0.getTimeNanos();
+
+ c = Long.signum(nanos1 - nanos2);
+ }
+
+ return fixSort(c, sortType());
+ }
+ }
+
+ return Integer.MIN_VALUE;
+ }
+
+ /**
+ * @param pageAddr Page address.
+ * @param off Offset.
+ * @param v Value to compare.
+ * @param type Highest value type.
+ * @return Compare result ({@code -2} means we can't compare).
+ */
+ private int compareAsPrimitive(long pageAddr, int off, Value v, int type) {
+ // only compatible types are supported now.
+ if(PageUtils.getByte(pageAddr, off) == type) {
+ switch (type) {
+ case Value.BOOLEAN:
+ boolean bool1 = PageUtils.getByte(pageAddr, off + 1) != 0;
+ boolean bool2 = v.getBoolean();
+
+ return fixSort(Boolean.compare(bool1, bool2), sortType());
+
+ case Value.BYTE:
+ byte byte1 = PageUtils.getByte(pageAddr, off + 1);
+ byte byte2 = v.getByte();
+
+ return fixSort(Integer.signum(byte1 - byte2), sortType());
+
+ case Value.SHORT:
+ short short1 = PageUtils.getShort(pageAddr, off + 1);
+ short short2 = v.getShort();
+
+ return fixSort(Integer.signum(short1 - short2), sortType());
+
+ case Value.INT:
+ int int1 = PageUtils.getInt(pageAddr, off + 1);
+ int int2 = v.getInt();
+
+ return fixSort(Integer.compare(int1, int2), sortType());
+
+ case Value.LONG:
+ long long1 = PageUtils.getLong(pageAddr, off + 1);
+ long long2 = v.getLong();
+
+ return fixSort(Long.compare(long1, long2), sortType());
+
+ case Value.FLOAT:
+ float float1 = Float.intBitsToFloat(PageUtils.getInt(pageAddr, off + 1));
+ float float2 = v.getFloat();
+
+ return fixSort(Float.compare(float1, float2), sortType());
+
+ case Value.DOUBLE:
+ double double1 = Double.longBitsToDouble(PageUtils.getLong(pageAddr, off + 1));
+ double double2 = v.getDouble();
+
+ return fixSort(Double.compare(double1, double2), sortType());
+ }
+ }
+
+ return Integer.MIN_VALUE;
+ }
+
+ /**
+ * @param pageAddr Page address.
+ * @param off Offset.
+ * @param v Value to compare.
+ * @return Compare result ({@code -2} means we can't compare).
+ */
+ private int compareAsBytes(long pageAddr, int off, Value v) {
+ byte[] bytes = v.getBytesNoCopy();
+
+ int len1;
+
+ long addr = pageAddr + off + 1; // Skip type.
+
+ if(size > 0)
+ // Fixed size value.
+ len1 = size;
+ else {
+ len1 = PageUtils.getShort(pageAddr, off + 1) & 0x7FFF;
+
+ addr += 2; // Skip size.
+ }
+
+ int len2 = bytes.length;
+
+ int len = Math.min(len1, len2);
+
+ if (compareBinaryUnsigned) {
+ for (int i = 0; i < len; i++) {
+ int b1 = GridUnsafe.getByte(addr + i) & 0xff;
+ int b2 = bytes[i] & 0xff;
+
+ if (b1 != b2)
+ return fixSort(Integer.signum(b1 - b2), sortType());
+ }
+ }
+ else {
+ for (int i = 0; i < len; i++) {
+ byte b1 = GridUnsafe.getByte(addr + i);
+ byte b2 = bytes[i];
+
+ if (b1 != b2)
+ return fixSort(Integer.signum(b1 - b2), sortType());
+ }
+ }
+
+ int res = Integer.signum(len1 - len2);
+
+ if(isValueFull(pageAddr, off))
+ return fixSort(res, sortType());
+
+ if (res >= 0)
+ // There are two cases:
+ // a) The values are equal but the stored value is truncated, so that it's bigger.
+ // b) Even truncated current value is longer, so that it's bigger.
+ return fixSort(1, sortType());
+
+ return -2;
+ }
+
+ /**
+ * @param pageAddr Page address.
+ * @param off Offset.
+ * @param v Value to compare.
+ * @param ignoreCase {@code True} if a case-insensitive comparison should be used.
+ * @return Compare result ({@code -2} means we can't compare).
+ */
+ private int compareAsString(long pageAddr, int off, Value v, boolean ignoreCase) {
+ String s = v.getString();
+
+ int len1 = PageUtils.getShort(pageAddr, off + 1) & 0x7FFF;
+ int len2 = s.length();
+
+ int c, c2, c3, c4, cntr1 = 0, cntr2 = 0;
+ char v1, v2;
+
+ long addr = pageAddr + off + 3; // Skip length and type byte.
+
+ // Try reading ASCII.
+ while (cntr1 < len1 && cntr2 < len2) {
+ c = (int) GridUnsafe.getByte(addr) & 0xFF;
+
+ if (c > 127)
+ break;
+
+ cntr1++; addr++;
+
+ v1 = (char)c;
+ v2 = s.charAt(cntr2++);
+
+ if (ignoreCase) {
+ v1 = Character.toUpperCase(v1);
+ v2 = Character.toUpperCase(v2);
+ }
+
+ if (v1 != v2)
+ return fixSort(Integer.signum(v1 - v2), sortType());
+ }
+
+ // read other
+ while (cntr1 < len1 && cntr2 < len2) {
+ c = (int) GridUnsafe.getByte(addr++) & 0xFF;
+
+ switch (c >> 4) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ /* 0xxxxxxx*/
+ cntr1++;
+
+ v1 = (char)c;
+
+ break;
+
+ case 12:
+ case 13:
+ /* 110x xxxx 10xx xxxx*/
+ cntr1 += 2;
+
+ if (cntr1 > len1)
+ throw new IllegalStateException("Malformed input (partial character at the end).");
+
+ c2 = (int) GridUnsafe.getByte(addr++) & 0xFF;
+
+ if ((c2 & 0xC0) != 0x80)
+ throw new IllegalStateException("Malformed input around byte: " + (cntr1 - 2));
+
+ c = c & 0x1F;
+ c = (c << 6) | (c2 & 0x3F);
+
+ v1 = (char)c;
+
+ break;
+
+ case 14:
+ /* 1110 xxxx 10xx xxxx 10xx xxxx */
+ cntr1 += 3;
+
+ if (cntr1 > len1)
+ throw new IllegalStateException("Malformed input (partial character at the end).");
+
+ c2 = (int) GridUnsafe.getByte(addr++) & 0xFF;
+
+ c3 = (int) GridUnsafe.getByte(addr++) & 0xFF;
+
+ if (((c2 & 0xC0) != 0x80) || ((c3 & 0xC0) != 0x80))
+ throw new IllegalStateException("Malformed input around byte: " + (cntr1 - 3));
+
+ c = c & 0x0F;
+ c = (c << 6) | (c2 & 0x3F);
+ c = (c << 6) | (c3 & 0x3F);
+
+ v1 = (char)c;
+
+ break;
+
+ case 15:
+ /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
+ cntr1 += 4;
+
+ if (cntr1 > len1)
+ throw new IllegalStateException("Malformed input (partial character at the end).");
+
+ c2 = (int) GridUnsafe.getByte(addr++) & 0xFF;
+
+ c3 = (int) GridUnsafe.getByte(addr++) & 0xFF;
+
+ c4 = (int) GridUnsafe.getByte(addr++) & 0xFF;
+
+ if (((c & 0xF8) != 0xf0) || ((c2 & 0xC0) != 0x80) || ((c3 & 0xC0) != 0x80) || ((c4 & 0xC0) != 0x80))
+ throw new IllegalStateException("Malformed input around byte: " + (cntr1 - 4));
+
+ c = c & 0x07;
+ c = (c << 6) | (c2 & 0x3F);
+ c = (c << 6) | (c3 & 0x3F);
+ c = (c << 6) | (c4 & 0x3F);
+
+ c = c - 0x010000; // Subtract 0x010000, c is now 0..fffff (20 bits)
+
+ // height surrogate
+ v1 = (char)(0xD800 + ((c >> 10) & 0x7FF));
+ v2 = s.charAt(cntr2++);
+
+ if (v1 != v2)
+ return fixSort(Integer.signum(v1 - v2), sortType());
+
+ if (cntr2 == len2)
+ // The string is malformed (partial partial character at the end).
+ // Finish comparison here.
+ return fixSort(1, sortType());
+
+ // Low surrogate.
+ v1 = (char)(0xDC00 + (c & 0x3FF));
+ v2 = s.charAt(cntr2++);
+
+ if (v1 != v2)
+ return fixSort(Integer.signum(v1 - v2), sortType());
+
+ continue;
+
+ default:
+ /* 10xx xxxx */
+ throw new IllegalStateException("Malformed input around byte: " + cntr1);
+ }
+
+ v2 = s.charAt(cntr2++);
+
+ if (ignoreCase) {
+ v1 = Character.toUpperCase(v1);
+ v2 = Character.toUpperCase(v2);
+ }
+
+ if (v1 != v2)
+ return fixSort(Integer.signum(v1 - v2), sortType());
+ }
+
+ int res = cntr1 == len1 && cntr2 == len2 ? 0 : cntr1 == len1 ? -1 : 1;
+
+ if (isValueFull(pageAddr, off))
+ return fixSort(res, sortType());
+
+ if (res >= 0)
+ // There are two cases:
+ // a) The values are equal but the stored value is truncated, so that it's bigger.
+ // b) Even truncated current value is longer, so that it's bigger.
+ return fixSort(1, sortType());
+
+ return -2;
+ }
+
+ /**
+ * @param pageAddr Page address.
+ * @param off Offset.
* @param val Value.
* @return NUmber of bytes saved.
*/
http://git-wip-us.apache.org/repos/asf/ignite/blob/71cd1e91/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 a2a3a72..fc06502 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
@@ -21,8 +21,9 @@ import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Arrays;
+import java.util.Comparator;
import java.util.UUID;
-import junit.framework.TestCase;
+import java.util.concurrent.ThreadLocalRandom;
import org.apache.commons.io.Charsets;
import org.apache.ignite.configuration.MemoryPolicyConfiguration;
import org.apache.ignite.internal.mem.unsafe.UnsafeMemoryProvider;
@@ -30,7 +31,7 @@ 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.internal.processors.cache.persistence.MemoryMetricsImpl;
-import org.apache.ignite.logger.java.JavaLogger;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.h2.result.SortOrder;
import org.h2.value.CompareMode;
import org.h2.value.Value;
@@ -52,7 +53,7 @@ import org.h2.value.ValueUuid;
/**
* Simple tests for {@link InlineIndexHelper}.
*/
-public class InlineIndexHelperTest extends TestCase {
+public class InlineIndexHelperTest extends GridCommonAbstractTest {
/** */
private static final int CACHE_ID = 42;
@@ -79,17 +80,163 @@ public class InlineIndexHelperTest extends TestCase {
assertEquals(4, bytes.length);
}
+ /** */
+ public void testCompare1bytes() throws Exception {
+ int maxSize = 3 + 2; // 2 ascii chars + 3 bytes header.
+
+ assertEquals(0, putAndCompare("aa", "aa", maxSize));
+ assertEquals(-1, putAndCompare("aa", "bb", maxSize));
+ assertEquals(-1, putAndCompare("aaa", "bbb", maxSize));
+ assertEquals(1, putAndCompare("bbb", "aaa", maxSize));
+ assertEquals(1, putAndCompare("aaa", "aa", maxSize));
+ assertEquals(1, putAndCompare("aaa", "a", maxSize));
+ assertEquals(-2, putAndCompare("aaa", "aaa", maxSize));
+ assertEquals(-2, putAndCompare("aaa", "aab", maxSize));
+ assertEquals(-2, putAndCompare("aab", "aaa", maxSize));
+ }
+
+ /** */
+ public void testCompare2bytes() throws Exception {
+ int maxSize = 3 + 4; // 2 2-bytes chars + 3 bytes header.
+
+ assertEquals(0, putAndCompare("¡¡", "¡¡", maxSize));
+ assertEquals(-1, putAndCompare("¡¡", "¢¢", maxSize));
+ assertEquals(-1, putAndCompare("¡¡¡", "¢¢¢", maxSize));
+ assertEquals(1, putAndCompare("¢¢¢", "¡¡¡", maxSize));
+ assertEquals(1, putAndCompare("¡¡¡", "¡¡", maxSize));
+ assertEquals(1, putAndCompare("¡¡¡", "¡", maxSize));
+ assertEquals(-2, putAndCompare("¡¡¡", "¡¡¡", maxSize));
+ assertEquals(-2, putAndCompare("¡¡¡", "¡¡¢", maxSize));
+ assertEquals(-2, putAndCompare("¡¡¢", "¡¡¡", maxSize));
+ }
+
+ /** */
+ public void testCompare3bytes() throws Exception {
+ int maxSize = 3 + 6; // 2 3-bytes chars + 3 bytes header.
+
+ assertEquals(0, putAndCompare("ऄऄ", "ऄऄ", maxSize));
+ assertEquals(-1, putAndCompare("ऄऄ", "अअ", maxSize));
+ assertEquals(-1, putAndCompare("ऄऄऄ", "अअअ", maxSize));
+ assertEquals(1, putAndCompare("अअअ", "ऄऄऄ", maxSize));
+ assertEquals(1, putAndCompare("ऄऄऄ", "ऄऄ", maxSize));
+ assertEquals(1, putAndCompare("ऄऄऄ", "ऄ", maxSize));
+ assertEquals(-2, putAndCompare("ऄऄऄ", "ऄऄऄ", maxSize));
+ assertEquals(-2, putAndCompare("ऄऄऄ", "ऄऄअ", maxSize));
+ assertEquals(-2, putAndCompare("ऄऄअ", "ऄऄऄ", maxSize));
+ }
+
+ /** */
+ public void testCompare4bytes() throws Exception {
+ int maxSize = 3 + 8; // 2 4-bytes chars + 3 bytes header.
+
+ assertEquals(0, putAndCompare("\ud802\udd20\ud802\udd20", "\ud802\udd20\ud802\udd20", maxSize));
+ assertEquals(-1, putAndCompare("\ud802\udd20\ud802\udd20", "\ud802\udd21\ud802\udd21", maxSize));
+ assertEquals(-1, putAndCompare("\ud802\udd20\ud802\udd20\ud802\udd20", "\ud802\udd21\ud802\udd21\ud802\udd21", maxSize));
+ assertEquals(1, putAndCompare("\ud802\udd21\ud802\udd21\ud802\udd21", "\ud802\udd20\ud802\udd20\ud802\udd20", maxSize));
+ assertEquals(1, putAndCompare("\ud802\udd20\ud802\udd20\ud802\udd20", "\ud802\udd20\ud802\udd20", maxSize));
+ assertEquals(1, putAndCompare("\ud802\udd20\ud802\udd20\ud802\udd20", "\ud802\udd20", maxSize));
+ assertEquals(-2, putAndCompare("\ud802\udd20\ud802\udd20\ud802\udd20", "\ud802\udd20\ud802\udd20\ud802\udd20", maxSize));
+ assertEquals(-2, putAndCompare("\ud802\udd20\ud802\udd20\ud802\udd20", "\ud802\udd20\ud802\udd20\ud802\udd21", maxSize));
+ assertEquals(-2, putAndCompare("\ud802\udd20\ud802\udd20\ud802\udd21", "\ud802\udd20\ud802\udd20\ud802\udd20", maxSize));
+ }
+
+ /** */
+ public void testCompareMixed() throws Exception {
+ int maxSize = 3 + 8; // 2 up to 4-bytes chars + 3 bytes header.
+
+ assertEquals(0, putAndCompare("\ud802\udd20\u0904", "\ud802\udd20\u0904", maxSize));
+ assertEquals(-1, putAndCompare("\ud802\udd20\u0904", "\ud802\udd20\u0905", maxSize));
+ assertEquals(1, putAndCompare("\u0905\ud802\udd20", "\u0904\ud802\udd20", maxSize));
+ assertEquals(-2, putAndCompare("\ud802\udd20\ud802\udd20\u0905", "\ud802\udd20\ud802\udd20\u0904", maxSize));
+ }
+
+ /** */
+ public void testCompareMixed2() throws Exception {
+ int strCnt = 1000;
+ int symbCnt = 20;
+ int inlineSize = symbCnt * 4 + 3;
+
+ ThreadLocalRandom rnd = ThreadLocalRandom.current();
+
+ String[] strings = new String[strCnt];
+
+ for (int i = 0; i < strings.length; i++)
+ strings[i] = randomString(symbCnt);
+
+ Arrays.sort(strings);
+
+ for (int i = 0; i < 100; i++) {
+ int i1 = rnd.nextInt(strings.length);
+ int i2 = rnd.nextInt(strings.length);
+
+ assertEquals(Integer.compare(i1,i2), putAndCompare(strings[i1], strings[i2], inlineSize));
+ }
+ }
+
+ /**
+ * @param v1 Value 1.
+ * @param v2 Value 2.
+ * @param maxSize Max inline size.
+ * @return Compare result.
+ * @throws Exception If failed.
+ */
+ private int putAndCompare(String v1, String v2, int maxSize) throws Exception {
+ MemoryPolicyConfiguration plcCfg = new MemoryPolicyConfiguration().setInitialSize(1024 * MB)
+ .setMaxSize(1024 * MB);
+
+ PageMemory pageMem = new PageMemoryNoStoreImpl(log,
+ new UnsafeMemoryProvider(log),
+ null,
+ PAGE_SIZE,
+ plcCfg,
+ new MemoryMetricsImpl(plcCfg),
+ false);
+
+ pageMem.start();
+
+ long pageId = 0L;
+ long page = 0L;
+
+ try {
+ pageId = pageMem.allocatePage(CACHE_ID, 1, PageIdAllocator.FLAG_DATA);
+ page = pageMem.acquirePage(CACHE_ID, pageId);
+ long pageAddr = pageMem.readLock(CACHE_ID, pageId, page);
+
+ int off = 0;
+
+ InlineIndexHelper ih = new InlineIndexHelper(Value.STRING, 1, 0,
+ CompareMode.getInstance(null, 0));
+
+ ih.put(pageAddr, off, ValueString.get(v1), maxSize);
+
+ Comparator<Value> comp = new Comparator<Value>() {
+ @Override public int compare(Value o1, Value o2) {
+ throw new AssertionError("Optimized algorithm should be used.");
+ }
+ };
+
+ return ih.compare(pageAddr, off, maxSize, ValueString.get(v2), comp);
+ }
+ finally {
+ if (page != 0L)
+ pageMem.releasePage(CACHE_ID, pageId, page);
+
+ pageMem.stop();
+ }
+ }
+
/** Limit is too small to cut */
public void testStringCut() {
// 6 bytes total: 3b, 3b.
-
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);
+ InlineIndexHelper ha = new InlineIndexHelper(Value.STRING, 0, SortOrder.ASCENDING,
+ CompareMode.getInstance(null, 0));
// same size
assertFalse(getRes(ha, "aabb", "aabb"));
@@ -110,7 +257,8 @@ public class InlineIndexHelperTest extends TestCase {
/** Test on Bytes values compare */
public void testRelyOnCompareBytes() {
- InlineIndexHelper ha = new InlineIndexHelper(Value.BYTES, 0, SortOrder.ASCENDING);
+ InlineIndexHelper ha = new InlineIndexHelper(Value.BYTES, 0, SortOrder.ASCENDING,
+ CompareMode.getInstance(null, 0));
// same size
assertFalse(getResBytes(ha, new byte[] {1, 2, 3, 4}, new byte[] {1, 2, 3, 4}));
@@ -131,12 +279,11 @@ public class InlineIndexHelperTest extends TestCase {
/** */
public void testStringTruncate() throws Exception {
- MemoryPolicyConfiguration plcCfg = new MemoryPolicyConfiguration().setMaxSize(1024 * MB);
-
- JavaLogger log = new JavaLogger();
+ MemoryPolicyConfiguration plcCfg = new MemoryPolicyConfiguration().setInitialSize(1024 * MB)
+ .setMaxSize(1024 * MB);
- PageMemory pageMem = new PageMemoryNoStoreImpl(log,
- new UnsafeMemoryProvider(log),
+ PageMemory pageMem = new PageMemoryNoStoreImpl(log(),
+ new UnsafeMemoryProvider(log()),
null,
PAGE_SIZE,
plcCfg,
@@ -155,7 +302,9 @@ public class InlineIndexHelperTest extends TestCase {
int off = 0;
- InlineIndexHelper ih = new InlineIndexHelper(Value.STRING, 1, 0);
+ InlineIndexHelper ih = new InlineIndexHelper(Value.STRING, 1, 0,
+ CompareMode.getInstance(null, 0));
+
ih.put(pageAddr, off, ValueString.get("aaaaaaa"), 3 + 5);
assertFalse(ih.isValueFull(pageAddr, off));
@@ -181,12 +330,11 @@ public class InlineIndexHelperTest extends TestCase {
/** */
public void testBytes() throws Exception {
- MemoryPolicyConfiguration plcCfg = new MemoryPolicyConfiguration().setMaxSize(1024 * MB);
+ MemoryPolicyConfiguration plcCfg = new MemoryPolicyConfiguration().setInitialSize(1024 * MB)
+ .setMaxSize(1024 * MB);
- JavaLogger log = new JavaLogger();
-
- PageMemory pageMem = new PageMemoryNoStoreImpl(log,
- new UnsafeMemoryProvider(log),
+ PageMemory pageMem = new PageMemoryNoStoreImpl(log(),
+ new UnsafeMemoryProvider(log()),
null,
PAGE_SIZE,
plcCfg,
@@ -205,7 +353,8 @@ public class InlineIndexHelperTest extends TestCase {
int off = 0;
- InlineIndexHelper ih = new InlineIndexHelper(Value.BYTES, 1, 0);
+ InlineIndexHelper ih = new InlineIndexHelper(Value.BYTES, 1, 0,
+ CompareMode.getInstance(null, 0));
ih.put(pageAddr, off, ValueBytes.get(new byte[] {1, 2, 3, 4, 5}), 3 + 3);
@@ -296,12 +445,11 @@ public class InlineIndexHelperTest extends TestCase {
/** */
private void testPutGet(Value v1, Value v2, Value v3) throws Exception {
- MemoryPolicyConfiguration plcCfg = new MemoryPolicyConfiguration().setMaxSize(1024 * MB);
+ MemoryPolicyConfiguration plcCfg = new MemoryPolicyConfiguration().setInitialSize(1024 * MB)
+ .setMaxSize(1024 * MB);
- JavaLogger log = new JavaLogger();
-
- PageMemory pageMem = new PageMemoryNoStoreImpl(log,
- new UnsafeMemoryProvider(log),
+ PageMemory pageMem = new PageMemoryNoStoreImpl(log(),
+ new UnsafeMemoryProvider(log()),
null,
PAGE_SIZE,
plcCfg,
@@ -321,7 +469,8 @@ public class InlineIndexHelperTest extends TestCase {
int off = 0;
int max = 255;
- InlineIndexHelper ih = new InlineIndexHelper(v1.getType(), 1, 0);
+ InlineIndexHelper ih = new InlineIndexHelper(v1.getType(), 1, 0,
+ CompareMode.getInstance(null, 0));
off += ih.put(pageAddr, off, v1, max - off);
off += ih.put(pageAddr, off, v2, max - off);
@@ -336,6 +485,7 @@ public class InlineIndexHelperTest extends TestCase {
finally {
if (page != 0L)
pageMem.releasePage(CACHE_ID, pageId, page);
+
pageMem.stop();
}
}
@@ -346,6 +496,7 @@ public class InlineIndexHelperTest extends TestCase {
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);
}
@@ -355,7 +506,54 @@ public class InlineIndexHelperTest extends TestCase {
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
+ /**
+ * @param cnt String length.
+ * @return Random string.
+ */
+ private String randomString(int cnt) {
+ final char[] buffer = new char[cnt];
+
+ ThreadLocalRandom rnd = ThreadLocalRandom.current();
+
+ while (cnt-- != 0) {
+ char ch;
+
+ if (rnd.nextInt(100) > 3)
+ ch = (char) (rnd.nextInt(95) + 32); // regular symbols
+ else
+ ch = (char) (rnd.nextInt(65407) + 127); // others symbols
+
+ if(ch >= 56320 && ch <= 57343) {
+ if(cnt == 0)
+ cnt++;
+ else {
+ // low surrogate, insert high surrogate after putting it in
+ buffer[cnt] = ch;
+ cnt--;
+ buffer[cnt] = (char) (55296 + rnd.nextInt(128));
+ }
+ }
+ else if(ch >= 55296 && ch <= 56191) {
+ if(cnt == 0)
+ cnt++;
+ else {
+ // high surrogate, insert low surrogate before putting it in
+ buffer[cnt] = (char) (56320 + rnd.nextInt(128));
+ cnt--;
+ buffer[cnt] = ch;
+ }
+ }
+ else if(ch >= 56192 && ch <= 56319)
+ // private high surrogate, no effing clue, so skip it
+ cnt++;
+ else
+ buffer[cnt] = ch;
+ }
+
+ return new String(buffer);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/71cd1e91/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheWithIndexingTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheWithIndexingTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheWithIndexingTestSuite.java
index 794ec4d..4047700 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheWithIndexingTestSuite.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheWithIndexingTestSuite.java
@@ -37,6 +37,7 @@ import org.apache.ignite.internal.processors.cache.ttl.CacheTtlAtomicLocalSelfTe
import org.apache.ignite.internal.processors.cache.ttl.CacheTtlAtomicPartitionedSelfTest;
import org.apache.ignite.internal.processors.cache.ttl.CacheTtlTransactionalLocalSelfTest;
import org.apache.ignite.internal.processors.cache.ttl.CacheTtlTransactionalPartitionedSelfTest;
+import org.apache.ignite.internal.processors.query.h2.database.InlineIndexHelperTest;
/**
* Cache tests using indexing.
@@ -49,6 +50,8 @@ public class IgniteCacheWithIndexingTestSuite extends TestSuite {
public static TestSuite suite() throws Exception {
TestSuite suite = new TestSuite("Ignite Cache With Indexing Test Suite");
+ suite.addTestSuite(InlineIndexHelperTest.class);
+
suite.addTestSuite(GridIndexingWithNoopSwapSelfTest.class);
suite.addTestSuite(GridCacheOffHeapSelfTest.class);