Repository: ignite Updated Branches: refs/heads/ignite-3477 4db65d292 -> 788d9bb74
ignite-3477 Try compare keys faster. Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/788d9bb7 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/788d9bb7 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/788d9bb7 Branch: refs/heads/ignite-3477 Commit: 788d9bb74e5e5406fb10a7865fc101f0fdeade5b Parents: 4db65d2 Author: sboikov <[email protected]> Authored: Wed Jan 25 14:23:39 2017 +0300 Committer: sboikov <[email protected]> Committed: Wed Jan 25 14:23:39 2017 +0300 ---------------------------------------------------------------------- .../cache/IgniteCacheOffheapManagerImpl.java | 36 ++++++++- .../apache/ignite/internal/util/GridUnsafe.java | 3 + .../database/IgniteDbPutGetAbstractTest.java | 77 ++++++++++++++++++++ 3 files changed, 113 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/788d9bb7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java index 5b788fc..e1ea6d1 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java @@ -60,6 +60,7 @@ import org.apache.ignite.internal.util.GridAtomicLong; import org.apache.ignite.internal.util.GridCloseableIteratorAdapter; import org.apache.ignite.internal.util.GridEmptyCloseableIterator; import org.apache.ignite.internal.util.GridSpinBusyLock; +import org.apache.ignite.internal.util.GridUnsafe; import org.apache.ignite.internal.util.lang.GridCloseableIterator; import org.apache.ignite.internal.util.lang.GridCursor; import org.apache.ignite.internal.util.lang.GridIterator; @@ -1348,7 +1349,7 @@ public class IgniteCacheOffheapManagerImpl extends GridCacheManagerAdapter imple if (data.nextLink() == 0) { long addr = pageAddr + data.offset(); - int len = PageUtils.getInt(addr, 0); + final int len = PageUtils.getInt(addr, 0); int lenCmp = Integer.compare(len, bytes.length); @@ -1357,7 +1358,21 @@ public class IgniteCacheOffheapManagerImpl extends GridCacheManagerAdapter imple addr += 5; // Skip length and type byte. - for (int i = 0; i < len; i++) { + final int words = len / 8; + + for (int i = 0; i < words; i++) { + int off = i * 8; + + long b1 = PageUtils.getLong(addr, off); + long b2 = GridUnsafe.getLong(bytes, GridUnsafe.BYTE_ARR_OFF + off); + + int cmp = Long.compare(b1, b2); + + if (cmp != 0) + return cmp; + } + + for (int i = words * 8; i < len; i++) { byte b1 = PageUtils.getByte(addr, i); byte b2 = bytes[i]; @@ -1385,7 +1400,22 @@ public class IgniteCacheOffheapManagerImpl extends GridCacheManagerAdapter imple if (lenCmp != 0) return lenCmp; - for (int i = 0; i < bytes1.length; i++) { + final int len = bytes1.length; + final int words = len / 8; + + for (int i = 0; i < words; i++) { + int off = GridUnsafe.BYTE_ARR_INT_OFF + i * 8; + + long b1 = GridUnsafe.getLong(bytes1, off); + long b2 = GridUnsafe.getLong(bytes2, off); + + int cmp = Long.compare(b1, b2); + + if (cmp != 0) + return cmp; + } + + for (int i = words * 8; i < len; i++) { byte b1 = bytes1[i]; byte b2 = bytes2[i]; http://git-wip-us.apache.org/repos/asf/ignite/blob/788d9bb7/modules/core/src/main/java/org/apache/ignite/internal/util/GridUnsafe.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/GridUnsafe.java b/modules/core/src/main/java/org/apache/ignite/internal/util/GridUnsafe.java index 1926f01..bbbf22b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/GridUnsafe.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/GridUnsafe.java @@ -67,6 +67,9 @@ public abstract class GridUnsafe { public static final long BYTE_ARR_OFF = UNSAFE.arrayBaseOffset(byte[].class); /** */ + public static final int BYTE_ARR_INT_OFF = UNSAFE.arrayBaseOffset(byte[].class); + + /** */ public static final long SHORT_ARR_OFF = UNSAFE.arrayBaseOffset(short[].class); /** */ http://git-wip-us.apache.org/repos/asf/ignite/blob/788d9bb7/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbPutGetAbstractTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbPutGetAbstractTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbPutGetAbstractTest.java index 34745b4..c7a07e3 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbPutGetAbstractTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/IgniteDbPutGetAbstractTest.java @@ -186,6 +186,9 @@ public abstract class IgniteDbPutGetAbstractTest extends GridCommonAbstractTest return false; }; + /** + * + */ public void testGradualRandomPutAllRemoveAll() { IgniteEx ig = grid(0); @@ -391,6 +394,39 @@ public abstract class IgniteDbPutGetAbstractTest extends GridCommonAbstractTest } /** + * @throws Exception If failed. + */ + public void testPutGetLargeKeys() throws Exception { + IgniteCache<LargeDbKey, Integer> cache = ignite(0).cache(null); + + ThreadLocalRandom rnd = ThreadLocalRandom.current(); + + Map<Integer, LargeDbKey> keys = new HashMap<>(); + + for (int i = 0; i < 100; i++) { + LargeDbKey key = new LargeDbKey(i, 512 + rnd.nextInt(1024)); + + assertNull(cache.get(key)); + + cache.put(key, i); + + keys.put(i, key); + } + + Map<LargeDbKey, Integer> res = cache.getAll(new HashSet<>(keys.values())); + + assertEquals(keys.size(), res.size()); + + for (Map.Entry<Integer, LargeDbKey> e : keys.entrySet()) + assertEquals(e.getKey(), res.get(e.getValue())); + + cache.removeAll(new HashSet<>(keys.values())); + + for (LargeDbKey key : keys.values()) + assertNull(cache.get(key)); + } + + /** * @param size Array size. * @return Array with random items. */ @@ -1350,6 +1386,47 @@ public abstract class IgniteDbPutGetAbstractTest extends GridCommonAbstractTest /** * */ + private static class LargeDbKey implements Serializable { + /** */ + private int val; + + /** */ + private byte[] data; + + /** + * @param val Value. + * @param size Key payload size. + */ + private LargeDbKey(int val, int size) { + this.val = val; + + data = new byte[size]; + + Arrays.fill(data, (byte)val); + } + + /** {@inheritDoc} */ + @Override public boolean equals(Object o) { + if (this == o) + return true; + + if (o == null || !(o instanceof LargeDbKey)) + return false; + + LargeDbKey key = (LargeDbKey)o; + + return val == key.val && Arrays.equals(data, key.data); + } + + /** {@inheritDoc} */ + @Override public int hashCode() { + return val + Arrays.hashCode(data); + } + } + + /** + * + */ private static class DbValue implements Serializable { /** */ @QuerySqlField(index = true)
