GG-11414: Remove snapshotableIndex flag from CacheConfiguration, Get rid of all usages of GridH2TreeIndex
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/b2999f2e Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/b2999f2e Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/b2999f2e Branch: refs/heads/ignite-3477 Commit: b2999f2e4d490fdb140483e4283f0fe2d8004a67 Parents: ef015d3 Author: Sergey Sidorov <ssido...@gridgain.com> Authored: Tue Nov 15 18:50:24 2016 +0300 Committer: Sergey Sidorov <ssido...@gridgain.com> Committed: Wed Nov 16 16:49:52 2016 +0300 ---------------------------------------------------------------------- .../configuration/CacheConfiguration.java | 30 ---- .../cache/IgniteCacheOffheapManagerImpl.java | 6 +- .../cache/database/tree/BPlusTree.java | 30 +++- .../util/GridCursorIteratorWrapper.java | 28 +++ .../apache/ignite/internal/util/IgniteTree.java | 79 ++++---- .../ignite/internal/util/lang/GridCursor.java | 1 + .../offheap/unsafe/GridOffHeapSnapTreeMap.java | 85 ++++++--- .../internal/util/snaptree/SnapTreeMap.java | 92 +++++++--- .../internal/processors/query/h2/H2Cursor.java | 84 +++++++++ .../processors/query/h2/IgniteH2Indexing.java | 36 +--- .../query/h2/database/H2TreeIndex.java | 92 +++------- .../query/h2/opt/GridH2IndexBase.java | 178 ++++++++----------- .../processors/query/h2/opt/GridH2Table.java | 4 +- .../query/h2/opt/GridH2TreeIndex.java | 154 +++++++++++----- .../cache/IgniteCacheAbstractQuerySelfTest.java | 2 +- .../query/h2/opt/GridH2TableSelfTest.java | 29 +-- 16 files changed, 536 insertions(+), 394 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/b2999f2e/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 e15c989..44c23c0 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 @@ -371,9 +371,6 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> { /** */ private transient Class<?>[] indexedTypes; - /** */ - private boolean snapshotableIdx; - /** Copy on read flag. */ private boolean cpOnRead = DFLT_COPY_ON_READ; @@ -466,7 +463,6 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> { rebalancePoolSize = cc.getRebalanceThreadPoolSize(); rebalanceTimeout = cc.getRebalanceTimeout(); rebalanceThrottle = cc.getRebalanceThrottle(); - snapshotableIdx = cc.isSnapshotableIndex(); sqlSchema = cc.getSqlSchema(); sqlEscapeAll = cc.isSqlEscapeAll(); sqlFuncCls = cc.getSqlFunctionClasses(); @@ -1930,32 +1926,6 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> { } /** - * Gets flag indicating whether SQL indexes should support snapshots. - * - * @return {@code True} if SQL indexes should support snapshots. - */ - public boolean isSnapshotableIndex() { - return snapshotableIdx; - } - - /** - * Sets flag indicating whether SQL indexes should support snapshots. - * <p> - * Default value is {@code false}. - * <p> - * <b>Note</b> that this flag is ignored if indexes are stored in offheap memory, - * for offheap indexes snapshots are always enabled. - * - * @param snapshotableIdx {@code True} if SQL indexes should support snapshots. - * @return {@code this} for chaining. - */ - public CacheConfiguration<K, V> setSnapshotableIndex(boolean snapshotableIdx) { - this.snapshotableIdx = snapshotableIdx; - - return this; - } - - /** * Gets array of cache plugin configurations. * * @return Cache plugin configurations. http://git-wip-us.apache.org/repos/asf/ignite/blob/b2999f2e/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 e431f58..66896d2 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 @@ -570,9 +570,11 @@ public class IgniteCacheOffheapManagerImpl extends GridCacheManagerAdapter imple * @throws IgniteCheckedException If failed. */ private long allocateForTree() throws IgniteCheckedException { - long pageId = cctx.shared().database().globalReuseList().takeRecycledPage(); + ReuseList reuseList = cctx.shared().database().globalReuseList(); - if (pageId == 0L) + long pageId; + + if (reuseList == null || (pageId = reuseList.takeRecycledPage()) == 0L) pageId = cctx.shared().database().pageMemory().allocatePage(cctx.cacheId(), INDEX_PARTITION, FLAG_IDX); return pageId; http://git-wip-us.apache.org/repos/asf/ignite/blob/b2999f2e/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/BPlusTree.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/BPlusTree.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/BPlusTree.java index 2aab831..f761975 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/BPlusTree.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/database/tree/BPlusTree.java @@ -55,8 +55,7 @@ import org.apache.ignite.internal.processors.cache.database.tree.io.PageIO; import org.apache.ignite.internal.processors.cache.database.tree.reuse.ReuseBag; import org.apache.ignite.internal.processors.cache.database.tree.reuse.ReuseList; import org.apache.ignite.internal.processors.cache.database.tree.util.PageHandler; -import org.apache.ignite.internal.util.GridArrays; -import org.apache.ignite.internal.util.GridLongList; +import org.apache.ignite.internal.util.*; import org.apache.ignite.internal.util.lang.GridCursor; import org.apache.ignite.internal.util.lang.GridTreePrinter; import org.apache.ignite.internal.util.typedef.F; @@ -83,7 +82,7 @@ import static org.apache.ignite.internal.processors.cache.database.tree.util.Pag * Abstract B+Tree. */ @SuppressWarnings({"RedundantThrowsDeclaration", "ConstantValueVariableUse"}) -public abstract class BPlusTree<L, T extends L> extends DataStructure { +public abstract class BPlusTree<L, T extends L> extends DataStructure implements IgniteTree<L, T> { /** */ private static final Object[] EMPTY = {}; @@ -752,6 +751,16 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure { } } + public GridCursor<T> find(L lower, boolean lowerInclusive, + L upper, boolean upperInclusive) throws IgniteCheckedException { + // TODO inclusive / exclusive logic should be implemented + return find(lower, upper); + } + + public GridCursor<T> findAll() throws IgniteCheckedException { + return find(null, null); + } + /** * @param row Lookup row for exact match. * @return Found row. @@ -1253,6 +1262,10 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure { return doRemove(row, false, null); } + @Override public T removeNode(L key) throws IgniteCheckedException { + return doRemove(key, false, null); + } + /** * @param row Lookup row. * @param ceil If we can remove ceil row when we can not find exact. @@ -1503,9 +1516,14 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure { } /** - * @param row Row. - * @return Old row. - * @throws IgniteCheckedException If failed. + * {@inheritDoc} + */ + public final long treeSize() throws IgniteCheckedException { + return size(); + } + + /** + * {@inheritDoc} */ public final T put(T row) throws IgniteCheckedException { return put(row, null); http://git-wip-us.apache.org/repos/asf/ignite/blob/b2999f2e/modules/core/src/main/java/org/apache/ignite/internal/util/GridCursorIteratorWrapper.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/GridCursorIteratorWrapper.java b/modules/core/src/main/java/org/apache/ignite/internal/util/GridCursorIteratorWrapper.java new file mode 100644 index 0000000..bd30ace --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/GridCursorIteratorWrapper.java @@ -0,0 +1,28 @@ +package org.apache.ignite.internal.util; + +import org.apache.ignite.*; +import org.apache.ignite.internal.util.lang.*; + +import java.util.*; + +/** + * Wrap {@code Iterator} and adapt it to {@code GridCursor}. + */ +public class GridCursorIteratorWrapper<V> implements GridCursor<V> { + private Iterator<V> iter; + private V next; + + public GridCursorIteratorWrapper(Iterator<V> iter) { + this.iter = iter; + } + + @Override public V get() throws IgniteCheckedException { + return next; + } + + @Override public boolean next() throws IgniteCheckedException { + next = iter.hasNext() ? iter.next() : null; + + return next != null; + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/b2999f2e/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteTree.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteTree.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteTree.java index 2c1e1af..512792b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteTree.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteTree.java @@ -17,20 +17,22 @@ package org.apache.ignite.internal.util; +import org.apache.ignite.*; +import org.apache.ignite.internal.util.lang.*; + import java.util.*; /** * Interface for ignite internal tree. */ -public interface IgniteTree<K, V> { +public interface IgniteTree<L, T> { /** - * Associates the specified value with the specified key in this tree. + * Put value in this tree. * - * @param key key with which the specified value is to be associated * @param value value to be associated with the specified key * @return the previous value associated with key */ - V put(K key, V value); + T put(T value) throws IgniteCheckedException; /** * Returns the value to which the specified key is mapped, or {@code null} if this tree contains no mapping for the @@ -40,66 +42,49 @@ public interface IgniteTree<K, V> { * @return the value to which the specified key is mapped, or {@code null} if this tree contains no mapping for the * key */ - V get(Object key); - - /** - * Removes the mapping for a key from this tree if it is present. - * - * @param key key whose mapping is to be removed from the tree - * @return the previous value associated with key, or null if there was no mapping for key. - */ - V remove(Object key); + T findOne(L key) throws IgniteCheckedException; /** - * Returns the number of elements in this tree. + * Returns a cursor from lower to upper bounds. * - * @return the number of elements in this tree + * @param lower Lower bound or {@code null} if unbounded. + * @param lowerInclusive {@code true} if the low bound + * is to be included in the returned view + * @param upper Upper bound or {@code null} if unbounded. + * @param upperInclusive {@code true} if the upper bound + * is to be included in the returned view + * @return Cursor. */ - int size(); + GridCursor<T> find(L lower, boolean lowerInclusive, L upper, boolean upperInclusive) throws IgniteCheckedException; /** - * Returns a {@link Collection} view of the values contained in this tree. + * Returns a cursor from lower to upper bounds inclusive. * - * @return a collection view of the values contained in this map + * @param lower Lower bound or {@code null} if unbounded. + * @param upper Upper bound or {@code null} if unbounded. + * @return Cursor. */ - Collection<V> values(); + GridCursor<T> find(L lower, L upper) throws IgniteCheckedException; /** - * Returns a view of the portion of this tree whose keys are less than (or equal to, if {@code inclusive} is true) - * {@code toKey}. The returned tree is backed by this tree, so changes in the returned tree are reflected in this - * tree, and vice-versa. The returned tree supports all optional tree operations that this tree supports. - * - * @param toKey high endpoint of the keys in the returned tree - * @param inclusive {@code true} if the high endpoint is to be included in the returned view - * @return a view of the portion of this tree whose keys are less than (or equal to, if {@code inclusive} is true) - * {@code toKey} + * Returns a cursor over all values. + * @return Cursor. + * @throws IgniteCheckedException */ - IgniteTree<K, V> headTree(K toKey, boolean inclusive); + GridCursor<T> findAll() throws IgniteCheckedException; /** - * Returns a view of the portion of this tree whose keys are greater than (or equal to, if {@code inclusive} is - * true) {@code fromKey}. The returned tree is backed by this tree, so changes in the returned tree are reflected - * in this tree, and vice-versa. The returned tree supports all optional tree operations that this tree supports. + * Removes the mapping for a key from this tree if it is present. * - * @param fromKey low endpoint of the keys in the returned tree - * @param inclusive {@code true} if the low endpoint is to be included in the returned view - * @return a view of the portion of this tree whose keys are greater than (or equal to, if {@code inclusive} is - * true) {@code fromKey} + * @param key key whose mapping is to be removed from the tree + * @return the previous value associated with key, or null if there was no mapping for key. */ - IgniteTree<K, V> tailTree(K fromKey, boolean inclusive); + T removeNode(L key) throws IgniteCheckedException; /** - * Returns a view of the portion of this tree whose keys range from {@code fromKey} to {@code toKey}. If {@code - * fromKey} and {@code toKey} are equal, the returned tree is empty unless {@code fromInclusive} and {@code - * toInclusive} are both true. The returned tree is backed by this tree, so changes in the returned tree are - * reflected in this tree, and vice-versa. The returned tree supports all optional tree operations that this tree - * supports. + * Returns the number of elements in this tree. * - * @param fromKey low endpoint of the keys in the returned tree - * @param fromInclusive {@code true} if the low endpoint is to be included in the returned view - * @param toKey high endpoint of the keys in the returned tree - * @param toInclusive {@code true} if the high endpoint is to be included in the returned view - * @return a view of the portion of this tree whose keys range from {@code fromKey} to {@code toKey} + * @return the number of elements in this tree */ - IgniteTree<K, V> subTree(final K fromKey, final boolean fromInclusive, final K toKey, final boolean toInclusive); + long treeSize() throws IgniteCheckedException; } http://git-wip-us.apache.org/repos/asf/ignite/blob/b2999f2e/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridCursor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridCursor.java b/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridCursor.java index 37d3a48..da85f99 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridCursor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/lang/GridCursor.java @@ -18,6 +18,7 @@ package org.apache.ignite.internal.util.lang; import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.processors.cache.database.*; /** * Simple cursor abstraction. Initial state must be "before first". http://git-wip-us.apache.org/repos/asf/ignite/blob/b2999f2e/modules/core/src/main/java/org/apache/ignite/internal/util/offheap/unsafe/GridOffHeapSnapTreeMap.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/offheap/unsafe/GridOffHeapSnapTreeMap.java b/modules/core/src/main/java/org/apache/ignite/internal/util/offheap/unsafe/GridOffHeapSnapTreeMap.java index 681394f..eb09af5 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/offheap/unsafe/GridOffHeapSnapTreeMap.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/offheap/unsafe/GridOffHeapSnapTreeMap.java @@ -54,8 +54,11 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock; + +import org.apache.ignite.*; import org.apache.ignite.internal.processors.cache.distributed.dht.GridReservable; import org.apache.ignite.internal.util.*; +import org.apache.ignite.internal.util.lang.*; import org.apache.ignite.internal.util.typedef.internal.SB; import org.jetbrains.annotations.Nullable; import org.jsr166.ConcurrentHashMap8; @@ -3824,30 +3827,48 @@ public class GridOffHeapSnapTreeMap<K extends GridOffHeapSmartPointer, V extends //////////////// IgniteTree - /** {@inheritDoc} */ - @Override public IgniteTree<K, V> headTree(final K toKey, final boolean inclusive) { - return new SubMap(this, null, null, false, toKey, comparable(toKey), inclusive, false); + @Override public V put(V value) throws IgniteCheckedException { + return put((K)value, value); } - /** {@inheritDoc} */ - @Override public IgniteTree<K, V> tailTree(final K fromKey, final boolean inclusive) { - return new SubMap(this, fromKey, comparable(fromKey), inclusive, null, null, false, false); + @Override public V findOne(K key) throws IgniteCheckedException { + return get(key); } - /** {@inheritDoc} */ - @Override public IgniteTree<K, V> subTree(final K fromKey, final boolean fromInclusive, final K toKey, - final boolean toInclusive) { - final Comparable<? super K> fromCmp = comparable(fromKey); - if (fromCmp.compareTo(toKey) > 0) { + @Override public GridCursor<V> findAll() throws IgniteCheckedException { + return find(null, null); + } + + @Override public GridCursor<V> find(K lower, K upper) throws IgniteCheckedException { + return find(lower, true, upper, true); + } + + @Override public GridCursor<V> find(K lower, boolean lowerInclusive, K upper, boolean upperInclusive) + throws IgniteCheckedException { + + final Comparable<? super K> fromCmp = comparable(lower); + + if (fromCmp.compareTo(upper) > 0) { throw new IllegalArgumentException(); } - return new SubMap(this, fromKey, fromCmp, fromInclusive, toKey, comparable(toKey), toInclusive, false); + + SubMap subMap = new SubMap(this, lower, fromCmp, lowerInclusive, upper, comparable(upper), upperInclusive, false); + + return new GridCursorIteratorWrapper<>(subMap.values().iterator()); + } + + @Override public V removeNode(K key) throws IgniteCheckedException { + return remove(key); + } + + @Override public long treeSize() throws IgniteCheckedException { + return size(); } /** * Submap. */ - private class SubMap extends AbstractMap<K,V> implements ConcurrentNavigableMap<K,V>, IgniteTree<K, V> { + private class SubMap extends AbstractMap<K, V> implements ConcurrentNavigableMap<K, V>, IgniteTree<K, V> { /** */ private final GridOffHeapSnapTreeMap<K,V> m; @@ -4456,22 +4477,36 @@ public class GridOffHeapSnapTreeMap<K extends GridOffHeapSmartPointer, V extends /////////// IgniteTree - /** {@inheritDoc} */ - @Override public IgniteTree<K, V> headTree(K toKey, boolean inclusive) { - return headMap(toKey, inclusive); + @Override public V put(V value) throws IgniteCheckedException { + return put((K)value, value); } - /** {@inheritDoc} */ - @Override public IgniteTree<K, V> tailTree(K fromKey, boolean inclusive) { - return tailMap(fromKey, inclusive); + @Override public V findOne(K key) throws IgniteCheckedException { + return get(key); } - /** {@inheritDoc} */ - @Override public IgniteTree<K, V> subTree(final K fromKey, - final boolean fromInclusive, - final K toKey, - final boolean toInclusive) { - return subMap(fromKey, fromInclusive, toKey, toInclusive); + @Override public GridCursor<V> findAll() throws IgniteCheckedException { + return find(null, null); + } + + @Override public GridCursor<V> find(K lower, K upper) throws IgniteCheckedException { + return find(lower, true, upper, true); + } + + @Override public GridCursor<V> find(K lower, boolean lowerInclusive, K upper, boolean upperInclusive) + throws IgniteCheckedException { + + SubMap subMap = subMap(lower, lowerInclusive, upper, upperInclusive); + + return new GridCursorIteratorWrapper(subMap.values().iterator()); + } + + @Override public V removeNode(K key) throws IgniteCheckedException { + return remove(key); + } + + @Override public long treeSize() throws IgniteCheckedException { + return size(); } } http://git-wip-us.apache.org/repos/asf/ignite/blob/b2999f2e/modules/core/src/main/java/org/apache/ignite/internal/util/snaptree/SnapTreeMap.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/snaptree/SnapTreeMap.java b/modules/core/src/main/java/org/apache/ignite/internal/util/snaptree/SnapTreeMap.java index 064e7b0..8bd5f59 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/util/snaptree/SnapTreeMap.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/util/snaptree/SnapTreeMap.java @@ -35,7 +35,9 @@ package org.apache.ignite.internal.util.snaptree; +import org.apache.ignite.*; import org.apache.ignite.internal.util.*; +import org.apache.ignite.internal.util.lang.*; import java.io.IOException; import java.io.ObjectInputStream; @@ -2347,24 +2349,43 @@ public class SnapTreeMap<K, V> extends AbstractMap<K, V> implements ConcurrentNa //////////////// IgniteTree - /** {@inheritDoc} */ - @Override public IgniteTree<K, V> headTree(final K toKey, final boolean inclusive) { - return new SubMap<K,V>(this, null, null, false, toKey, comparable(toKey), inclusive, false); + @Override public GridCursor<V> find(K lower, boolean lowerInclusive, + K upper, boolean upperInclusive) throws IgniteCheckedException { + if (lower == null) + if (upper == null) // all + return new GridCursorIteratorWrapper<>(values().iterator()); + else // head + return new GridCursorIteratorWrapper<>(headMap(upper, upperInclusive).values().iterator()); + else + if (upper == null) // tail + return new GridCursorIteratorWrapper<>(tailMap(lower, lowerInclusive).values().iterator()); + else // interval + return new GridCursorIteratorWrapper<>(subMap(lower, lowerInclusive, upper, upperInclusive) + .values().iterator()); } - /** {@inheritDoc} */ - @Override public IgniteTree<K, V> tailTree(final K fromKey, final boolean inclusive) { - return new SubMap<K,V>(this, fromKey, comparable(fromKey), inclusive, null, null, false, false); + public GridCursor<V> find(K lower, K upper) throws IgniteCheckedException { + return find(lower, true, upper, true); } - /** {@inheritDoc} */ - @Override public IgniteTree<K, V> subTree(final K fromKey, final boolean fromInclusive, final K toKey, - final boolean toInclusive) { - final Comparable<? super K> fromCmp = comparable(fromKey); - if (fromCmp.compareTo(toKey) > 0) { - throw new IllegalArgumentException(); - } - return new SubMap<K,V>(this, fromKey, fromCmp, fromInclusive, toKey, comparable(toKey), toInclusive, false); + public GridCursor<V> findAll() throws IgniteCheckedException { + return find(null, null); + } + + @Override public V findOne(K key) throws IgniteCheckedException { + return get(key); + } + + @Override public long treeSize() throws IgniteCheckedException { + return size(); + } + + @Override public V put(V value) throws IgniteCheckedException { + return put((K)value, value); + } + + @Override public V removeNode(K key) throws IgniteCheckedException { + return remove(key); } private static class SubMap<K, V> extends AbstractMap<K, V> implements ConcurrentNavigableMap<K, V>, Serializable, @@ -2893,20 +2914,43 @@ public class SnapTreeMap<K, V> extends AbstractMap<K, V> implements ConcurrentNa /////// IgniteTree - /** {@inheritDoc} */ - @Override public IgniteTree<K, V> headTree(final K toKey, final boolean inclusive) { - return headMap(toKey, inclusive); + @Override public V findOne(K key) throws IgniteCheckedException { + return get(key); + } + + @Override public GridCursor<V> find(K lower, boolean lowerInclusive, + K upper, boolean upperInclusive) throws IgniteCheckedException { + + if (lower == null) + if (upper == null) // all + return new GridCursorIteratorWrapper<>(values().iterator()); + else // head + return new GridCursorIteratorWrapper<>(headMap(upper, upperInclusive).values().iterator()); + else + if (upper == null) // tail + return new GridCursorIteratorWrapper<>(tailMap(lower, lowerInclusive).values().iterator()); + else // interval + return new GridCursorIteratorWrapper<>(subMap(lower, lowerInclusive, upper, upperInclusive).values().iterator()); + } + + public GridCursor<V> find(K lower, K upper) throws IgniteCheckedException { + return find(lower, true, upper, true); + } + + public GridCursor<V> findAll() throws IgniteCheckedException { + return find(null, null); + } + + @Override public long treeSize() throws IgniteCheckedException { + return size(); } - /** {@inheritDoc} */ - @Override public IgniteTree<K, V> tailTree(final K fromKey, final boolean inclusive) { - return tailMap(fromKey, inclusive); + @Override public V put(V value) throws IgniteCheckedException { + return put((K)value, value); } - /** {@inheritDoc} */ - @Override public IgniteTree<K, V> subTree(final K fromKey, final boolean fromInclusive, final K toKey, - final boolean toInclusive) { - return subMap(fromKey, fromInclusive, toKey, toInclusive); + @Override public V removeNode(K key) throws IgniteCheckedException { + return remove(key); } } http://git-wip-us.apache.org/repos/asf/ignite/blob/b2999f2e/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Cursor.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Cursor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Cursor.java new file mode 100644 index 0000000..d3b6265 --- /dev/null +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2Cursor.java @@ -0,0 +1,84 @@ +package org.apache.ignite.internal.processors.query.h2; + +import org.apache.ignite.*; +import org.apache.ignite.internal.processors.query.h2.opt.*; +import org.apache.ignite.internal.util.lang.*; +import org.apache.ignite.internal.util.typedef.internal.*; +import org.apache.ignite.lang.*; +import org.h2.index.*; +import org.h2.message.*; +import org.h2.result.*; + +/** + * Cursor. + */ +public class H2Cursor implements Cursor { + /** */ + final GridCursor<GridH2Row> cursor; + + /** */ + final IgniteBiPredicate<Object,Object> filter; + + /** */ + final long time = U.currentTimeMillis(); + + /** + * @param cursor Cursor. + * @param filter Filter. + */ + public H2Cursor(GridCursor<GridH2Row> cursor, IgniteBiPredicate<Object, Object> filter) { + assert cursor != null; + + this.cursor = cursor; + this.filter = filter; + } + + /** {@inheritDoc} */ + @Override public Row get() { + try { + return cursor.get(); + } + catch (IgniteCheckedException e) { + throw DbException.convert(e); + } + } + + /** {@inheritDoc} */ + @Override public SearchRow getSearchRow() { + return get(); + } + + /** {@inheritDoc} */ + @Override public boolean next() { + try { + while (cursor.next()) { + GridH2Row row = cursor.get(); + + if (row.expireTime() > 0 && row.expireTime() <= time) + continue; + + if (filter == null) + return true; + + Object key = row.getValue(0).getObject(); + Object val = row.getValue(1).getObject(); + + assert key != null; + assert val != null; + + if (filter.apply(key, val)) + return true; + } + + return false; + } + catch (IgniteCheckedException e) { + throw DbException.convert(e); + } + } + + /** {@inheritDoc} */ + @Override public boolean previous() { + throw DbException.getUnsupportedException("previous"); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/b2999f2e/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java index 55d1b57..47ca598 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java @@ -98,7 +98,6 @@ import org.apache.ignite.internal.processors.query.h2.opt.GridH2Row; import org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor; import org.apache.ignite.internal.processors.query.h2.opt.GridH2RowFactory; import org.apache.ignite.internal.processors.query.h2.opt.GridH2Table; -import org.apache.ignite.internal.processors.query.h2.opt.GridH2TreeIndex; import org.apache.ignite.internal.processors.query.h2.opt.GridH2ValueCacheObject; import org.apache.ignite.internal.processors.query.h2.opt.GridLuceneIndex; import org.apache.ignite.internal.processors.query.h2.sql.GridSqlQuerySplitter; @@ -2431,7 +2430,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { // Add explicit affinity key index if nothing alike was found. if (affCol != null && !affIdxFound) { - idxs.add(new GridH2TreeIndex("AFFINITY_KEY", tbl, false, + idxs.add(createSortedIndex(cacheId, "AFFINITY_KEY", tbl, false, treeIndexColumns(new ArrayList<IndexColumn>(2), affCol, keyCol))); } @@ -2454,14 +2453,14 @@ public class IgniteH2Indexing implements GridQueryIndexing { List<IndexColumn> cols ) { try { - GridCacheSharedContext<Object,Object> scctx = ctx.cache().context(); + GridCacheSharedContext<Object, Object> scctx = ctx.cache().context(); GridCacheContext cctx = scctx.cacheContext(cacheId); - if (cctx.affinityNode() && cctx.offheapIndex()) - return createIndex(cctx, name, tbl, pk, cols); + if (log.isInfoEnabled()) + log.info("Creating cache index [cacheId=" + cctx.cacheId() + ", idxName=" + name + ']'); - return new GridH2TreeIndex(name, tbl, pk, cols); + return new H2TreeIndex(cctx, tbl, name, pk, cols); } catch (IgniteCheckedException e) { throw new IgniteException(e); @@ -2469,31 +2468,6 @@ public class IgniteH2Indexing implements GridQueryIndexing { } /** - * @param name Index name. - * @param tbl Table. - * @param pk Primary key flag. - * @param cols Columns. - * @return Index. - */ - private Index createIndex( - GridCacheContext cctx, - String name, - GridH2Table tbl, - boolean pk, - List<IndexColumn> cols - ) throws IgniteCheckedException { - if (log.isInfoEnabled()) - log.info("Creating cache index [cacheId=" + cctx.cacheId() + ", idxName=" + name + ']'); - - return new H2TreeIndex( - cctx, - tbl, - name, - pk, - cols); - } - - /** * */ void onDrop() { http://git-wip-us.apache.org/repos/asf/ignite/blob/b2999f2e/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 8bd8ebe..b56b1ed 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,18 +26,16 @@ import org.apache.ignite.internal.processors.cache.database.IgniteCacheDatabaseS 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.query.h2.opt.GridH2IndexBase; -import org.apache.ignite.internal.processors.query.h2.opt.GridH2Row; -import org.apache.ignite.internal.processors.query.h2.opt.GridH2Table; -import org.apache.ignite.internal.util.lang.GridCursor; -import org.apache.ignite.internal.util.typedef.internal.U; +import org.apache.ignite.internal.processors.query.h2.*; +import org.apache.ignite.internal.processors.query.h2.opt.*; +import org.apache.ignite.internal.util.*; +import org.apache.ignite.internal.util.lang.*; import org.apache.ignite.lang.IgniteBiPredicate; import org.apache.ignite.spi.indexing.IndexingQueryFilter; import org.h2.engine.Session; import org.h2.index.Cursor; import org.h2.index.IndexType; import org.h2.message.DbException; -import org.h2.result.Row; import org.h2.result.SearchRow; import org.h2.result.SortOrder; import org.h2.table.IndexColumn; @@ -215,77 +213,27 @@ public class H2TreeIndex extends GridH2IndexBase { return this; } - /** - * Cursor. - */ - private static class H2Cursor implements Cursor { - /** */ - final GridCursor<GridH2Row> cursor; - - /** */ - final IgniteBiPredicate<Object,Object> filter; - - /** */ - final long time = U.currentTimeMillis(); - - /** - * @param cursor Cursor. - * @param filter Filter. - */ - private H2Cursor(GridCursor<GridH2Row> cursor, IgniteBiPredicate<Object,Object> filter) { - assert cursor != null; - - this.cursor = cursor; - this.filter = filter; - } - - /** {@inheritDoc} */ - @Override public Row get() { - try { - return cursor.get(); - } - catch (IgniteCheckedException e) { - throw DbException.convert(e); - } - } - - /** {@inheritDoc} */ - @Override public SearchRow getSearchRow() { - return get(); - } - - /** {@inheritDoc} */ - @Override public boolean next() { - try { - while (cursor.next()) { - GridH2Row row = cursor.get(); - - if (row.expireTime() > 0 && row.expireTime() <= time) - continue; - - if (filter == null) - return true; + protected IgniteTree<SearchRow, GridH2Row> treeForRead() { + return tree; + } - Object key = row.getValue(0).getObject(); - Object val = row.getValue(1).getObject(); + protected GridCursor<GridH2Row> doFind0(IgniteTree t, + @Nullable SearchRow first, + boolean includeFirst, + @Nullable SearchRow last, + IndexingQueryFilter filter) { + includeFirst &= first != null; - assert key != null; - assert val != null; + try { + GridCursor<GridH2Row> range = tree.find(first, last); - if (filter.apply(key, val)) - return true; - } + if (range == null) + return EMPTY_CURSOR; - return false; - } - catch (IgniteCheckedException e) { - throw DbException.convert(e); - } + return filter(range, filter); } - - /** {@inheritDoc} */ - @Override public boolean previous() { - throw DbException.getUnsupportedException("previous"); + catch (IgniteCheckedException e) { + throw DbException.convert(e); } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/b2999f2e/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2IndexBase.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2IndexBase.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2IndexBase.java index 032b548..84d3b6a 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2IndexBase.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2IndexBase.java @@ -44,7 +44,7 @@ import org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2RowRange import org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2ValueMessage; import org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2ValueMessageFactory; import org.apache.ignite.internal.util.*; -import org.apache.ignite.internal.util.lang.GridFilteredIterator; +import org.apache.ignite.internal.util.lang.*; import org.apache.ignite.internal.util.typedef.CIX2; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.util.typedef.internal.CU; @@ -306,12 +306,12 @@ public abstract class GridH2IndexBase extends BaseIndex { /** * Filters rows from expired ones and using predicate. * - * @param iter Iterator over rows. + * @param cursor GridCursor over rows. * @param filter Optional filter. * @return Filtered iterator. */ - protected Iterator<GridH2Row> filter(Iterator<GridH2Row> iter, IndexingQueryFilter filter) { - return new FilteringIterator(iter, U.currentTimeMillis(), filter, getTable().spaceName()); + protected GridCursor<GridH2Row> filter(GridCursor<GridH2Row> cursor, IndexingQueryFilter filter) { + return new FilteringCursor(cursor, U.currentTimeMillis(), filter, getTable().spaceName()); } /** @@ -460,13 +460,7 @@ public abstract class GridH2IndexBase extends BaseIndex { assert !msg.bounds().isEmpty() : "empty bounds"; - IgniteTree snapshotTree; - - if (snapshot0 instanceof IgniteTree) - snapshotTree = (IgniteTree)snapshot0; - else - snapshotTree = new IgniteNavigableMapTree( - (NavigableMap<GridSearchRowPointer, GridH2Row>) snapshot0); + IgniteTree snapshotTree = (IgniteTree)snapshot0; src = new RangeSource(msg.bounds(), snapshotTree, qctx.filter()); } @@ -1367,7 +1361,7 @@ public abstract class GridH2IndexBase extends BaseIndex { int curRangeId = -1; /** */ - Iterator<GridH2Row> curRange = emptyIterator(); + GridCursor<GridH2Row> curRange = EMPTY_CURSOR; /** */ final IgniteTree tree; @@ -1393,8 +1387,8 @@ public abstract class GridH2IndexBase extends BaseIndex { /** * @return {@code true} If there are more rows in this source. */ - public boolean hasMoreRows() { - return boundsIter.hasNext() || curRange.hasNext(); + public boolean hasMoreRows() throws IgniteCheckedException { + return boundsIter.hasNext() || curRange.next(); } /** @@ -1404,56 +1398,60 @@ public abstract class GridH2IndexBase extends BaseIndex { public GridH2RowRange next(int maxRows) { assert maxRows > 0 : maxRows; - for (;;) { - if (curRange.hasNext()) { - // Here we are getting last rows from previously partially fetched range. - List<GridH2RowMessage> rows = new ArrayList<>(); + try { + for (;;) { + if (curRange.next()) { + // Here we are getting last rows from previously partially fetched range. + List<GridH2RowMessage> rows = new ArrayList<>(); - GridH2RowRange nextRange = new GridH2RowRange(); + GridH2RowRange nextRange = new GridH2RowRange(); - nextRange.rangeId(curRangeId); - nextRange.rows(rows); + nextRange.rangeId(curRangeId); + nextRange.rows(rows); - do { - rows.add(toRowMessage(curRange.next())); - } - while (rows.size() < maxRows && curRange.hasNext()); + do { + rows.add(toRowMessage(curRange.get())); + } + while (rows.size() < maxRows && curRange.next()); - if (curRange.hasNext()) - nextRange.setPartial(); - else - curRange = emptyIterator(); + if (curRange.next()) + nextRange.setPartial(); + else + curRange = EMPTY_CURSOR; - return nextRange; - } + return nextRange; + } - curRange = emptyIterator(); + curRange = EMPTY_CURSOR; - if (!boundsIter.hasNext()) { - boundsIter = emptyIterator(); + if (!boundsIter.hasNext()) { + boundsIter = emptyIterator(); - return null; - } + return null; + } - GridH2RowRangeBounds bounds = boundsIter.next(); + GridH2RowRangeBounds bounds = boundsIter.next(); - curRangeId = bounds.rangeId(); + curRangeId = bounds.rangeId(); - SearchRow first = toSearchRow(bounds.first()); - SearchRow last = toSearchRow(bounds.last()); + SearchRow first = toSearchRow(bounds.first()); + SearchRow last = toSearchRow(bounds.last()); - IgniteTree t = tree != null ? tree : treeForRead(); + IgniteTree t = tree != null ? tree : treeForRead(); - curRange = doFind0(t, first, true, last, filter); + curRange = doFind0(t, first, true, last, filter); - if (!curRange.hasNext()) { - // We have to return empty range here. - GridH2RowRange emptyRange = new GridH2RowRange(); + if (!curRange.next()) { + // We have to return empty range here. + GridH2RowRange emptyRange = new GridH2RowRange(); - emptyRange.rangeId(curRangeId); + emptyRange.rangeId(curRangeId); - return emptyRange; + return emptyRange; + } } + } catch (IgniteCheckedException e) { + throw DbException.convert(e); } } } @@ -1461,7 +1459,7 @@ public abstract class GridH2IndexBase extends BaseIndex { /** * @return Snapshot for current thread if there is one. */ - protected IgniteTree treeForRead() { + protected <K, V> IgniteTree<K, V> treeForRead() { throw new UnsupportedOperationException(); } @@ -1473,7 +1471,7 @@ public abstract class GridH2IndexBase extends BaseIndex { * @param filter Filter. * @return Iterator over rows in given range. */ - protected Iterator<GridH2Row> doFind0(IgniteTree t, + protected GridCursor<GridH2Row> doFind0(IgniteTree t, @Nullable SearchRow first, boolean includeFirst, @Nullable SearchRow last, @@ -1482,9 +1480,11 @@ public abstract class GridH2IndexBase extends BaseIndex { } /** - * Iterator which filters by expiration time and predicate. + * Cursor which filters by expiration time and predicate. */ - protected static class FilteringIterator extends GridFilteredIterator<GridH2Row> { + protected static class FilteringCursor implements GridCursor<GridH2Row> { + /** */ + private final GridCursor<GridH2Row> cursor; /** */ private final IgniteBiPredicate<Object, Object> fltr; @@ -1494,17 +1494,19 @@ public abstract class GridH2IndexBase extends BaseIndex { /** Is value required for filtering predicate? */ private final boolean isValRequired; + private GridH2Row next; + /** - * @param iter Iterator. + * @param cursor GridCursor. * @param time Time for expired rows filtering. * @param qryFilter Filter. * @param spaceName Space name. */ - protected FilteringIterator(Iterator<GridH2Row> iter, + protected FilteringCursor(GridCursor<GridH2Row> cursor, long time, IndexingQueryFilter qryFilter, String spaceName) { - super(iter); + this.cursor = cursor; this.time = time; @@ -1524,7 +1526,7 @@ public abstract class GridH2IndexBase extends BaseIndex { * @return If this row was accepted. */ @SuppressWarnings("unchecked") - @Override protected boolean accept(GridH2Row row) { + protected boolean accept(GridH2Row row) { if (row.expireTime() <= time) return false; @@ -1539,62 +1541,40 @@ public abstract class GridH2IndexBase extends BaseIndex { return fltr.apply(key, val); } - } - - /** - * Adapter from {@link NavigableMap} to {@link IgniteTree}. - */ - protected static class IgniteNavigableMapTree implements IgniteTree<GridSearchRowPointer, GridH2Row> { - private NavigableMap<GridSearchRowPointer, GridH2Row> tree; - - /** - * @param map the {@link NavigableMap} which should be adapted. - */ - public IgniteNavigableMapTree(final NavigableMap<GridSearchRowPointer, GridH2Row> map) { - this.tree = map; - } - /** {@inheritDoc} */ - @Override public GridH2Row put(final GridSearchRowPointer key, final GridH2Row value) { - return tree.put(key, value); - } + @Override public boolean next() throws IgniteCheckedException { + next = null; - /** {@inheritDoc} */ - @Override public GridH2Row get(final Object key) { - return tree.get(key); - } + while (cursor.next()) { + GridH2Row t = cursor.get(); - /** {@inheritDoc} */ - @Override public GridH2Row remove(final Object key) { - return tree.remove(key); - } + if (accept(t)) { + next = t; + return true; + } + } - /** {@inheritDoc} */ - @Override public int size() { - return tree.size(); + return false; } - /** {@inheritDoc} */ - @Override public Collection<GridH2Row> values() { - return tree.values(); - } + @Override public GridH2Row get() throws IgniteCheckedException { + if (next == null) + throw new NoSuchElementException(); - /** {@inheritDoc} */ - @Override - public IgniteTree<GridSearchRowPointer, GridH2Row> headTree(GridSearchRowPointer toKey, boolean inclusive) { - return new IgniteNavigableMapTree(tree.headMap(toKey, inclusive)); + return next; } + } + /** Empty cursor. */ + protected static final GridCursor<GridH2Row> EMPTY_CURSOR = new GridCursor<GridH2Row>() { /** {@inheritDoc} */ - @Override - public IgniteTree<GridSearchRowPointer, GridH2Row> tailTree(GridSearchRowPointer fromKey, boolean inclusive) { - return new IgniteNavigableMapTree(tree.tailMap(fromKey, inclusive)); + @Override public boolean next() { + return false; } /** {@inheritDoc} */ - @Override public IgniteTree<GridSearchRowPointer, GridH2Row> subTree(GridSearchRowPointer fromKey, - boolean fromInclusive, GridSearchRowPointer toKey, boolean toInclusive) { - return new IgniteNavigableMapTree(tree.subMap(fromKey, fromInclusive, toKey, toInclusive)); + @Override public GridH2Row get() { + return null; } - } + }; } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/b2999f2e/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 ef3dd35..bf390ba 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 @@ -34,7 +34,7 @@ import org.apache.ignite.internal.processors.cache.CacheObject; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.KeyCacheObject; import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; -import org.apache.ignite.internal.processors.query.h2.database.H2RowFactory; +import org.apache.ignite.internal.processors.query.h2.database.*; import org.apache.ignite.internal.util.offheap.unsafe.GridUnsafeMemory; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.lang.IgniteBiTuple; @@ -893,7 +893,7 @@ public class GridH2Table extends TableBase { /** * Create list of indexes. First must be primary key, after that all unique indexes and * only then non-unique indexes. - * All indexes must be subtypes of {@link GridH2TreeIndex}. + * All indexes must be subtypes of {@link H2TreeIndex}. * * @param tbl Table to create indexes for. * @return List of indexes. http://git-wip-us.apache.org/repos/asf/ignite/blob/b2999f2e/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2TreeIndex.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2TreeIndex.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2TreeIndex.java index b4cd76f..e03c1a1 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2TreeIndex.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2TreeIndex.java @@ -18,13 +18,14 @@ package org.apache.ignite.internal.processors.query.h2.opt; import java.util.Comparator; -import java.util.Iterator; import java.util.List; import java.util.NavigableMap; -import java.util.concurrent.ConcurrentNavigableMap; import java.util.concurrent.ConcurrentSkipListMap; +import org.apache.ignite.*; +import org.apache.ignite.internal.processors.query.h2.*; import org.apache.ignite.internal.util.*; +import org.apache.ignite.internal.util.lang.*; import org.apache.ignite.internal.util.offheap.unsafe.GridOffHeapSnapTreeMap; import org.apache.ignite.internal.util.offheap.unsafe.GridUnsafeGuard; import org.apache.ignite.internal.util.snaptree.SnapTreeMap; @@ -93,7 +94,7 @@ public class GridH2TreeIndex extends GridH2IndexBase implements Comparator<GridS } else { tree = new IgniteNavigableMapTree( - new ConcurrentSkipListMap<>( + new ConcurrentSkipListMap<GridSearchRowPointer, GridH2Row>( new Comparator<GridSearchRowPointer>() { @Override public int compare(GridSearchRowPointer o1, GridSearchRowPointer o2) { if (o1 instanceof ComparableRow) @@ -178,16 +179,22 @@ public class GridH2TreeIndex extends GridH2IndexBase implements Comparator<GridS // Fast path if we don't need to perform any filtering. if (f == null || f.forSpace((getTable()).spaceName()) == null) - return treeForRead().size(); + try { + return treeForRead().treeSize(); + } catch (IgniteCheckedException e) { + throw DbException.convert(e); + } - Iterator<GridH2Row> iter = doFind(null, false, null); + GridCursor<GridH2Row> cursor = doFind(null, false, null); long size = 0; - while (iter.hasNext()) { - iter.next(); - - size++; + try { + while (cursor.next()) + size++; + } + catch (IgniteCheckedException e) { + throw DbException.convert(e); } return size; @@ -240,12 +247,12 @@ public class GridH2TreeIndex extends GridH2IndexBase implements Comparator<GridS /** {@inheritDoc} */ @Override public Cursor find(Session ses, @Nullable SearchRow first, @Nullable SearchRow last) { - return new GridH2Cursor(doFind(first, true, last)); + return new H2Cursor(doFind(first, true, last), null); } /** {@inheritDoc} */ @Override public Cursor findNext(Session ses, SearchRow higherThan, SearchRow last) { - return new GridH2Cursor(doFind(higherThan, false, last)); + return new H2Cursor(doFind(higherThan, false, last), null); } /** @@ -257,7 +264,11 @@ public class GridH2TreeIndex extends GridH2IndexBase implements Comparator<GridS * @return Row. */ public GridH2Row findOne(GridH2Row row) { - return tree.get(row); + try { + return tree.findOne(row); + } catch (IgniteCheckedException e) { + throw DbException.convert(e); + } } /** @@ -269,14 +280,14 @@ public class GridH2TreeIndex extends GridH2IndexBase implements Comparator<GridS * @return Iterator over rows in given range. */ @SuppressWarnings("unchecked") - private Iterator<GridH2Row> doFind(@Nullable SearchRow first, boolean includeFirst, @Nullable SearchRow last) { + private GridCursor<GridH2Row> doFind(@Nullable SearchRow first, boolean includeFirst, @Nullable SearchRow last) { IgniteTree t = treeForRead(); return doFind0(t, first, includeFirst, last, threadLocalFilter()); } /** {@inheritDoc} */ - @Override protected final Iterator<GridH2Row> doFind0( + @Override protected final GridCursor<GridH2Row> doFind0( IgniteTree t, @Nullable SearchRow first, boolean includeFirst, @@ -285,13 +296,13 @@ public class GridH2TreeIndex extends GridH2IndexBase implements Comparator<GridS ) { includeFirst &= first != null; - IgniteTree<GridSearchRowPointer, GridH2Row> range = subTree(t, comparable(first, includeFirst ? -1 : 1), + GridCursor<GridH2Row> range = subTree(t, comparable(first, includeFirst ? -1 : 1), comparable(last, 1)); if (range == null) - return new GridEmptyIterator<>(); + return EMPTY_CURSOR; - return filter(range.values().iterator(), filter); + return filter(range, filter); } /** @@ -318,25 +329,19 @@ public class GridH2TreeIndex extends GridH2IndexBase implements Comparator<GridS * @return Sub-map. */ @SuppressWarnings({"IfMayBeConditional", "TypeMayBeWeakened"}) - private IgniteTree subTree(IgniteTree tree, + private GridCursor<GridH2Row> subTree(IgniteTree tree, @Nullable GridSearchRowPointer first, @Nullable GridSearchRowPointer last) { - // We take exclusive bounds because it is possible that one search row will be equal to multiple key rows - // in tree and we must return them all. - if (first == null) { - if (last == null) - return tree; - else - return tree.headTree(last, false); - } - else { - if (last == null) - return tree.tailTree(first, false); - else { - if (compare(first, last) > 0) - return null; - return tree.subTree(first, false, last, false); - } + if (first != null && last != null && compare(first, last) > 0) + return null; + + try { + // We take exclusive bounds because it is possible that one search row will be equal to multiple key rows + // in tree and we must return them all. + return tree.find(first, false, last, false); + } + catch (IgniteCheckedException e) { + throw DbException.convert(e); } } @@ -345,7 +350,7 @@ public class GridH2TreeIndex extends GridH2IndexBase implements Comparator<GridS * * @return Rows iterator. */ - Iterator<GridH2Row> rows() { + GridCursor<GridH2Row> rows() { return doFind(null, false, null); } @@ -361,12 +366,22 @@ public class GridH2TreeIndex extends GridH2IndexBase implements Comparator<GridS /** {@inheritDoc} */ @Override public GridH2Row put(GridH2Row row) { - return tree.put(row, row); + try { + return tree.put(row); + } + catch (IgniteCheckedException e) { + throw DbException.convert(e); + } } /** {@inheritDoc} */ @Override public GridH2Row remove(SearchRow row) { - return tree.remove(comparable(row, 0)); + try { + return tree.removeNode(comparable(row, 0)); + } + catch (IgniteCheckedException e) { + throw DbException.convert(e); + } } /** @@ -471,14 +486,69 @@ public class GridH2TreeIndex extends GridH2IndexBase implements Comparator<GridS long i = 0; - for (GridH2Row row : tree.values()) { - // Check for interruptions every 1000 iterations. - if (++i % 1000 == 0 && thread.isInterrupted()) - throw new InterruptedException(); + try { + GridCursor<GridH2Row> cursor = tree.findAll(); - idx.tree.put(row, row); + while(cursor.next()) { + GridH2Row row = cursor.get(); + + // Check for interruptions every 1000 iterations. + if (++i % 1000 == 0 && thread.isInterrupted()) + throw new InterruptedException(); + + idx.tree.put(row); + } + } + catch (IgniteCheckedException e) { + throw DbException.convert(e); } return idx; } + + /** + * Adapter from {@link NavigableMap} to {@link IgniteTree}. + */ + private final class IgniteNavigableMapTree implements IgniteTree<GridSearchRowPointer, GridH2Row> { + private NavigableMap<GridSearchRowPointer, GridH2Row> tree; + + public IgniteNavigableMapTree(NavigableMap<GridSearchRowPointer, GridH2Row> tree) { + this.tree = tree; + } + + @Override public GridH2Row put(GridH2Row value) throws IgniteCheckedException { + return tree.put(value, value); + } + + @Override public GridH2Row findOne(GridSearchRowPointer key) throws IgniteCheckedException { + return tree.get(key); + } + + @Override public GridCursor<GridH2Row> find(GridSearchRowPointer lower, boolean lowerInclusive, + GridSearchRowPointer upper, boolean upperInclusive) + throws IgniteCheckedException { + + NavigableMap<GridSearchRowPointer, GridH2Row> subMap = + tree.subMap(lower, lowerInclusive, upper, upperInclusive); + + return new GridCursorIteratorWrapper<GridH2Row>(subMap.values().iterator()); + } + + public GridCursor<GridH2Row> find(GridSearchRowPointer lower, GridSearchRowPointer upper) + throws IgniteCheckedException { + return find(lower, true, upper, true); + } + + public GridCursor<GridH2Row> findAll() throws IgniteCheckedException { + return find(null, null); + } + + @Override public GridH2Row removeNode(GridSearchRowPointer key) throws IgniteCheckedException { + return tree.remove(key); + } + + @Override public long treeSize() throws IgniteCheckedException { + return tree.size(); + } + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/b2999f2e/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractQuerySelfTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractQuerySelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractQuerySelfTest.java index e4b7dd3..15f110f 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractQuerySelfTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheAbstractQuerySelfTest.java @@ -172,7 +172,7 @@ public abstract class IgniteCacheAbstractQuerySelfTest extends GridCommonAbstrac if (cacheMode() == CacheMode.PARTITIONED) cc.setBackups(gridCount()); - cc.setSnapshotableIndex(snapshotableIndex()); + //cc.setSnapshotableIndex(snapshotableIndex()); return cc; } http://git-wip-us.apache.org/repos/asf/ignite/blob/b2999f2e/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2TableSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2TableSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2TableSelfTest.java index a0ac181..5daf415 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2TableSelfTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2TableSelfTest.java @@ -33,7 +33,10 @@ import java.util.Set; import java.util.UUID; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.ignite.*; import org.apache.ignite.internal.processors.query.h2.database.H2RowFactory; +import org.apache.ignite.internal.util.lang.*; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; import org.h2.Driver; @@ -283,11 +286,11 @@ public class GridH2TableSelfTest extends GridCommonAbstractTest { * * @param idx Index. */ - private void dumpRows(GridH2TreeIndex idx) { - Iterator<GridH2Row> iter = idx.rows(); + private void dumpRows(GridH2TreeIndex idx) throws IgniteCheckedException { + GridCursor<GridH2Row> cursor = idx.rows(); - while (iter.hasNext()) - System.out.println(iter.next().toString()); + while (cursor.next()) + System.out.println(cursor.get().toString()); } /** @@ -584,17 +587,17 @@ public class GridH2TableSelfTest extends GridCommonAbstractTest { * @param rowSet Rows. * @return Rows. */ - private Set<Row> checkIndexesConsistent(ArrayList<Index> idxs, @Nullable Set<Row> rowSet) { + private Set<Row> checkIndexesConsistent(ArrayList<Index> idxs, @Nullable Set<Row> rowSet) throws IgniteCheckedException { for (Index idx : idxs) { if (!(idx instanceof GridH2TreeIndex)) continue; Set<Row> set = new HashSet<>(); - Iterator<GridH2Row> iter = ((GridH2TreeIndex)idx).rows(); + GridCursor<GridH2Row> cursor = ((GridH2TreeIndex)idx).rows(); - while(iter.hasNext()) - assertTrue(set.add(iter.next())); + while(cursor.next()) + assertTrue(set.add(cursor.get())); //((GridH2SnapTreeSet)((GridH2Index)idx).tree).print(); @@ -610,7 +613,7 @@ public class GridH2TableSelfTest extends GridCommonAbstractTest { /** * @param idxs Indexes list. */ - private void checkOrdered(ArrayList<Index> idxs) { + private void checkOrdered(ArrayList<Index> idxs) throws IgniteCheckedException { for (Index idx : idxs) { if (!(idx instanceof GridH2TreeIndex)) continue; @@ -625,13 +628,13 @@ public class GridH2TableSelfTest extends GridCommonAbstractTest { * @param idx Index. * @param cmp Comparator. */ - private void checkOrdered(GridH2TreeIndex idx, Comparator<? super GridH2Row> cmp) { - Iterator<GridH2Row> rows = idx.rows(); + private void checkOrdered(GridH2TreeIndex idx, Comparator<? super GridH2Row> cmp) throws IgniteCheckedException { + GridCursor<GridH2Row> cursor = idx.rows(); GridH2Row min = null; - while (rows.hasNext()) { - GridH2Row row = rows.next(); + while (cursor.next()) { + GridH2Row row = cursor.get(); assertNotNull(row);