You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2017/08/10 13:52:58 UTC

[01/30] ignite git commit: IGNITE-5888 Web Console: Fixed maven project generation.

Repository: ignite
Updated Branches:
  refs/heads/ignite-5872 cfbd3275d -> 855ece3b1


IGNITE-5888 Web Console: Fixed maven project generation.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/20969c07
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/20969c07
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/20969c07

Branch: refs/heads/ignite-5872
Commit: 20969c0755595ba686d00220287d986327ff2b9d
Parents: 4d323f3
Author: Andrey Novikov <an...@gridgain.com>
Authored: Thu Aug 3 10:42:08 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Thu Aug 3 10:42:08 2017 +0700

----------------------------------------------------------------------
 .../modules/configuration/generator/Maven.service.js   | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/20969c07/modules/web-console/frontend/app/modules/configuration/generator/Maven.service.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/modules/configuration/generator/Maven.service.js b/modules/web-console/frontend/app/modules/configuration/generator/Maven.service.js
index abbada9..9bf0a34 100644
--- a/modules/web-console/frontend/app/modules/configuration/generator/Maven.service.js
+++ b/modules/web-console/frontend/app/modules/configuration/generator/Maven.service.js
@@ -42,13 +42,18 @@ export default class IgniteMavenGenerator {
         deps.push({groupId, artifactId, version, jar});
     }
 
-    pickDependency(deps, key, dfltVer, igniteVer) {
+    pickDependency(acc, key, dfltVer, igniteVer) {
+        const deps = POM_DEPENDENCIES[key];
+
+        if (_.isNil(deps))
+            return;
+
         const extractVersion = (version) => {
             return _.isArray(version) ? _.find(version, (v) => versionService.since(igniteVer, v.range)).version : version;
         };
 
-        _.forEach(POM_DEPENDENCIES[key], ({groupId, artifactId, version, jar}) => {
-            this.addDependency(deps, groupId || 'org.apache.ignite', artifactId, extractVersion(version) || dfltVer, jar);
+        _.forEach(_.castArray(deps), ({groupId, artifactId, version, jar}) => {
+            this.addDependency(acc, groupId || 'org.apache.ignite', artifactId, extractVersion(version) || dfltVer, jar);
         });
     }
 
@@ -140,8 +145,10 @@ export default class IgniteMavenGenerator {
 
     /**
      * Add dependency for specified store factory if not exist.
+     *
      * @param deps Already added dependencies.
      * @param storeFactory Store factory to add dependency.
+     * @param igniteVer Ignite version.
      */
     storeFactoryDependency(deps, storeFactory, igniteVer) {
         if (storeFactory.dialect && (!storeFactory.connectVia || storeFactory.connectVia === 'DataSource'))


[09/30] ignite git commit: IGNITE-5908 Restore splash.

Posted by ag...@apache.org.
IGNITE-5908 Restore splash.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/0eedf46b
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/0eedf46b
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/0eedf46b

Branch: refs/heads/ignite-5872
Commit: 0eedf46bddb9647cc02efd982b212c8c0df19308
Parents: eb33607
Author: anovikov <an...@gridgain.com>
Authored: Fri Aug 4 18:10:36 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Fri Aug 4 18:10:36 2017 +0700

----------------------------------------------------------------------
 .../hide-on-state-change/hide-on-state-change.directive.js   | 8 ++------
 modules/web-console/frontend/views/index.pug                 | 8 ++++++++
 2 files changed, 10 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/0eedf46b/modules/web-console/frontend/app/directives/hide-on-state-change/hide-on-state-change.directive.js
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/app/directives/hide-on-state-change/hide-on-state-change.directive.js b/modules/web-console/frontend/app/directives/hide-on-state-change/hide-on-state-change.directive.js
index 98f1c57..152e942 100644
--- a/modules/web-console/frontend/app/directives/hide-on-state-change/hide-on-state-change.directive.js
+++ b/modules/web-console/frontend/app/directives/hide-on-state-change/hide-on-state-change.directive.js
@@ -15,13 +15,9 @@
  * limitations under the License.
  */
 
-export default ['hideOnStateChange', ['$timeout', ($timeout) => {
+export default ['hideOnStateChange', ['$transitions', ($transitions) => {
     const link = (scope, element) => {
-        scope.$on('$stateChangeSuccess', () => {
-            $timeout(() => {
-                element.fadeOut('slow');
-            });
-        });
+        $transitions.onSuccess({}, () => element.fadeOut('slow'));
     };
 
     return {

http://git-wip-us.apache.org/repos/asf/ignite/blob/0eedf46b/modules/web-console/frontend/views/index.pug
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/views/index.pug b/modules/web-console/frontend/views/index.pug
index 1881b38..2e47e87 100644
--- a/modules/web-console/frontend/views/index.pug
+++ b/modules/web-console/frontend/views/index.pug
@@ -30,6 +30,14 @@ html(ng-app='ignite-console' id='app' ng-strict-di)
 
     body.theme-line.body-overlap
 
+        .splash.splash-max-foreground(hide-on-state-change)
+            .splash-wrapper
+                .spinner
+                    .bounce1
+                    .bounce2
+                    .bounce3
+
+                .splash-wellcome Loading...
 
         .ribbon-wrapper.right(ng-cloak)
             .ribbon(ng-style='IgniteDemoMode && {"background": "#1b6d88"}')


[19/30] ignite git commit: IGNITE-5993: Removed unused SQL-related classes and methods (old tree index, snapshots, etc). This closes #2414.

Posted by ag...@apache.org.
IGNITE-5993: Removed unused SQL-related classes and methods (old tree index, snapshots, etc). This closes #2414.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/ebed404b
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/ebed404b
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/ebed404b

Branch: refs/heads/ignite-5872
Commit: ebed404bd1932fc8a937ce34140e5a2fd69f5f59
Parents: 870ecf8
Author: devozerov <vo...@gridgain.com>
Authored: Wed Aug 9 11:47:58 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Wed Aug 9 11:47:58 2017 +0300

----------------------------------------------------------------------
 .../query/h2/opt/GridH2SpatialIndex.java        |   7 -
 .../processors/query/h2/H2RowDescriptor.java    |  11 -
 .../processors/query/h2/H2TableEngine.java      |   4 +-
 .../query/h2/database/H2PkHashIndex.java        |   7 -
 .../query/h2/database/H2TreeIndex.java          |  26 -
 .../query/h2/opt/GridH2IndexBase.java           |  93 +--
 .../query/h2/opt/GridH2QueryContext.java        |  59 --
 .../query/h2/opt/GridH2RowDescriptor.java       |   5 -
 .../processors/query/h2/opt/GridH2Table.java    | 186 +-----
 .../query/h2/opt/GridH2TreeIndex.java           | 602 -------------------
 .../query/h2/twostep/GridMapQueryExecutor.java  |  25 -
 .../query/h2/opt/GridH2TableSelfTest.java       | 172 ------
 12 files changed, 7 insertions(+), 1190 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/ebed404b/modules/geospatial/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2SpatialIndex.java
----------------------------------------------------------------------
diff --git a/modules/geospatial/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2SpatialIndex.java b/modules/geospatial/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2SpatialIndex.java
index 9389290..d83e860 100644
--- a/modules/geospatial/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2SpatialIndex.java
+++ b/modules/geospatial/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2SpatialIndex.java
@@ -31,7 +31,6 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.internal.processors.query.h2.H2Cursor;
 import org.apache.ignite.internal.util.GridCursorIteratorWrapper;
-import org.apache.ignite.internal.util.IgniteTree;
 import org.apache.ignite.internal.util.lang.GridCursor;
 import org.h2.engine.Session;
 import org.h2.index.Cursor;
@@ -51,7 +50,6 @@ import org.h2.table.IndexColumn;
 import org.h2.table.TableFilter;
 import org.h2.value.Value;
 import org.h2.value.ValueGeometry;
-import org.jetbrains.annotations.Nullable;
 
 import static org.apache.ignite.internal.processors.query.h2.opt.GridH2AbstractKeyValueRow.KEY_COL;
 
@@ -158,11 +156,6 @@ public class GridH2SpatialIndex extends GridH2IndexBase implements SpatialIndex
     }
 
     /** {@inheritDoc} */
-    @Nullable @Override protected IgniteTree doTakeSnapshot() {
-        return null; // TODO We do not support snapshots, but probably this is possible.
-    }
-
-    /** {@inheritDoc} */
     @Override public GridH2Row put(GridH2Row row) {
         assert row instanceof GridH2AbstractKeyValueRow : "requires key to be at 0";
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/ebed404b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2RowDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2RowDescriptor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2RowDescriptor.java
index dab83d1..31f0e69 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2RowDescriptor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2RowDescriptor.java
@@ -107,9 +107,6 @@ public class H2RowDescriptor implements GridH2RowDescriptor {
     private final GridUnsafeGuard guard;
 
     /** */
-    private final boolean snapshotableIdx;
-
-    /** */
     private final GridQueryProperty[] props;
 
     /** Id of user-defined key column */
@@ -170,9 +167,6 @@ public class H2RowDescriptor implements GridH2RowDescriptor {
 
         valueAliasColumnId =
             (type.valueFieldName() != null) ? DEFAULT_COLUMNS_COUNT + fieldsList.indexOf(type.valueFieldAlias()) : -1;
-
-        // Index is not snapshotable in db-x.
-        snapshotableIdx = false;
     }
 
     /** {@inheritDoc} */
@@ -382,11 +376,6 @@ public class H2RowDescriptor implements GridH2RowDescriptor {
     }
 
     /** {@inheritDoc} */
-    @Override public boolean snapshotableIndex() {
-        return snapshotableIdx;
-    }
-
-    /** {@inheritDoc} */
     @Override public boolean isKeyColumn(int columnId) {
         assert columnId >= 0;
         return columnId == KEY_COL || columnId == keyAliasColumnId;

http://git-wip-us.apache.org/repos/asf/ignite/blob/ebed404b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableEngine.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableEngine.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableEngine.java
index 57b7ba0..6bdcc30 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableEngine.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/H2TableEngine.java
@@ -56,8 +56,8 @@ public class H2TableEngine implements TableEngine {
      * @throws SQLException If failed.
      * @return Created table.
      */
-    public static synchronized GridH2Table createTable(Connection conn, String sql,
-        @Nullable GridH2RowDescriptor rowDesc, H2RowFactory rowFactory, H2TableDescriptor tblDesc)
+    public static synchronized GridH2Table createTable(Connection conn, String sql, GridH2RowDescriptor rowDesc,
+        H2RowFactory rowFactory, H2TableDescriptor tblDesc)
         throws SQLException {
         rowDesc0 = rowDesc;
         rowFactory0 = rowFactory;

http://git-wip-us.apache.org/repos/asf/ignite/blob/ebed404b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2PkHashIndex.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2PkHashIndex.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2PkHashIndex.java
index 2ae5868..1937a4b 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2PkHashIndex.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2PkHashIndex.java
@@ -30,7 +30,6 @@ import org.apache.ignite.internal.processors.cache.persistence.CacheDataRow;
 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.IgniteTree;
 import org.apache.ignite.internal.util.lang.GridCursor;
 import org.apache.ignite.lang.IgniteBiPredicate;
 import org.apache.ignite.spi.indexing.IndexingQueryFilter;
@@ -44,7 +43,6 @@ import org.h2.result.SortOrder;
 import org.h2.table.Column;
 import org.h2.table.IndexColumn;
 import org.h2.table.TableFilter;
-import org.jetbrains.annotations.Nullable;
 
 /**
  *
@@ -199,11 +197,6 @@ public class H2PkHashIndex extends GridH2IndexBase {
         throw new UnsupportedOperationException();
     }
 
-    /** {@inheritDoc} */
-    @Nullable @Override protected IgniteTree doTakeSnapshot() {
-        throw new AssertionError("This method must not be called for PK index");
-    }
-
     /**
      * Cursor.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/ebed404b/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 e02510f..eb579c3 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
@@ -215,25 +215,6 @@ public class H2TreeIndex extends GridH2IndexBase {
     }
 
     /** {@inheritDoc} */
-    @Override public boolean putx(GridH2Row row) {
-        try {
-            InlineIndexHelper.setCurrentInlineIndexes(inlineIdxs);
-
-            int seg = segmentForRow(row);
-
-            H2Tree tree = treeForRead(seg);
-
-            return tree.putx(row);
-        }
-        catch (IgniteCheckedException e) {
-            throw DbException.convert(e);
-        }
-        finally {
-            InlineIndexHelper.clearCurrentInlineIndexes();
-        }
-    }
-
-    /** {@inheritDoc} */
     @Override public GridH2Row remove(SearchRow row) {
         try {
             InlineIndexHelper.setCurrentInlineIndexes(inlineIdxs);
@@ -344,13 +325,6 @@ public class H2TreeIndex extends GridH2IndexBase {
     }
 
     /** {@inheritDoc} */
-    @Nullable @Override protected IgniteTree<SearchRow, GridH2Row> doTakeSnapshot() {
-        int seg = threadLocalSegment();
-
-        return treeForRead(seg);
-    }
-
-    /** {@inheritDoc} */
     @Override protected H2Tree treeForRead(int segment) {
         return segments[segment];
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/ebed404b/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 542adf0..5d5fb56 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
@@ -22,7 +22,6 @@ import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.Future;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
 import javax.cache.CacheException;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteInterruptedException;
@@ -35,7 +34,6 @@ import org.apache.ignite.internal.managers.communication.GridIoPolicy;
 import org.apache.ignite.internal.managers.communication.GridMessageListener;
 import org.apache.ignite.internal.processors.cache.CacheObject;
 import org.apache.ignite.internal.processors.cache.GridCacheContext;
-import org.apache.ignite.internal.processors.cache.distributed.dht.GridReservable;
 import org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2IndexRangeRequest;
 import org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2IndexRangeResponse;
 import org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2RowMessage;
@@ -93,15 +91,6 @@ public abstract class GridH2IndexBase extends BaseIndex {
     private static final Object EXPLICIT_NULL = new Object();
 
     /** */
-    private static final AtomicLong idxIdGen = new AtomicLong();
-
-    /** */
-    protected final long idxId = idxIdGen.incrementAndGet();
-
-    /** */
-    private final ThreadLocal<Object> snapshot = new ThreadLocal<>();
-
-    /** */
     private Object msgTopic;
 
     /** */
@@ -198,16 +187,6 @@ public abstract class GridH2IndexBase extends BaseIndex {
     public abstract GridH2Row put(GridH2Row row);
 
     /**
-     * Puts row.
-     *
-     * @param row Row.
-     * @return {@code True} if replaced existing row.
-     */
-    public boolean putx(GridH2Row row) {
-        return put(row) != null;
-    }
-
-    /**
      * Remove row from index.
      *
      * @param row Row.
@@ -233,32 +212,6 @@ public abstract class GridH2IndexBase extends BaseIndex {
     public abstract GridH2Row findOne(GridH2Row row);
 
     /**
-     * Takes or sets existing snapshot to be used in current thread.
-     *
-     * @param s Optional existing snapshot to use.
-     * @param qctx Query context.
-     * @return Snapshot.
-     */
-    public final Object takeSnapshot(@Nullable Object s, GridH2QueryContext qctx) {
-        assert snapshot.get() == null;
-
-        if (s == null)
-            s = doTakeSnapshot();
-
-        if (s != null) {
-            if (s instanceof GridReservable && !((GridReservable)s).reserve())
-                return null;
-
-            snapshot.set(s);
-
-            if (qctx != null)
-                qctx.putSnapshot(idxId, s);
-        }
-
-        return s;
-    }
-
-    /**
      * @param ses Session.
      */
     private static void clearViewIndexCache(Session ses) {
@@ -303,38 +256,6 @@ public abstract class GridH2IndexBase extends BaseIndex {
     }
 
     /**
-     * Takes and returns actual snapshot or {@code null} if snapshots are not supported.
-     *
-     * @return Snapshot or {@code null}.
-     */
-    @Nullable protected abstract IgniteTree doTakeSnapshot();
-
-    /**
-     * @return Thread local snapshot.
-     */
-    @SuppressWarnings("unchecked")
-    protected <T> T threadLocalSnapshot() {
-        return (T)snapshot.get();
-    }
-
-    /**
-     * Releases snapshot for current thread.
-     */
-    public void releaseSnapshot() {
-        Object s = snapshot.get();
-
-        assert s != null;
-
-        snapshot.remove();
-
-        if (s instanceof GridReservable)
-            ((GridReservable)s).release();
-
-        if (s instanceof AutoCloseable)
-            U.closeQuiet((AutoCloseable)s);
-    }
-
-    /**
      * Filters rows from expired ones and using predicate.
      *
      * @param cursor GridCursor over rows.
@@ -498,11 +419,9 @@ public abstract class GridH2IndexBase extends BaseIndex {
 
                 if (msg.bounds() != null) {
                     // This is the first request containing all the search rows.
-                    IgniteTree snapshotTree = qctx.getSnapshot(idxId);
-
                     assert !msg.bounds().isEmpty() : "empty bounds";
 
-                    src = new RangeSource(msg.bounds(), msg.segment(), snapshotTree, qctx.filter());
+                    src = new RangeSource(msg.bounds(), msg.segment(), qctx.filter());
                 }
                 else {
                     // This is request to fetch next portion of data.
@@ -619,7 +538,7 @@ public abstract class GridH2IndexBase extends BaseIndex {
 
         if (isLocalQry) {
             if (partMap != null && !partMap.containsKey(cctx.localNodeId()))
-                return Collections.<SegmentKey>emptyList(); // Prevent remote index call for local queries.
+                return Collections.emptyList(); // Prevent remote index call for local queries.
 
             nodes = Collections.singletonList(cctx.localNode());
         }
@@ -1543,9 +1462,6 @@ public abstract class GridH2IndexBase extends BaseIndex {
         int curRangeId = -1;
 
         /** */
-        final IgniteTree tree;
-
-        /** */
         private final int segment;
 
         /** */
@@ -1556,18 +1472,15 @@ public abstract class GridH2IndexBase extends BaseIndex {
 
         /**
          * @param bounds Bounds.
-         * @param tree Snapshot.
          * @param filter Filter.
          */
         RangeSource(
             Iterable<GridH2RowRangeBounds> bounds,
             int segment,
-            IgniteTree tree,
             IndexingQueryFilter filter
         ) {
             this.segment = segment;
             this.filter = filter;
-            this.tree = tree;
             boundsIter = bounds.iterator();
         }
 
@@ -1623,7 +1536,7 @@ public abstract class GridH2IndexBase extends BaseIndex {
                 SearchRow first = toSearchRow(bounds.first());
                 SearchRow last = toSearchRow(bounds.last());
 
-                IgniteTree t = tree != null ? tree : treeForRead(segment);
+                IgniteTree t = treeForRead(segment);
 
                 iter = new CursorIteratorWrapper(doFind0(t, first, true, last, filter));
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/ebed404b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2QueryContext.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2QueryContext.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2QueryContext.java
index a7ee0dc..2b4e180 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2QueryContext.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2QueryContext.java
@@ -25,7 +25,6 @@ import java.util.concurrent.ConcurrentMap;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.cache.GridCacheContext;
 import org.apache.ignite.internal.processors.cache.distributed.dht.GridReservable;
-import org.apache.ignite.internal.util.tostring.GridToStringInclude;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.spi.indexing.IndexingQueryFilter;
@@ -51,10 +50,6 @@ public class GridH2QueryContext {
     /** */
     private volatile boolean cleared;
 
-    /** Index snapshots. */
-    @GridToStringInclude
-    private Map<Long, Object> snapshots;
-
     /** */
     private List<GridReservable> reservations;
 
@@ -248,51 +243,6 @@ public class GridH2QueryContext {
     }
 
     /**
-     * @param idxId Index ID.
-     * @param snapshot Index snapshot.
-     */
-    public void putSnapshot(long idxId, Object snapshot) {
-        assert snapshot != null;
-        assert get() == null : "need to snapshot indexes before setting query context for correct visibility";
-
-        if (snapshot instanceof GridReservable && !((GridReservable)snapshot).reserve())
-            throw new IllegalStateException("Must be already reserved before.");
-
-        if (snapshots == null)
-            snapshots = new HashMap<>();
-
-        if (snapshots.put(idxId, snapshot) != null)
-            throw new IllegalStateException("Index already snapshoted.");
-    }
-
-    /**
-     * Clear taken snapshots.
-     */
-    public void clearSnapshots() {
-        if (F.isEmpty(snapshots))
-            return;
-
-        for (Object snapshot : snapshots.values()) {
-            if (snapshot instanceof GridReservable)
-                ((GridReservable)snapshot).release();
-        }
-
-        snapshots = null;
-    }
-
-    /**
-     * @param idxId Index ID.
-     * @return Index snapshot or {@code null} if none.
-     */
-    @SuppressWarnings("unchecked")
-    public <T> T getSnapshot(long idxId) {
-        if (snapshots == null)
-            return null;
-
-        return (T)snapshots.get(idxId);
-    }
-
-    /**
      * @param batchLookupId Batch lookup ID.
      * @param streams Range streams.
      */
@@ -363,13 +313,6 @@ public class GridH2QueryContext {
     }
 
     /**
-     * @return If indexes were snapshotted before query execution.
-     */
-    public boolean hasIndexSnapshots() {
-        return snapshots != null;
-    }
-
-    /**
      * Sets current thread local context. This method must be called when all the non-volatile properties are
      * already set to ensure visibility for other threads.
      *
@@ -440,8 +383,6 @@ public class GridH2QueryContext {
     public void clearContext(boolean nodeStop) {
         cleared = true;
 
-        clearSnapshots();
-
         List<GridReservable> r = reservations;
 
         if (!nodeStop && !F.isEmpty(r)) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/ebed404b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2RowDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2RowDescriptor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2RowDescriptor.java
index ce73010..d273e16 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2RowDescriptor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2RowDescriptor.java
@@ -154,11 +154,6 @@ public interface GridH2RowDescriptor extends GridOffHeapSmartPointerFactory<Grid
     public Value wrap(Object o, int type) throws IgniteCheckedException;
 
     /**
-     * @return {@code True} if index should support snapshots.
-     */
-    public boolean snapshotableIndex();
-
-    /**
      * Checks if provided column id matches key column or key alias.
      *
      * @param colId Column id.

http://git-wip-us.apache.org/repos/asf/ignite/blob/ebed404b/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 76d0258..f76cb5f 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
@@ -22,8 +22,6 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReferenceArray;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -61,7 +59,6 @@ import org.jsr166.LongAdder8;
 
 import static org.apache.ignite.cache.CacheMode.PARTITIONED;
 import static org.apache.ignite.internal.processors.query.h2.opt.GridH2AbstractKeyValueRow.KEY_COL;
-import static org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryType.MAP;
 
 /**
  * H2 Table implementation.
@@ -95,18 +92,12 @@ public class GridH2Table extends TableBase {
     private final ConcurrentMap<Session, Boolean> sessions = new ConcurrentHashMap8<>();
 
     /** */
-    private final AtomicReferenceArray<Object[]> actualSnapshot;
-
-    /** */
     private IndexColumn affKeyCol;
 
     /** */
     private final LongAdder8 size = new LongAdder8();
 
     /** */
-    private final boolean snapshotEnabled;
-
-    /** */
     private final H2RowFactory rowFactory;
 
     /** */
@@ -127,7 +118,7 @@ public class GridH2Table extends TableBase {
      * @param idxsFactory Indexes factory.
      * @param cctx Cache context.
      */
-    public GridH2Table(CreateTableData createTblData, @Nullable GridH2RowDescriptor desc, H2RowFactory rowFactory,
+    public GridH2Table(CreateTableData createTblData, GridH2RowDescriptor desc, H2RowFactory rowFactory,
         GridH2SystemIndexFactory idxsFactory, GridCacheContext cctx) {
         super(createTblData);
 
@@ -136,7 +127,7 @@ public class GridH2Table extends TableBase {
         this.desc = desc;
         this.cctx = cctx;
 
-        if (desc != null && desc.context() != null && !desc.context().customAffinityMapper()) {
+        if (desc.context() != null && !desc.context().customAffinityMapper()) {
             boolean affinityColExists = true;
 
             String affKey = desc.type().affinityKey();
@@ -186,18 +177,10 @@ public class GridH2Table extends TableBase {
         else
             idxs.add(0, new GridH2PrimaryScanIndex(this, index(0), null));
 
-        snapshotEnabled = desc == null || desc.snapshotableIndex();
-
         pkIndexPos = hasHashIndex ? 2 : 1;
 
         sysIdxsCnt = idxs.size();
 
-        final int segments = desc != null ? desc.context().config().getQueryParallelism() :
-            // Get index segments count from PK index. Null desc can be passed from tests.
-            index(pkIndexPos).segmentsCount();
-
-        actualSnapshot = snapshotEnabled ? new AtomicReferenceArray<Object[]>(Math.max(segments, 1)) : null;
-
         lock = new ReentrantReadWriteLock();
     }
 
@@ -259,79 +242,10 @@ public class GridH2Table extends TableBase {
             throw new IllegalStateException("Table " + identifierString() + " already destroyed.");
         }
 
-        if (snapshotInLock()) {
-            final GridH2QueryContext qctx = GridH2QueryContext.get();
-
-            assert qctx != null;
-
-            snapshotIndexes(null, qctx.segment());
-        }
-
         return false;
     }
 
     /**
-     * @return {@code True} If we must snapshot and release index snapshots in {@link #lock(Session, boolean, boolean)}
-     * and {@link #unlock(Session)} methods.
-     */
-    private boolean snapshotInLock() {
-        if (!snapshotEnabled)
-            return false;
-
-        GridH2QueryContext qctx = GridH2QueryContext.get();
-
-        // On MAP queries with distributed joins we lock tables before the queries.
-        return qctx == null || qctx.type() != MAP || !qctx.hasIndexSnapshots();
-    }
-
-    /**
-     * @param qctx Query context.
-     * @param segment id of index segment to be snapshoted.
-     */
-    public void snapshotIndexes(GridH2QueryContext qctx, int segment) {
-        if (!snapshotEnabled)
-            return;
-
-        Object[] segmentSnapshot;
-
-        // Try to reuse existing snapshots outside of the lock.
-        for (long waitTime = 200; ; waitTime *= 2) { // Increase wait time to avoid starvation.
-            segmentSnapshot = actualSnapshot.get(segment);
-
-            if (segmentSnapshot != null) { // Reuse existing snapshot without locking.
-                segmentSnapshot = doSnapshotIndexes(segment, segmentSnapshot, qctx);
-
-                if (segmentSnapshot != null)
-                    return; // Reused successfully.
-            }
-
-            if (tryLock(true, waitTime))
-                break;
-        }
-
-        try {
-            ensureNotDestroyed();
-
-            // Try again inside of the lock.
-            segmentSnapshot = actualSnapshot.get(segment);
-
-            if (segmentSnapshot != null) // Try reusing.
-                segmentSnapshot = doSnapshotIndexes(segment, segmentSnapshot, qctx);
-
-            if (segmentSnapshot == null) { // Reuse failed, produce new snapshots.
-                segmentSnapshot = doSnapshotIndexes(segment,null, qctx);
-
-                assert segmentSnapshot != null;
-
-                actualSnapshot.set(segment, segmentSnapshot);
-            }
-        }
-        finally {
-            unlock(true);
-        }
-    }
-
-    /**
      * @return Table identifier.
      */
     public QueryTable identifier() {
@@ -364,27 +278,6 @@ public class GridH2Table extends TableBase {
     }
 
     /**
-     * @param exclusive Exclusive lock.
-     * @param waitMillis Milliseconds to wait for the lock.
-     * @return Whether lock was acquired.
-     */
-    private boolean tryLock(boolean exclusive, long waitMillis) {
-        Lock l = exclusive ? lock.writeLock() : lock.readLock();
-
-        try {
-            if (!l.tryLock(waitMillis, TimeUnit.MILLISECONDS))
-                return false;
-        }
-        catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-
-            throw new IgniteInterruptedException("Thread got interrupted while trying to acquire table lock.", e);
-        }
-
-        return true;
-    }
-
-    /**
      * Release table lock.
      *
      * @param exclusive Exclusive flag.
@@ -403,55 +296,6 @@ public class GridH2Table extends TableBase {
             throw new IllegalStateException("Table " + identifierString() + " already destroyed.");
     }
 
-    /**
-     * Must be called inside of write lock because when using multiple indexes we have to ensure that all of them have
-     * the same contents at snapshot taking time.
-     *
-     * @param segment id of index segment snapshot.
-     * @param segmentSnapshot snapshot to be reused.
-     * @param qctx Query context.
-     * @return New indexes data snapshot.
-     */
-    @SuppressWarnings("unchecked")
-    private Object[] doSnapshotIndexes(int segment, Object[] segmentSnapshot, GridH2QueryContext qctx) {
-        assert snapshotEnabled;
-
-        //TODO: make HashIndex snapshotable or remove it at all?
-        if (segmentSnapshot == null) // Nothing to reuse, create new snapshots.
-            segmentSnapshot = new Object[idxs.size() - pkIndexPos];
-
-        // Take snapshots on all except first which is scan.
-        for (int i = pkIndexPos, len = idxs.size(); i < len; i++) {
-            Object s = segmentSnapshot[i - pkIndexPos];
-
-            boolean reuseExisting = s != null;
-
-            if (!(idxs.get(i) instanceof GridH2IndexBase))
-                continue;
-
-            s = index(i).takeSnapshot(s, qctx);
-
-            if (reuseExisting && s == null) { // Existing snapshot was invalidated before we were able to reserve it.
-                // Release already taken snapshots.
-                if (qctx != null)
-                    qctx.clearSnapshots();
-
-                for (int j = pkIndexPos; j < i; j++)
-                    if ((idxs.get(j) instanceof GridH2IndexBase))
-                        index(j).releaseSnapshot();
-
-                // Drop invalidated snapshot.
-                actualSnapshot.compareAndSet(segment, segmentSnapshot, null);
-
-                return null;
-            }
-
-            segmentSnapshot[i - pkIndexPos] = s;
-        }
-
-        return segmentSnapshot;
-    }
-
     /** {@inheritDoc} */
     @Override public void close(Session ses) {
         // No-op.
@@ -525,32 +369,10 @@ public class GridH2Table extends TableBase {
         if (exclusive == null)
             return;
 
-        if (snapshotInLock())
-            releaseSnapshots();
-
         unlock(exclusive);
     }
 
     /**
-     * Releases snapshots.
-     */
-    public void releaseSnapshots() {
-        if (!snapshotEnabled)
-            return;
-
-        releaseSnapshots0(idxs);
-    }
-
-    /**
-     * @param idxs Indexes.
-     */
-    private void releaseSnapshots0(ArrayList<Index> idxs) {
-        // Release snapshots on all except first which is scan and second which is hash.
-        for (int i = 2, len = idxs.size(); i < len; i++)
-            ((GridH2IndexBase)idxs.get(i)).releaseSnapshot();
-    }
-
-    /**
      * Updates table for given key. If value is null then row with given key will be removed from table,
      * otherwise value and expiration time will be updated or new row will be added.
      *
@@ -700,10 +522,6 @@ public class GridH2Table extends TableBase {
                     return false;
             }
 
-            // The snapshot is not actual after update.
-            if (actualSnapshot != null)
-                actualSnapshot.set(pk.segmentForRow(row), null);
-
             return true;
         }
         finally {

http://git-wip-us.apache.org/repos/asf/ignite/blob/ebed404b/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
deleted file mode 100644
index 03fedcb..0000000
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridH2TreeIndex.java
+++ /dev/null
@@ -1,602 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.internal.processors.query.h2.opt;
-
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.NavigableMap;
-import java.util.concurrent.ConcurrentSkipListMap;
-import org.apache.ignite.IgniteCheckedException;
-import org.apache.ignite.internal.processors.query.h2.H2Cursor;
-import org.apache.ignite.internal.util.GridCursorIteratorWrapper;
-import org.apache.ignite.internal.util.IgniteTree;
-import org.apache.ignite.internal.util.lang.GridCursor;
-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;
-import org.apache.ignite.internal.util.typedef.internal.SB;
-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.index.SingleRowCursor;
-import org.h2.message.DbException;
-import org.h2.result.SearchRow;
-import org.h2.result.SortOrder;
-import org.h2.table.Column;
-import org.h2.table.IndexColumn;
-import org.h2.table.TableFilter;
-import org.h2.value.Value;
-import org.jetbrains.annotations.Nullable;
-
-/**
- * Base class for snapshotable segmented tree indexes.
- */
-@SuppressWarnings("ComparatorNotSerializable")
-public class GridH2TreeIndex extends GridH2IndexBase implements Comparator<GridSearchRowPointer> {
-    /** */
-    private final IgniteNavigableMapTree[] segments;
-
-    /** */
-    private final boolean snapshotEnabled;
-
-    /**
-     * Constructor with index initialization. Creates index with single segment.
-     *
-     * @param name Index name.
-     * @param tbl Table.
-     * @param pk If this index is primary key.
-     * @param colsList Index columns list.
-     */
-    @SuppressWarnings("unchecked")
-    public GridH2TreeIndex(String name, GridH2Table tbl, boolean pk, List<IndexColumn> colsList) {
-        this(name, tbl, pk, colsList, 1);
-    }
-
-    /**
-     * Constructor with index initialization.
-     *
-     * @param name Index name.
-     * @param tbl Table.
-     * @param pk If this index is primary key.
-     * @param colsList Index columns list.
-     * @param segmentsCnt Number of segments.
-     */
-    @SuppressWarnings("unchecked")
-    public GridH2TreeIndex(String name, GridH2Table tbl, boolean pk, List<IndexColumn> colsList, int segmentsCnt) {
-        assert segmentsCnt > 0 : segmentsCnt;
-
-        IndexColumn[] cols = colsList.toArray(new IndexColumn[colsList.size()]);
-
-        IndexColumn.mapColumns(cols, tbl);
-
-        initBaseIndex(tbl, 0, name, cols,
-            pk ? IndexType.createPrimaryKey(false, false) : IndexType.createNonUnique(false, false, false));
-
-        segments = new IgniteNavigableMapTree[segmentsCnt];
-
-        final GridH2RowDescriptor desc = tbl.rowDescriptor();
-
-        if (desc == null || desc.memory() == null) {
-            snapshotEnabled = desc == null || desc.snapshotableIndex();
-
-            if (snapshotEnabled) {
-                for (int i = 0; i < segmentsCnt; i++) {
-                    segments[i] = new IgniteNavigableMapTree(new SnapTreeMap<GridSearchRowPointer, GridH2Row>(this) {
-                        @Override protected void afterNodeUpdate_nl(Node<GridSearchRowPointer, GridH2Row> node, Object val) {
-                            if (val != null)
-                                node.key = (GridSearchRowPointer)val;
-                        }
-
-                        @Override protected Comparable<? super GridSearchRowPointer> comparable(Object key) {
-                            if (key instanceof ComparableRow)
-                                return (Comparable<? super SearchRow>)key;
-
-                            return super.comparable(key);
-                        }
-                    });
-                }
-            }
-            else {
-                for (int i = 0; i < segmentsCnt; i++) {
-                    segments[i] = new IgniteNavigableMapTree(
-                    new ConcurrentSkipListMap<GridSearchRowPointer, GridH2Row>(
-                        new Comparator<GridSearchRowPointer>() {
-                            @Override public int compare(GridSearchRowPointer o1, GridSearchRowPointer o2) {
-                                if (o1 instanceof ComparableRow)
-                                    return ((ComparableRow)o1).compareTo(o2);
-
-                                if (o2 instanceof ComparableRow)
-                                    return -((ComparableRow)o2).compareTo(o1);
-
-                                return compareRows(o1, o2);
-                            }
-                        }
-                    ));
-                }
-            }
-        }
-        else {
-            assert desc.snapshotableIndex() : desc;
-
-            snapshotEnabled = true;
-
-            for (int i = 0; i < segmentsCnt; i++) {
-                segments[i] = new IgniteNavigableMapTree(new GridOffHeapSnapTreeMap<GridSearchRowPointer, GridH2Row>(desc, desc, desc.memory(), desc.guard(), this) {
-                    @Override protected void afterNodeUpdate_nl(long node, GridH2Row val) {
-                        final long oldKey = keyPtr(node);
-
-                        if (val != null) {
-                            key(node, val);
-
-                            guard.finalizeLater(new Runnable() {
-                                @Override public void run() {
-                                    desc.createPointer(oldKey).decrementRefCount();
-                                }
-                            });
-                        }
-                    }
-
-                    @Override protected Comparable<? super GridSearchRowPointer> comparable(Object key) {
-                        if (key instanceof ComparableRow)
-                            return (Comparable<? super SearchRow>)key;
-
-                        return super.comparable(key);
-                    }
-                });
-            }
-        }
-
-        initDistributedJoinMessaging(tbl);
-    }
-
-    /** {@inheritDoc} */
-    @Override protected IgniteTree doTakeSnapshot() {
-        assert snapshotEnabled;
-
-        int seg = threadLocalSegment();
-
-        IgniteNavigableMapTree tree = segments[seg];
-
-        return tree.clone();
-    }
-
-    /** {@inheritDoc} */
-    @Override protected final IgniteTree treeForRead(int seg) {
-        if (!snapshotEnabled)
-            return segments[seg];
-
-        IgniteTree res = threadLocalSnapshot();
-
-        if (res == null)
-            return segments[seg];
-
-        return res;
-    }
-
-    /** {@inheritDoc} */
-    @Override public void destroy() {
-        assert threadLocalSnapshot() == null;
-
-        super.destroy();
-    }
-
-    /** {@inheritDoc} */
-    @Override public long getRowCount(@Nullable Session ses) {
-        IndexingQueryFilter f = threadLocalFilter();
-
-        int seg = threadLocalSegment();
-
-        // Fast path if we don't need to perform any filtering.
-        if (f == null || f.forCache((getTable()).cacheName()) == null)
-            try {
-                return treeForRead(seg).size();
-            } catch (IgniteCheckedException e) {
-                throw DbException.convert(e);
-            }
-
-        GridCursor<GridH2Row> cursor = doFind(null, false, null);
-
-        long size = 0;
-
-        try {
-            while (cursor.next())
-                size++;
-        }
-        catch (IgniteCheckedException e) {
-            throw DbException.convert(e);
-        }
-
-        return size;
-    }
-
-    /** {@inheritDoc} */
-    @Override public long getRowCountApproximation() {
-        return table.getRowCountApproximation();
-    }
-
-    /** {@inheritDoc} */
-    @Override public int compare(GridSearchRowPointer r1, GridSearchRowPointer r2) {
-        // Second row here must be data row if first is a search row.
-        return -compareRows(r2, r1);
-    }
-
-    /** {@inheritDoc} */
-    @Override public String toString() {
-        SB sb = new SB((indexType.isUnique() ? "Unique index '" : "Index '") + getName() + "' [");
-
-        boolean first = true;
-
-        for (IndexColumn col : getIndexColumns()) {
-            if (first)
-                first = false;
-            else
-                sb.a(", ");
-
-            sb.a(col.getSQL());
-        }
-
-        sb.a(" ]");
-
-        return sb.toString();
-    }
-
-    /** {@inheritDoc} */
-    @Override public double getCost(Session ses, int[] masks, TableFilter[] filters, int filter,
-        SortOrder sortOrder, HashSet<Column> cols) {
-        long rowCnt = getRowCountApproximation();
-        double baseCost = getCostRangeIndex(masks, rowCnt, filters, filter, sortOrder, false, cols);
-        int mul = getDistributedMultiplier(ses, filters, filter);
-
-        return mul * baseCost;
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean canFindNext() {
-        return false;
-    }
-
-    /** {@inheritDoc} */
-    @Override public Cursor find(Session ses, @Nullable SearchRow first, @Nullable SearchRow last) {
-        return new H2Cursor(doFind(first, true, last), null);
-    }
-
-    /** {@inheritDoc} */
-    @Override public Cursor findNext(Session ses, SearchRow higherThan, SearchRow last) {
-        return new H2Cursor(doFind(higherThan, false, last), null);
-    }
-
-    /**
-     * Finds row with key equal one in given search row.
-     * WARNING!! Method call must be protected by {@link GridUnsafeGuard#begin()}
-     * {@link GridUnsafeGuard#end()} block.
-     *
-     * @param row Search row.
-     * @return Row.
-     */
-    @Override public GridH2Row findOne(GridH2Row row) {
-        int seg = segmentForRow(row);
-
-        return segments[seg].findOne(row);
-    }
-
-    /**
-     * Returns sub-tree bounded by given values.
-     *
-     * @param first Lower bound.
-     * @param includeFirst Whether lower bound should be inclusive.
-     * @param last Upper bound always inclusive.
-     * @return Iterator over rows in given range.
-     */
-    @SuppressWarnings("unchecked")
-    private GridCursor<GridH2Row> doFind(@Nullable SearchRow first, boolean includeFirst, @Nullable SearchRow last) {
-        int seg = threadLocalSegment();
-
-        IgniteTree t = treeForRead(seg);
-
-        return doFind0(t, first, includeFirst, last, threadLocalFilter());
-    }
-
-    /** {@inheritDoc} */
-    @Override protected final GridCursor<GridH2Row> doFind0(
-        IgniteTree t,
-        @Nullable SearchRow first,
-        boolean includeFirst,
-        @Nullable SearchRow last,
-        IndexingQueryFilter filter
-    ) {
-        includeFirst &= first != null;
-
-        GridCursor<GridH2Row> range = subTree(t, comparable(first, includeFirst ? -1 : 1),
-            comparable(last, 1));
-
-        if (range == null)
-            return EMPTY_CURSOR;
-
-        return filter(range, filter);
-    }
-
-    /**
-     * @param row Row.
-     * @param bias Bias.
-     * @return Comparable row.
-     */
-    private GridSearchRowPointer comparable(SearchRow row, int bias) {
-        if (row == null)
-            return null;
-
-        if (bias == 0 && row instanceof GridH2Row)
-            return (GridSearchRowPointer)row;
-
-        return new ComparableRow(row, bias);
-    }
-
-    /**
-     * Takes sup-map from given one.
-     *
-     * @param tree Tree.
-     * @param first Lower bound.
-     * @param last Upper bound.
-     * @return Sub-map.
-     */
-    @SuppressWarnings({"IfMayBeConditional", "TypeMayBeWeakened"})
-    private GridCursor<GridH2Row> subTree(IgniteTree tree,
-        @Nullable GridSearchRowPointer first, @Nullable GridSearchRowPointer last) {
-
-        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, last);
-        }
-        catch (IgniteCheckedException e) {
-            throw DbException.convert(e);
-        }
-    }
-
-    /**
-     * Gets iterator over all rows in this index.
-     *
-     * @return Rows iterator.
-     */
-    GridCursor<GridH2Row> rows() {
-        return doFind(null, false, null);
-    }
-
-    /** {@inheritDoc} */
-    @Override public boolean canGetFirstOrLast() {
-        return true;
-    }
-
-    /** {@inheritDoc} */
-    @Override public Cursor findFirstOrLast(Session ses, boolean first) {
-        try {
-            int seg = threadLocalSegment();
-
-            IgniteTree t = treeForRead(seg);
-
-            GridH2Row row = (GridH2Row)(first ? t.findFirst() : t.findLast());
-
-            return new SingleRowCursor(row);
-        }
-        catch (IgniteCheckedException e) {
-            throw DbException.convert(e);
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override public GridH2Row put(GridH2Row row) {
-        int seg = segmentForRow(row);
-
-        return segments[seg].put(row);
-    }
-
-    /** {@inheritDoc} */
-    @Override public GridH2Row remove(SearchRow row) {
-        GridSearchRowPointer comparable = comparable(row, 0);
-
-        int seg = segmentForRow(row);
-
-        return segments[seg].remove(comparable);
-    }
-
-    /** {@inheritDoc} */
-    @Override protected int segmentsCount() {
-        return segments.length;
-    }
-
-    /**
-     * Comparable row with bias. Will be used for queries to have correct bounds (in case of multicolumn index
-     * and query on few first columns we will multiple equal entries in tree).
-     */
-    private final class ComparableRow implements GridSearchRowPointer, Comparable<SearchRow> {
-        /** */
-        private final SearchRow row;
-
-        /** */
-        private final int bias;
-
-        /**
-         * @param row Row.
-         * @param bias Bias.
-         */
-        private ComparableRow(SearchRow row, int bias) {
-            this.row = row;
-            this.bias = bias;
-        }
-
-        /** {@inheritDoc} */
-        @Override public int compareTo(SearchRow o) {
-            int res = compareRows(o, row);
-
-            if (res == 0)
-                return bias;
-
-            return -res;
-        }
-
-        /** {@inheritDoc} */
-        @Override public boolean equals(Object obj) {
-            throw new IllegalStateException("Should never be called.");
-        }
-
-        /** {@inheritDoc} */
-        @Override public int getColumnCount() {
-            return row.getColumnCount();
-        }
-
-        /** {@inheritDoc} */
-        @Override public Value getValue(int idx) {
-            return row.getValue(idx);
-        }
-
-        /** {@inheritDoc} */
-        @Override public void setValue(int idx, Value v) {
-            row.setValue(idx, v);
-        }
-
-        /** {@inheritDoc} */
-        @Override public void setKeyAndVersion(SearchRow old) {
-            row.setKeyAndVersion(old);
-        }
-
-        /** {@inheritDoc} */
-        @Override public int getVersion() {
-            return row.getVersion();
-        }
-
-        /** {@inheritDoc} */
-        @Override public void setKey(long key) {
-            row.setKey(key);
-        }
-
-        /** {@inheritDoc} */
-        @Override public long getKey() {
-            return row.getKey();
-        }
-
-        /** {@inheritDoc} */
-        @Override public int getMemory() {
-            return row.getMemory();
-        }
-
-        /** {@inheritDoc} */
-        @Override public long pointer() {
-            throw new IllegalStateException();
-        }
-
-        /** {@inheritDoc} */
-        @Override public void incrementRefCount() {
-            throw new IllegalStateException();
-        }
-
-        /** {@inheritDoc} */
-        @Override public void decrementRefCount() {
-            throw new IllegalStateException();
-        }
-    }
-
-    /**
-     * Adapter from {@link NavigableMap} to {@link IgniteTree}.
-     */
-    private static final class IgniteNavigableMapTree implements IgniteTree<GridSearchRowPointer, GridH2Row>, Cloneable {
-        /** Tree. */
-        private final NavigableMap<GridSearchRowPointer, GridH2Row> tree;
-
-        /**
-         * @param tree Tree.
-         */
-        private IgniteNavigableMapTree(NavigableMap<GridSearchRowPointer, GridH2Row> tree) {
-            this.tree = tree;
-        }
-
-        /** {@inheritDoc} */
-        @Override public void invoke(GridSearchRowPointer key, Object x, InvokeClosure<GridH2Row> c) {
-            throw new UnsupportedOperationException();
-        }
-
-        /** {@inheritDoc} */
-        @Override public GridH2Row put(GridH2Row val) {
-            return tree.put(val, val);
-        }
-
-        /** {@inheritDoc} */
-        @Override public GridH2Row findOne(GridSearchRowPointer key) {
-            return tree.get(key);
-        }
-
-        /** {@inheritDoc} */
-        @Override public GridCursor<GridH2Row> find(GridSearchRowPointer lower, GridSearchRowPointer upper)
-            throws IgniteCheckedException {
-
-            Collection<GridH2Row> rows;
-
-            if (lower == null && upper == null)
-                rows = tree.values();
-            else if (lower != null && upper == null)
-                rows = tree.tailMap(lower).values();
-            else if (lower == null)
-                rows = tree.headMap(upper).values();
-            else
-                rows = tree.subMap(lower, false, upper, false).values();
-
-            return new GridCursorIteratorWrapper<>(rows.iterator());
-        }
-
-        /** {@inheritDoc} */
-        @Override public GridH2Row findFirst() throws IgniteCheckedException {
-            Map.Entry<GridSearchRowPointer, GridH2Row> first = tree.firstEntry();
-            return (first == null) ? null : first.getValue();
-        }
-
-        /** {@inheritDoc} */
-        @Override public GridH2Row findLast() throws IgniteCheckedException {
-            Map.Entry<GridSearchRowPointer, GridH2Row> last = tree.lastEntry();
-            return (last == null) ? null : last.getValue();
-        }
-
-        /** {@inheritDoc} */
-        @Override public GridH2Row remove(GridSearchRowPointer key) {
-            return tree.remove(key);
-        }
-
-        /** {@inheritDoc} */
-        @Override public long size() {
-            return tree.size();
-        }
-
-        /** {@inheritDoc} */
-        @Override public IgniteNavigableMapTree clone() {
-            IgniteNavigableMapTree cp;
-
-            try {
-                cp = (IgniteNavigableMapTree)super.clone();
-            }
-            catch (final CloneNotSupportedException e) {
-                throw DbException.convert(e);
-            }
-
-            return new IgniteNavigableMapTree(cp.tree);
-        }
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/ebed404b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
index 19b628b..e717367 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
@@ -26,7 +26,6 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 import java.util.UUID;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentMap;
@@ -59,7 +58,6 @@ import org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing;
 import org.apache.ignite.internal.processors.query.h2.opt.DistributedJoinMode;
 import org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryContext;
 import org.apache.ignite.internal.processors.query.h2.opt.GridH2RetryException;
-import org.apache.ignite.internal.processors.query.h2.opt.GridH2Table;
 import org.apache.ignite.internal.processors.query.h2.twostep.messages.GridQueryCancelRequest;
 import org.apache.ignite.internal.processors.query.h2.twostep.messages.GridQueryFailResponse;
 import org.apache.ignite.internal.processors.query.h2.twostep.messages.GridQueryNextPageRequest;
@@ -545,22 +543,6 @@ public class GridMapQueryExecutor {
                 .topologyVersion(topVer)
                 .reservations(reserved);
 
-            List<GridH2Table> snapshotedTbls = null;
-
-            if (!F.isEmpty(tbls)) {
-                snapshotedTbls = new ArrayList<>(tbls.size());
-
-                for (QueryTable tbl : tbls) {
-                    GridH2Table h2Tbl = h2.dataTable(tbl);
-
-                    Objects.requireNonNull(h2Tbl, tbl.toString());
-
-                    h2Tbl.snapshotIndexes(qctx, segmentId);
-
-                    snapshotedTbls.add(h2Tbl);
-                }
-            }
-
             Connection conn = h2.connectionForSchema(schemaName);
 
             H2Utils.setupConnection(conn, distributedJoinMode != OFF, enforceJoinOrder);
@@ -596,8 +578,6 @@ public class GridMapQueryExecutor {
                             qr.queryCancel(qryIdx));
 
                         if (evt) {
-                            assert mainCctx != null;
-
                             ctx.event().record(new CacheQueryExecutedEvent<>(
                                 node,
                                 "SQL query executed.",
@@ -635,11 +615,6 @@ public class GridMapQueryExecutor {
 
                 if (distributedJoinMode == OFF)
                     qctx.clearContext(false);
-
-                if (!F.isEmpty(snapshotedTbls)) {
-                    for (GridH2Table dataTbl : snapshotedTbls)
-                        dataTbl.releaseSnapshots();
-                }
             }
         }
         catch (Throwable e) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/ebed404b/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 88ff61e..a1a64e8 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
@@ -18,38 +18,20 @@
 package org.apache.ignite.internal.processors.query.h2.opt;
 
 import java.sql.Connection;
-import java.sql.DriverManager;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.HashSet;
 import java.util.Random;
-import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.Callable;
 import java.util.concurrent.atomic.AtomicInteger;
-import org.apache.ignite.IgniteCheckedException;
-import org.apache.ignite.internal.processors.query.h2.database.H2PkHashIndex;
-import org.apache.ignite.internal.processors.query.h2.database.H2RowFactory;
-import org.apache.ignite.internal.util.lang.GridCursor;
-import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
-import org.h2.Driver;
-import org.h2.index.Cursor;
-import org.h2.index.Index;
-import org.h2.result.Row;
-import org.h2.result.SearchRow;
-import org.h2.result.SortOrder;
-import org.h2.table.IndexColumn;
 import org.h2.value.ValueLong;
 import org.h2.value.ValueString;
 import org.h2.value.ValueTimestamp;
 import org.h2.value.ValueUuid;
-import org.jetbrains.annotations.Nullable;
 
 /**
  * Tests H2 Table.
@@ -173,47 +155,6 @@ public class GridH2TableSelfTest extends GridCommonAbstractTest {
             assertEquals(MAX_X, idx.getRowCount(null));
         }
 
-        // Check correct rows order.
-        checkOrdered((GridH2TreeIndex)tbl.indexes().get(0), new Comparator<SearchRow>() {
-            @Override public int compare(SearchRow o1, SearchRow o2) {
-                UUID id1 = (UUID)o1.getValue(0).getObject();
-                UUID id2 = (UUID)o2.getValue(0).getObject();
-
-                return id1.compareTo(id2);
-            }
-        });
-
-        checkOrdered((GridH2TreeIndex)tbl.indexes().get(1), new Comparator<SearchRow>() {
-            @Override public int compare(SearchRow o1, SearchRow o2) {
-                Long x1 = (Long)o1.getValue(3).getObject();
-                Long x2 = (Long)o2.getValue(3).getObject();
-
-                int c = x2.compareTo(x1);
-
-                if (c != 0)
-                    return c;
-
-                Timestamp t1 = (Timestamp)o1.getValue(1).getObject();
-                Timestamp t2 = (Timestamp)o2.getValue(1).getObject();
-
-                return t1.compareTo(t2);
-            }
-        });
-
-        checkOrdered((GridH2TreeIndex)tbl.indexes().get(2), new Comparator<SearchRow>() {
-            @Override public int compare(SearchRow o1, SearchRow o2) {
-                String s1 = (String)o1.getValue(2).getObject();
-                String s2 = (String)o2.getValue(2).getObject();
-
-                return s2.compareTo(s1);
-            }
-        });
-
-        // Indexes data consistency.
-        ArrayList<? extends Index> idxs = tbl.indexes();
-
-        checkIndexesConsistent((ArrayList<Index>)idxs, null);
-
         // Check unique index.
         UUID id = UUID.randomUUID();
         UUID id2 = UUID.randomUUID();
@@ -405,54 +346,6 @@ public class GridH2TableSelfTest extends GridCommonAbstractTest {
 
 
     /**
-     * @throws Exception If failed.
-     */
-    public void testIndexFindFirstOrLast() throws Exception {
-        Index index = tbl.getIndexes().get(2);
-        assertTrue(index instanceof GridH2TreeIndex);
-        assertTrue(index.canGetFirstOrLast());
-
-        //find first on empty data
-        Cursor cursor = index.findFirstOrLast(null, true);
-        assertFalse(cursor.next());
-        assertNull(cursor.get());
-
-        //find last on empty data
-        cursor = index.findFirstOrLast(null, false);
-        assertFalse(cursor.next());
-        assertNull(cursor.get());
-
-        //fill with data
-        int rows = 100;
-        long t = System.currentTimeMillis();
-        Random rnd = new Random();
-        UUID min = null;
-        UUID max = null;
-
-        for (int i = 0 ; i < rows; i++) {
-            UUID id = UUID.randomUUID();
-            if (min == null || id.compareTo(min) < 0)
-                min = id;
-            if (max == null || id.compareTo(max) > 0)
-                max = id;
-            GridH2Row row = row(id, t++, id.toString(), rnd.nextInt(100));
-            ((GridH2TreeIndex)index).put(row);
-        }
-
-        //find first
-        cursor = index.findFirstOrLast(null, true);
-        assertTrue(cursor.next());
-        assertEquals(min, cursor.get().getValue(0).getObject());
-        assertFalse(cursor.next());
-
-        //find last
-        cursor = index.findFirstOrLast(null, false);
-        assertTrue(cursor.next());
-        assertEquals(max, cursor.get().getValue(0).getObject());
-        assertFalse(cursor.next());
-    }
-
-    /**
      * Check query plan to correctly select index.
      *
      * @param conn Connection.
@@ -473,69 +366,4 @@ public class GridH2TableSelfTest extends GridCommonAbstractTest {
             }
         }
     }
-
-    /**
-     * @param idxs Indexes.
-     * @param rowSet Rows.
-     * @return Rows.
-     */
-    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<>();
-
-            GridCursor<GridH2Row> cursor = ((GridH2TreeIndex)idx).rows();
-
-            while(cursor.next())
-                assertTrue(set.add(cursor.get()));
-
-            //((GridH2SnapTreeSet)((GridH2Index)idx).tree).print();
-
-            if (rowSet == null || rowSet.isEmpty())
-                rowSet = set;
-            else
-                assertEquals(rowSet, set);
-        }
-
-        return rowSet;
-    }
-
-    /**
-     * @param idxs Indexes list.
-     */
-    private void checkOrdered(ArrayList<Index> idxs) throws IgniteCheckedException {
-        for (Index idx : idxs) {
-            if (!(idx instanceof GridH2TreeIndex))
-                continue;
-
-            GridH2TreeIndex h2Idx = (GridH2TreeIndex)idx;
-
-            checkOrdered(h2Idx, h2Idx);
-        }
-    }
-
-    /**
-     * @param idx Index.
-     * @param cmp Comparator.
-     */
-    private void checkOrdered(GridH2TreeIndex idx, Comparator<? super GridH2Row> cmp) throws IgniteCheckedException {
-        GridCursor<GridH2Row> cursor = idx.rows();
-
-        GridH2Row min = null;
-
-        while (cursor.next()) {
-            GridH2Row row = cursor.get();
-
-            System.out.println(row);
-
-            assertNotNull(row);
-
-            assertFalse("Incorrect row order in index: " + idx + "\n min: " + min + "\n row: " + row,
-                min != null && cmp.compare(min, row) > 0);
-
-            min = row;
-        }
-    }
 }
\ No newline at end of file


[27/30] ignite git commit: IGNITE-5961 - Align pages in LFS partition files to pageSize

Posted by ag...@apache.org.
IGNITE-5961 - Align pages in LFS partition files to pageSize


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/3919d803
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/3919d803
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/3919d803

Branch: refs/heads/ignite-5872
Commit: 3919d8035fb172e1546f7a3ecea0f29f8e1e2214
Parents: b5ad729
Author: Ivan Rakov <iv...@gmail.com>
Authored: Thu Aug 10 13:31:23 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Thu Aug 10 13:31:23 2017 +0300

----------------------------------------------------------------------
 .../internal/pagemem/store/PageStore.java       |   5 +
 .../cache/persistence/file/FilePageStore.java   |  54 ++++++---
 .../persistence/file/FilePageStoreFactory.java  |  35 ++++++
 .../persistence/file/FilePageStoreManager.java  |  17 +--
 .../cache/persistence/file/FilePageStoreV2.java |  53 +++++++++
 .../file/FileVersionCheckingFactory.java        | 116 +++++++++++++++++++
 ...gnitePdsRecoveryAfterFileCorruptionTest.java |   2 +-
 7 files changed, 251 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/3919d803/modules/core/src/main/java/org/apache/ignite/internal/pagemem/store/PageStore.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/store/PageStore.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/store/PageStore.java
index 4698a6b..f6e577c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/store/PageStore.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/store/PageStore.java
@@ -95,4 +95,9 @@ public interface PageStore {
      * @throws IgniteCheckedException If sync failed (IO error occurred).
      */
     public void ensure() throws IgniteCheckedException;
+
+    /**
+     * @return Page store version.
+     */
+    public int version();
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/3919d803/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStore.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStore.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStore.java
index a7ca13c..7fe1ffe 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStore.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStore.java
@@ -45,10 +45,10 @@ public class FilePageStore implements PageStore {
     private static final long SIGNATURE = 0xF19AC4FE60C530B8L;
 
     /** File version. */
-    private static final int VERSION = 1;
+    public static final int VERSION = 1;
 
     /** Allocated field offset. */
-    public static final int HEADER_SIZE = 8/*SIGNATURE*/ + 4/*VERSION*/ + 1/*type*/ + 4/*page size*/;
+    static final int HEADER_SIZE = 8/*SIGNATURE*/ + 4/*VERSION*/ + 1/*type*/ + 4/*page size*/;
 
     /** */
     private final File cfgFile;
@@ -57,7 +57,7 @@ public class FilePageStore implements PageStore {
     private final byte type;
 
     /** Database configuration. */
-    private final MemoryConfiguration dbCfg;
+    protected final MemoryConfiguration dbCfg;
 
     /** Factory to provide I/O interfaces for read/write operations with files */
     private final FileIOFactory ioFactory;
@@ -103,20 +103,36 @@ public class FilePageStore implements PageStore {
 
     /** {@inheritDoc} */
     @Override public boolean exists() {
-        return cfgFile.exists() && cfgFile.length() > HEADER_SIZE;
+        return cfgFile.exists() && cfgFile.length() > headerSize();
     }
 
     /**
+     * Size of page store header.
+     */
+    public int headerSize() {
+        return HEADER_SIZE;
+    }
+
+    /**
+     * Page store version.
+     */
+    public int version() {
+        return VERSION;
+    }
+
+    /**
+     * Creates header for current version file store. Doesn't init the store.
+     *
      * @param type Type.
      * @param pageSize Page size.
      * @return Byte buffer instance.
      */
-    public static ByteBuffer header(byte type, int pageSize) {
-        ByteBuffer hdr = ByteBuffer.allocate(HEADER_SIZE).order(ByteOrder.LITTLE_ENDIAN);
+    public ByteBuffer header(byte type, int pageSize) {
+        ByteBuffer hdr = ByteBuffer.allocate(headerSize()).order(ByteOrder.LITTLE_ENDIAN);
 
         hdr.putLong(SIGNATURE);
 
-        hdr.putInt(VERSION);
+        hdr.putInt(version());
 
         hdr.put(type);
 
@@ -142,7 +158,7 @@ public class FilePageStore implements PageStore {
         }
 
         //there is 'super' page in every file
-        return HEADER_SIZE + dbCfg.getPageSize();
+        return headerSize() + dbCfg.getPageSize();
     }
 
     /**
@@ -150,7 +166,7 @@ public class FilePageStore implements PageStore {
      */
     private long checkFile() throws IgniteCheckedException {
         try {
-            ByteBuffer hdr = ByteBuffer.allocate(HEADER_SIZE).order(ByteOrder.LITTLE_ENDIAN);
+            ByteBuffer hdr = ByteBuffer.allocate(headerSize()).order(ByteOrder.LITTLE_ENDIAN);
 
             while (hdr.remaining() > 0)
                 fileIO.read(hdr);
@@ -166,9 +182,9 @@ public class FilePageStore implements PageStore {
 
             int ver = hdr.getInt();
 
-            if (VERSION != ver)
+            if (version() != ver)
                 throw new IgniteCheckedException("Failed to verify store file (invalid file version)" +
-                    " [expectedVersion=" + VERSION +
+                    " [expectedVersion=" + version() +
                     ", fileVersion=" + ver + "]");
 
             byte type = hdr.get();
@@ -187,10 +203,10 @@ public class FilePageStore implements PageStore {
 
             long fileSize = cfgFile.length();
 
-            if (fileSize == HEADER_SIZE) // Every file has a special meta page.
-                fileSize = pageSize + HEADER_SIZE;
+            if (fileSize == headerSize()) // Every file has a special meta page.
+                fileSize = pageSize + headerSize();
 
-            if ((fileSize - HEADER_SIZE) % pageSize != 0)
+            if ((fileSize - headerSize()) % pageSize != 0)
                 throw new IgniteCheckedException("Failed to verify store file (invalid file size)" +
                     " [fileSize=" + U.hexLong(fileSize) +
                     ", pageSize=" + U.hexLong(pageSize) + ']');
@@ -346,9 +362,9 @@ public class FilePageStore implements PageStore {
         init();
 
         try {
-            assert buf.remaining() == HEADER_SIZE;
+            assert buf.remaining() == headerSize();
 
-            int len = HEADER_SIZE;
+            int len = headerSize();
 
             long off = 0;
 
@@ -425,7 +441,7 @@ public class FilePageStore implements PageStore {
 
             long off = pageOffset(pageId);
 
-            assert (off >= 0 && off + pageSize <= allocated.get() + HEADER_SIZE) || recover :
+            assert (off >= 0 && off + pageSize <= allocated.get() + headerSize()) || recover :
                 "off=" + U.hexLong(off) + ", allocated=" + U.hexLong(allocated.get()) + ", pageId=" + U.hexLong(pageId);
 
             assert pageBuf.capacity() == pageSize;
@@ -463,7 +479,7 @@ public class FilePageStore implements PageStore {
 
     /** {@inheritDoc} */
     @Override public long pageOffset(long pageId) {
-        return (long) PageIdUtils.pageIndex(pageId) * pageSize + HEADER_SIZE;
+        return (long) PageIdUtils.pageIndex(pageId) * pageSize + headerSize();
     }
 
     /** {@inheritDoc} */
@@ -494,7 +510,7 @@ public class FilePageStore implements PageStore {
 
         long off = allocPage();
 
-        return off / pageSize;
+        return (off - headerSize()) / pageSize;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/3919d803/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreFactory.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreFactory.java
new file mode 100644
index 0000000..d97ab26
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreFactory.java
@@ -0,0 +1,35 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License.  You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package org.apache.ignite.internal.processors.cache.persistence.file;
+
+import java.io.File;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.pagemem.PageIdAllocator;
+
+/**
+ *
+ */
+public interface FilePageStoreFactory {
+    /**
+     * Creates instance of FilePageStore based on given file.
+     *
+     * @param type Data type, can be {@link PageIdAllocator#FLAG_IDX} or {@link PageIdAllocator#FLAG_DATA}.
+     * @param file File Page store file.
+     */
+    public FilePageStore createPageStore(byte type, File file) throws IgniteCheckedException;
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3919d803/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java
index e2ad070..0041ea6 100755
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java
@@ -365,21 +365,16 @@ public class FilePageStoreManager extends GridCacheSharedManagerAdapter implemen
         if (dirExisted && !idxFile.exists())
             grpsWithoutIdx.add(grpDesc.groupId());
 
-        FilePageStore idxStore = new FilePageStore(
-            PageMemory.FLAG_IDX,
-            idxFile,
-            pstCfg.getFileIOFactory(),
-            cctx.kernalContext().config().getMemoryConfiguration());
+        FileVersionCheckingFactory pageStoreFactory = new FileVersionCheckingFactory(
+            pstCfg.getFileIOFactory(), igniteCfg.getMemoryConfiguration());
+
+        FilePageStore idxStore = pageStoreFactory.createPageStore(PageMemory.FLAG_IDX, idxFile);
 
         FilePageStore[] partStores = new FilePageStore[grpDesc.config().getAffinity().partitions()];
 
         for (int partId = 0; partId < partStores.length; partId++) {
-            FilePageStore partStore = new FilePageStore(
-                PageMemory.FLAG_DATA,
-                new File(cacheWorkDir, String.format(PART_FILE_TEMPLATE, partId)),
-                pstCfg.getFileIOFactory(),
-                cctx.kernalContext().config().getMemoryConfiguration()
-            );
+            FilePageStore partStore = pageStoreFactory.createPageStore(
+                PageMemory.FLAG_DATA, new File(cacheWorkDir, String.format(PART_FILE_TEMPLATE, partId)));
 
             partStores[partId] = partStore;
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/3919d803/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreV2.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreV2.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreV2.java
new file mode 100644
index 0000000..5d044ec
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreV2.java
@@ -0,0 +1,53 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License.  You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.apache.ignite.internal.processors.cache.persistence.file;
+
+import java.io.File;
+import org.apache.ignite.configuration.MemoryConfiguration;
+
+/**
+ *
+ */
+public class FilePageStoreV2 extends FilePageStore {
+    /** File version. */
+    public static final int VERSION = 2;
+
+    /** Header size. */
+    private final int hdrSize;
+
+    /**
+     * @param type Type.
+     * @param file File.
+     * @param factory Factory.
+     * @param cfg Config.
+     */
+    public FilePageStoreV2(byte type, File file, FileIOFactory factory, MemoryConfiguration cfg) {
+        super(type, file, factory, cfg);
+
+        hdrSize = cfg.getPageSize();
+    }
+
+    /** {@inheritDoc} */
+    @Override public int headerSize() {
+        return hdrSize;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int version() {
+        return VERSION;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3919d803/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FileVersionCheckingFactory.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FileVersionCheckingFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FileVersionCheckingFactory.java
new file mode 100644
index 0000000..53bd802
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FileVersionCheckingFactory.java
@@ -0,0 +1,116 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+* the License.  You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package org.apache.ignite.internal.processors.cache.persistence.file;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.configuration.MemoryConfiguration;
+
+/**
+ * Checks version in files if it's present on the disk, creates store with latest version otherwise.
+ */
+public class FileVersionCheckingFactory implements FilePageStoreFactory {
+    /** Property to override latest version. Should be used only in tests. */
+    public static final String LATEST_VERSION_OVERRIDE_PROPERTY = "file.page.store.latest.version.override";
+
+    /** Latest page store version. */
+    public final static int LATEST_VERSION = 2;
+
+    /** Factory to provide I/O interfaces for read/write operations with files. */
+    private final FileIOFactory fileIOFactory;
+
+    /** Memory configuration. */
+    private final MemoryConfiguration memCfg;
+
+    /**
+     * @param fileIOFactory File io factory.
+     * @param memCfg Memory configuration.
+     */
+    public FileVersionCheckingFactory(
+        FileIOFactory fileIOFactory, MemoryConfiguration memCfg) {
+        this.fileIOFactory = fileIOFactory;
+        this.memCfg = memCfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override public FilePageStore createPageStore(byte type, File file) throws IgniteCheckedException {
+        if (!file.exists())
+            return createPageStore(type, file, latestVersion());
+
+        try (FileIO fileIO = fileIOFactory.create(file, "r")) {
+            int minHdr = FilePageStore.HEADER_SIZE;
+
+            if (fileIO.size() < minHdr)
+                return createPageStore(type, file, latestVersion());
+
+            ByteBuffer hdr = ByteBuffer.allocate(minHdr).order(ByteOrder.LITTLE_ENDIAN);
+
+            while (hdr.remaining() > 0)
+                fileIO.read(hdr);
+
+            hdr.rewind();
+
+            hdr.getLong(); // Read signature
+
+            int ver = hdr.getInt();
+
+            return createPageStore(type, file, ver);
+        }
+        catch (IOException e) {
+            throw new IgniteCheckedException("Error while creating file page store [file=" + file + "]:", e);
+        }
+    }
+
+    /**
+     * Resolves latest page store version.
+     */
+    public int latestVersion() {
+        int latestVer = LATEST_VERSION;
+
+        try {
+            latestVer = Integer.parseInt(System.getProperty(LATEST_VERSION_OVERRIDE_PROPERTY));
+        } catch (NumberFormatException e) {
+            // No override.
+        }
+
+        return latestVer;
+    }
+
+    /**
+     * Instantiates specific version of FilePageStore.
+     *
+     * @param type Type.
+     * @param file File.
+     * @param ver Version.
+     */
+    public FilePageStore createPageStore(byte type, File file, int ver) throws IgniteCheckedException {
+        switch (ver) {
+            case FilePageStore.VERSION:
+                return new FilePageStore(type, file, fileIOFactory, memCfg);
+
+            case FilePageStoreV2.VERSION:
+                return new FilePageStoreV2(type, file, fileIOFactory, memCfg);
+
+            default:
+                throw new IllegalArgumentException("Unknown version of file page store: " + ver);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/3919d803/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsRecoveryAfterFileCorruptionTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsRecoveryAfterFileCorruptionTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsRecoveryAfterFileCorruptionTest.java
index c248c35..11d5eef 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsRecoveryAfterFileCorruptionTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/IgnitePdsRecoveryAfterFileCorruptionTest.java
@@ -194,7 +194,7 @@ public class IgnitePdsRecoveryAfterFileCorruptionTest extends GridCommonAbstract
 
         long size = fileIO.size();
 
-        fileIO.write(ByteBuffer.allocate((int)size - FilePageStore.HEADER_SIZE), FilePageStore.HEADER_SIZE);
+        fileIO.write(ByteBuffer.allocate((int)size - filePageStore.headerSize()), filePageStore.headerSize());
 
         fileIO.force();
     }


[28/30] ignite git commit: IGNITE-5995: ODBC fix for SQLGetData.

Posted by ag...@apache.org.
IGNITE-5995: ODBC fix for SQLGetData.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/0d8d166b
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/0d8d166b
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/0d8d166b

Branch: refs/heads/ignite-5872
Commit: 0d8d166b77d37f8740f3e9dd0637c336b77b0c8f
Parents: 3919d80
Author: Igor Sapego <is...@gridgain.com>
Authored: Thu Aug 10 15:31:44 2017 +0300
Committer: Igor Sapego <is...@gridgain.com>
Committed: Thu Aug 10 15:31:44 2017 +0300

----------------------------------------------------------------------
 .../impl/cache/query/query_fields_row_impl.h    |   2 +-
 .../cpp/odbc-test/include/test_utils.h          |   9 ++
 .../cpp/odbc-test/src/meta_queries_test.cpp     | 100 +++++++++++++++++++
 .../platforms/cpp/odbc-test/src/test_utils.cpp  |  13 +++
 .../ignite/odbc/query/column_metadata_query.h   |   3 +
 .../ignite/odbc/query/table_metadata_query.h    |   3 +
 .../include/ignite/odbc/query/type_info_query.h |   3 +
 .../cpp/odbc/src/query/batch_query.cpp          |   7 +-
 .../odbc/src/query/column_metadata_query.cpp    |  16 ++-
 .../platforms/cpp/odbc/src/query/data_query.cpp |   7 +-
 .../cpp/odbc/src/query/table_metadata_query.cpp |  16 ++-
 .../cpp/odbc/src/query/type_info_query.cpp      |  16 ++-
 12 files changed, 183 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/0d8d166b/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_fields_row_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_fields_row_impl.h b/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_fields_row_impl.h
index 63e0523..2943625 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_fields_row_impl.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_fields_row_impl.h
@@ -143,7 +143,7 @@ namespace ignite
 
                             int32_t actualLen = reader.ReadInt8Array(dst, len);
 
-                            if (actualLen == 0 || dst && len >= actualLen)
+                            if (actualLen == 0 || (dst && len >= actualLen))
                                 ++processed;
 
                             return actualLen;

http://git-wip-us.apache.org/repos/asf/ignite/blob/0d8d166b/modules/platforms/cpp/odbc-test/include/test_utils.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/include/test_utils.h b/modules/platforms/cpp/odbc-test/include/test_utils.h
index 6a58e54..5dc6d6e 100644
--- a/modules/platforms/cpp/odbc-test/include/test_utils.h
+++ b/modules/platforms/cpp/odbc-test/include/test_utils.h
@@ -43,6 +43,15 @@ namespace ignite_test
     enum { ODBC_BUFFER_SIZE = 1024 };
 
     /**
+     * Extract error state.
+     *
+     * @param handleType Type of the handle.
+     * @param handle Handle.
+     * @return Error state.
+     */
+    std::string GetOdbcErrorState(SQLSMALLINT handleType, SQLHANDLE handle);
+
+    /**
      * Extract error message.
      *
      * @param handleType Type of the handle.

http://git-wip-us.apache.org/repos/asf/ignite/blob/0d8d166b/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp b/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
index 454a989..ff3695d 100644
--- a/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
@@ -103,6 +103,9 @@ struct MetaQueriesTestSuiteFixture
         BOOST_REQUIRE(stmt != NULL);
     }
 
+    /**
+     * Disconnect.
+     */
     void Disconnect()
     {
         // Releasing statement handle.
@@ -116,6 +119,11 @@ struct MetaQueriesTestSuiteFixture
         SQLFreeHandle(SQL_HANDLE_ENV, env);
     }
 
+    /**
+     * Start additional node with the specified name.
+     *
+     * @param name Node name.
+     */
     static Ignite StartAdditionalNode(const char* name)
     {
 #ifdef IGNITE_TESTS_32
@@ -126,6 +134,36 @@ struct MetaQueriesTestSuiteFixture
     }
 
     /**
+     * Checks single row result set for correct work with SQLGetData.
+     *
+     * @param stmt Statement.
+     */
+    void CheckSingleRowResultSetWithGetData(SQLHSTMT stmt)
+    {
+        SQLRETURN ret = SQLFetch(stmt);
+
+        if (!SQL_SUCCEEDED(ret))
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        char buf[1024];
+        SQLLEN bufLen = sizeof(buf);
+
+        ret = SQLGetData(stmt, 1, SQL_C_CHAR, buf, sizeof(buf), &bufLen);
+
+        if (!SQL_SUCCEEDED(ret))
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+        ret = SQLFetch(stmt);
+
+        BOOST_REQUIRE_EQUAL(ret, SQL_NO_DATA);
+
+        ret = SQLGetData(stmt, 1, SQL_C_CHAR, buf, sizeof(buf), &bufLen);
+
+        BOOST_REQUIRE_EQUAL(ret, SQL_ERROR);
+        BOOST_CHECK_EQUAL(GetOdbcErrorState(SQL_HANDLE_STMT, stmt), "24000");
+    }
+
+    /**
      * Constructor.
      */
     MetaQueriesTestSuiteFixture() :
@@ -237,4 +275,66 @@ BOOST_AUTO_TEST_CASE(TestColAttributesColumnScale)
         BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
 }
 
+BOOST_AUTO_TEST_CASE(TestGetDataWithGetTypeInfo)
+{
+    Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
+
+    SQLRETURN ret = SQLGetTypeInfo(stmt, SQL_VARCHAR);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    CheckSingleRowResultSetWithGetData(stmt);
+}
+
+BOOST_AUTO_TEST_CASE(TestGetDataWithTables)
+{
+    Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
+
+    SQLCHAR empty[] = "";
+    SQLCHAR table[] = "TestType";
+
+    SQLRETURN ret = SQLTables(stmt, empty, SQL_NTS, empty, SQL_NTS, table, SQL_NTS, empty, SQL_NTS);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    CheckSingleRowResultSetWithGetData(stmt);
+}
+
+BOOST_AUTO_TEST_CASE(TestGetDataWithColumns)
+{
+    Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
+
+    SQLCHAR empty[] = "";
+    SQLCHAR table[] = "TestType";
+    SQLCHAR column[] = "strField";
+
+    SQLRETURN ret = SQLColumns(stmt, empty, SQL_NTS, empty, SQL_NTS, table, SQL_NTS, column, SQL_NTS);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    CheckSingleRowResultSetWithGetData(stmt);
+}
+
+BOOST_AUTO_TEST_CASE(TestGetDataWithSelectQuery)
+{
+    Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
+
+    SQLCHAR insertReq[] = "insert into TestType(_key, strField) VALUES(1, 'Lorem ipsum')";
+    SQLRETURN ret = SQLExecDirect(stmt, insertReq, SQL_NTS);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    SQLCHAR selectReq[] = "select strField from TestType";
+    ret = SQLExecDirect(stmt, selectReq, SQL_NTS);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+
+    CheckSingleRowResultSetWithGetData(stmt);
+}
+
 BOOST_AUTO_TEST_SUITE_END()

http://git-wip-us.apache.org/repos/asf/ignite/blob/0d8d166b/modules/platforms/cpp/odbc-test/src/test_utils.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/test_utils.cpp b/modules/platforms/cpp/odbc-test/src/test_utils.cpp
index c7aa70a..6e8fe6a 100644
--- a/modules/platforms/cpp/odbc-test/src/test_utils.cpp
+++ b/modules/platforms/cpp/odbc-test/src/test_utils.cpp
@@ -21,6 +21,19 @@
 
 namespace ignite_test
 {
+    std::string GetOdbcErrorState(SQLSMALLINT handleType, SQLHANDLE handle)
+    {
+        SQLCHAR sqlstate[7] = {};
+        SQLINTEGER nativeCode;
+
+        SQLCHAR message[ODBC_BUFFER_SIZE];
+        SQLSMALLINT reallen = 0;
+
+        SQLGetDiagRec(handleType, handle, 1, sqlstate, &nativeCode, message, ODBC_BUFFER_SIZE, &reallen);
+
+        return std::string(reinterpret_cast<char*>(sqlstate));
+    }
+
     std::string GetOdbcErrorMessage(SQLSMALLINT handleType, SQLHANDLE handle)
     {
         SQLCHAR sqlstate[7] = {};

http://git-wip-us.apache.org/repos/asf/ignite/blob/0d8d166b/modules/platforms/cpp/odbc/include/ignite/odbc/query/column_metadata_query.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/query/column_metadata_query.h b/modules/platforms/cpp/odbc/include/ignite/odbc/query/column_metadata_query.h
index 878a4be..875b1ce 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/query/column_metadata_query.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/query/column_metadata_query.h
@@ -130,6 +130,9 @@ namespace ignite
                 /** Query executed. */
                 bool executed;
 
+                /** Fetched flag. */
+                bool fetched;
+
                 /** Fetched metadata. */
                 meta::ColumnMetaVector meta;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/0d8d166b/modules/platforms/cpp/odbc/include/ignite/odbc/query/table_metadata_query.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/query/table_metadata_query.h b/modules/platforms/cpp/odbc/include/ignite/odbc/query/table_metadata_query.h
index cef963c..acd3f49 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/query/table_metadata_query.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/query/table_metadata_query.h
@@ -134,6 +134,9 @@ namespace ignite
                 /** Query executed. */
                 bool executed;
 
+                /** Fetched flag. */
+                bool fetched;
+
                 /** Fetched metadata. */
                 meta::TableMetaVector meta;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/0d8d166b/modules/platforms/cpp/odbc/include/ignite/odbc/query/type_info_query.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/query/type_info_query.h b/modules/platforms/cpp/odbc/include/ignite/odbc/query/type_info_query.h
index a7cee92..00cca08 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/query/type_info_query.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/query/type_info_query.h
@@ -105,6 +105,9 @@ namespace ignite
                 /** Executed flag. */
                 bool executed;
 
+                /** Fetched flag. */
+                bool fetched;
+
                 /** Requested types. */
                 std::vector<int8_t> types;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/0d8d166b/modules/platforms/cpp/odbc/src/query/batch_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/batch_query.cpp b/modules/platforms/cpp/odbc/src/query/batch_query.cpp
index df9fb05..46447c0 100644
--- a/modules/platforms/cpp/odbc/src/query/batch_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/batch_query.cpp
@@ -112,7 +112,12 @@ namespace ignite
                 }
 
                 if (dataRetrieved)
-                    return SqlResult::AI_NO_DATA;
+                {
+                    diag.AddStatusRecord(SqlState::S24000_INVALID_CURSOR_STATE,
+                        "Cursor has reached end of the result set.");
+
+                    return SqlResult::AI_ERROR;
+                }
 
                 if (columnIdx != 1)
                 {

http://git-wip-us.apache.org/repos/asf/ignite/blob/0d8d166b/modules/platforms/cpp/odbc/src/query/column_metadata_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/column_metadata_query.cpp b/modules/platforms/cpp/odbc/src/query/column_metadata_query.cpp
index 8ba9323..b9c08f5 100644
--- a/modules/platforms/cpp/odbc/src/query/column_metadata_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/column_metadata_query.cpp
@@ -83,6 +83,7 @@ namespace ignite
                 table(table),
                 column(column),
                 executed(false),
+                fetched(false),
                 meta(),
                 columnsMeta()
             {
@@ -125,6 +126,7 @@ namespace ignite
                 if (result == SqlResult::AI_SUCCESS)
                 {
                     executed = true;
+                    fetched = false;
 
                     cursor = meta.begin();
                 }
@@ -146,6 +148,11 @@ namespace ignite
                     return SqlResult::AI_ERROR;
                 }
 
+                if (!fetched)
+                    fetched = true;
+                else
+                    ++cursor;
+
                 if (cursor == meta.end())
                     return SqlResult::AI_NO_DATA;
 
@@ -154,8 +161,6 @@ namespace ignite
                 for (it = columnBindings.begin(); it != columnBindings.end(); ++it)
                     GetColumn(it->first, it->second);
 
-                ++cursor;
-
                 return SqlResult::AI_SUCCESS;
             }
 
@@ -169,7 +174,12 @@ namespace ignite
                 }
 
                 if (cursor == meta.end())
-                    return SqlResult::AI_NO_DATA;
+                {
+                    diag.AddStatusRecord(SqlState::S24000_INVALID_CURSOR_STATE,
+                        "Cursor has reached end of the result set.");
+
+                    return SqlResult::AI_ERROR;
+                }
 
                 const meta::ColumnMeta& currentColumn = *cursor;
                 uint8_t columnType = currentColumn.GetDataType();

http://git-wip-us.apache.org/repos/asf/ignite/blob/0d8d166b/modules/platforms/cpp/odbc/src/query/data_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/data_query.cpp b/modules/platforms/cpp/odbc/src/query/data_query.cpp
index 23d5240..f14d004 100644
--- a/modules/platforms/cpp/odbc/src/query/data_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/data_query.cpp
@@ -125,7 +125,12 @@ namespace ignite
                 Row* row = cursor->GetRow();
 
                 if (!row)
-                    return SqlResult::AI_NO_DATA;
+                {
+                    diag.AddStatusRecord(SqlState::S24000_INVALID_CURSOR_STATE,
+                        "Cursor has reached end of the result set.");
+
+                    return SqlResult::AI_ERROR;
+                }
 
                 SqlResult::Type result = row->ReadColumnToBuffer(columnIdx, buffer);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/0d8d166b/modules/platforms/cpp/odbc/src/query/table_metadata_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/table_metadata_query.cpp b/modules/platforms/cpp/odbc/src/query/table_metadata_query.cpp
index 401a1d2..e66b281 100644
--- a/modules/platforms/cpp/odbc/src/query/table_metadata_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/table_metadata_query.cpp
@@ -63,6 +63,7 @@ namespace ignite
                 table(table),
                 tableType(tableType),
                 executed(false),
+                fetched(false),
                 meta(),
                 columnsMeta()
             {
@@ -98,6 +99,7 @@ namespace ignite
                 if (result == SqlResult::AI_SUCCESS)
                 {
                     executed = true;
+                    fetched = false;
 
                     cursor = meta.begin();
                 }
@@ -119,6 +121,11 @@ namespace ignite
                     return SqlResult::AI_ERROR;
                 }
 
+                if (!fetched)
+                    fetched = true;
+                else
+                    ++cursor;
+
                 if (cursor == meta.end())
                     return SqlResult::AI_NO_DATA;
 
@@ -127,8 +134,6 @@ namespace ignite
                 for (it = columnBindings.begin(); it != columnBindings.end(); ++it)
                     GetColumn(it->first, it->second);
 
-                ++cursor;
-
                 return SqlResult::AI_SUCCESS;
             }
 
@@ -142,7 +147,12 @@ namespace ignite
                 }
 
                 if (cursor == meta.end())
-                    return SqlResult::AI_NO_DATA;
+                {
+                    diag.AddStatusRecord(SqlState::S24000_INVALID_CURSOR_STATE,
+                        "Cursor has reached end of the result set.");
+
+                    return SqlResult::AI_ERROR;
+                }
 
                 const meta::TableMeta& currentColumn = *cursor;
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/0d8d166b/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/type_info_query.cpp b/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
index f6b3990..b4efca0 100644
--- a/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
@@ -122,6 +122,7 @@ namespace ignite
                 Query(diag, QueryType::TYPE_INFO),
                 columnsMeta(),
                 executed(false),
+                fetched(false),
                 types(),
                 cursor(types.end())
             {
@@ -185,6 +186,7 @@ namespace ignite
                 cursor = types.begin();
 
                 executed = true;
+                fetched = false;
 
                 return SqlResult::AI_SUCCESS;
             }
@@ -203,6 +205,11 @@ namespace ignite
                     return SqlResult::AI_ERROR;
                 }
 
+                if (!fetched)
+                    fetched = true;
+                else
+                    ++cursor;
+
                 if (cursor == types.end())
                     return SqlResult::AI_NO_DATA;
 
@@ -211,8 +218,6 @@ namespace ignite
                 for (it = columnBindings.begin(); it != columnBindings.end(); ++it)
                     GetColumn(it->first, it->second);
 
-                ++cursor;
-
                 return SqlResult::AI_SUCCESS;
             }
 
@@ -228,7 +233,12 @@ namespace ignite
                 }
 
                 if (cursor == types.end())
-                    return SqlResult::AI_NO_DATA;
+                {
+                    diag.AddStatusRecord(SqlState::S24000_INVALID_CURSOR_STATE,
+                        "Cursor has reached end of the result set.");
+
+                    return SqlResult::AI_ERROR;
+                }
 
                 int8_t currentType = *cursor;
 


[10/30] ignite git commit: IGNITE-4800: Lucene query may fails with NPE. This closes #2315.

Posted by ag...@apache.org.
IGNITE-4800: Lucene query may fails with NPE. This closes #2315.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/359777f2
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/359777f2
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/359777f2

Branch: refs/heads/ignite-5872
Commit: 359777f2355483b3d206b874117d680076a03853
Parents: 48c914d
Author: Andrey V. Mashenkov <an...@gmail.com>
Authored: Mon Jul 31 17:32:12 2017 +0300
Committer: Andrey V. Mashenkov <an...@gmail.com>
Committed: Fri Aug 4 18:06:18 2017 +0300

----------------------------------------------------------------------
 .../query/h2/opt/GridLuceneDirectory.java       | 64 +++++++++++---
 .../processors/query/h2/opt/GridLuceneFile.java | 91 +++++++++++++++-----
 .../query/h2/opt/GridLuceneIndex.java           |  3 +-
 .../query/h2/opt/GridLuceneInputStream.java     | 42 ++++++---
 .../query/h2/opt/GridLuceneOutputStream.java    | 18 +++-
 ...teCacheFullTextQueryNodeJoiningSelfTest.java |  3 +-
 .../IgniteCacheQuerySelfTestSuite.java          |  2 +
 7 files changed, 176 insertions(+), 47 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/359777f2/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneDirectory.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneDirectory.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneDirectory.java
index ff20987..3ac9641 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneDirectory.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneDirectory.java
@@ -21,22 +21,27 @@ import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicLong;
+import org.apache.ignite.IgniteException;
 import org.apache.ignite.internal.util.offheap.unsafe.GridUnsafeMemory;
+import org.apache.ignite.internal.util.typedef.F;
 import org.apache.lucene.store.BaseDirectory;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.IOContext;
 import org.apache.lucene.store.IndexInput;
 import org.apache.lucene.store.IndexOutput;
+import org.apache.lucene.util.Accountable;
+import org.apache.lucene.util.Accountables;
 
 /**
  * A memory-resident {@link Directory} implementation.
  */
-public class GridLuceneDirectory extends BaseDirectory {
+public class GridLuceneDirectory extends BaseDirectory implements Accountable {
     /** */
     protected final Map<String, GridLuceneFile> fileMap = new ConcurrentHashMap<>();
 
@@ -51,7 +56,7 @@ public class GridLuceneDirectory extends BaseDirectory {
      *
      * @param mem Memory.
      */
-    public GridLuceneDirectory(GridUnsafeMemory mem) {
+    GridLuceneDirectory(GridUnsafeMemory mem) {
         super(new GridLuceneLockFactory());
 
         this.mem = mem;
@@ -64,10 +69,7 @@ public class GridLuceneDirectory extends BaseDirectory {
         // and the code below is resilient to map changes during the array population.
         Set<String> fileNames = fileMap.keySet();
 
-        List<String> names = new ArrayList<>(fileNames.size());
-
-        for (String name : fileNames)
-            names.add(name);
+        List<String> names = new ArrayList<>(fileNames);
 
         return names.toArray(new String[names.size()]);
     }
@@ -82,6 +84,7 @@ public class GridLuceneDirectory extends BaseDirectory {
             throw new FileNotFoundException(source);
 
         fileMap.put(dest, file);
+
         fileMap.remove(source);
     }
 
@@ -101,21 +104,25 @@ public class GridLuceneDirectory extends BaseDirectory {
     @Override public void deleteFile(String name) throws IOException {
         ensureOpen();
 
-        doDeleteFile(name);
+        doDeleteFile(name, false);
     }
 
     /**
      * Deletes file.
      *
      * @param name File name.
+     * @param onClose If on close directory;
      * @throws IOException If failed.
      */
-    private void doDeleteFile(String name) throws IOException {
+    private void doDeleteFile(String name, boolean onClose) throws IOException {
         GridLuceneFile file = fileMap.remove(name);
 
         if (file != null) {
             file.delete();
 
+            // All files should be closed when Directory is closing.
+            assert !onClose || !file.hasRefs() : "Possible memory leak, resource is not closed: " + file.toString();
+
             sizeInBytes.addAndGet(-file.getSizeInBytes());
         }
         else
@@ -128,7 +135,10 @@ public class GridLuceneDirectory extends BaseDirectory {
 
         GridLuceneFile file = newRAMFile();
 
-        GridLuceneFile existing = fileMap.remove(name);
+        // Lock for using in stream. Will be unlocked on stream closing.
+        file.lockRef();
+
+        GridLuceneFile existing = fileMap.put(name, file);
 
         if (existing != null) {
             sizeInBytes.addAndGet(-existing.getSizeInBytes());
@@ -136,8 +146,6 @@ public class GridLuceneDirectory extends BaseDirectory {
             existing.delete();
         }
 
-        fileMap.put(name, file);
-
         return new GridLuceneOutputStream(file);
     }
 
@@ -165,6 +173,16 @@ public class GridLuceneDirectory extends BaseDirectory {
         if (file == null)
             throw new FileNotFoundException(name);
 
+        // Lock for using in stream. Will be unlocked on stream closing.
+        file.lockRef();
+
+        if (!fileMap.containsKey(name)) {
+            // Unblock for deferred delete.
+            file.releaseRef();
+
+            throw new FileNotFoundException(name);
+        }
+
         return new GridLuceneInputStream(name, file);
     }
 
@@ -172,16 +190,36 @@ public class GridLuceneDirectory extends BaseDirectory {
     @Override public void close() {
         isOpen = false;
 
+        IgniteException errs = null;
+
         for (String fileName : fileMap.keySet()) {
             try {
-                doDeleteFile(fileName);
+                doDeleteFile(fileName, true);
             }
             catch (IOException e) {
-                throw new IllegalStateException(e);
+                if (errs == null)
+                    errs = new IgniteException("Error closing index directory.");
+
+                errs.addSuppressed(e);
             }
         }
 
         assert fileMap.isEmpty();
+
+        if (errs != null && !F.isEmpty(errs.getSuppressed()))
+            throw errs;
+    }
+
+    /** {@inheritDoc} */
+    @Override public long ramBytesUsed() {
+        ensureOpen();
+
+        return sizeInBytes.get();
+    }
+
+    /** {@inheritDoc} */
+    @Override public synchronized Collection<Accountable> getChildResources() {
+        return Accountables.namedAccountables("file", new HashMap<>(fileMap));
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/359777f2/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneFile.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneFile.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneFile.java
index 3985f09..d7ae132 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneFile.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneFile.java
@@ -17,22 +17,19 @@
 
 package org.apache.ignite.internal.processors.query.h2.opt;
 
-import java.io.Serializable;
 import java.util.Arrays;
-import java.util.concurrent.atomic.AtomicInteger;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+import org.apache.lucene.util.Accountable;
 
 import static org.apache.ignite.internal.processors.query.h2.opt.GridLuceneOutputStream.BUFFER_SIZE;
 
 /**
  * Lucene file.
  */
-public class GridLuceneFile implements Serializable {
-    /** */
-    private static final long serialVersionUID = 0L;
-
-    /** */
-    public static final AtomicInteger filesCnt = new AtomicInteger();
-
+public class GridLuceneFile implements Accountable {
     /** */
     private LongArray buffers = new LongArray();
 
@@ -45,6 +42,12 @@ public class GridLuceneFile implements Serializable {
     /** */
     private volatile long sizeInBytes;
 
+    /** */
+    private final AtomicLong refCnt = new AtomicLong();
+
+    /** */
+    private final AtomicBoolean deleted = new AtomicBoolean();
+
     /**
      * File used as buffer, in no RAMDirectory
      *
@@ -52,8 +55,6 @@ public class GridLuceneFile implements Serializable {
      */
     GridLuceneFile(GridLuceneDirectory dir) {
         this.dir = dir;
-
-        filesCnt.incrementAndGet();
     }
 
     /**
@@ -93,51 +94,89 @@ public class GridLuceneFile implements Serializable {
     }
 
     /**
+     * Increment ref counter.
+     */
+    void lockRef() {
+        refCnt.incrementAndGet();
+    }
+
+    /**
+     * Decrement ref counter.
+     */
+    void releaseRef() {
+        refCnt.decrementAndGet();
+
+        deferredDelete();
+    }
+
+    /**
+     * Checks if there is file stream opened.
+     *
+     * @return {@code True} if file has external references.
+     */
+    boolean hasRefs() {
+        long refs = refCnt.get();
+
+        assert refs >= 0;
+
+        return refs != 0;
+    }
+
+    /**
      * Gets address of buffer.
      *
      * @param idx Index.
      * @return Pointer.
      */
-    protected final synchronized long getBuffer(int idx) {
+    final synchronized long getBuffer(int idx) {
         return buffers.get(idx);
     }
 
     /**
      * @return Number of buffers.
      */
-    protected final synchronized int numBuffers() {
+    final synchronized int numBuffers() {
         return buffers.size();
     }
 
     /**
-     * Expert: allocate a new buffer.
-     * Subclasses can allocate differently.
+     * Expert: allocate a new buffer. Subclasses can allocate differently.
      *
      * @return allocated buffer.
      */
-    protected long newBuffer() {
+    private long newBuffer() {
         return dir.memory().allocate(BUFFER_SIZE);
     }
 
     /**
      * Deletes file and deallocates memory..
      */
-    public synchronized void delete() {
-        if (buffers == null)
+    public void delete() {
+        if (!deleted.compareAndSet(false, true))
             return;
 
+        deferredDelete();
+    }
+
+    /**
+     * Deferred delete.
+     */
+    synchronized void deferredDelete() {
+        if (!deleted.get() || hasRefs())
+            return;
+
+        assert refCnt.get() == 0;
+
         for (int i = 0; i < buffers.idx; i++)
             dir.memory().release(buffers.arr[i], BUFFER_SIZE);
 
         buffers = null;
-
-        filesCnt.decrementAndGet();
     }
 
     /**
      * @return Size in bytes.
      */
-    public long getSizeInBytes() {
+    long getSizeInBytes() {
         return sizeInBytes;
     }
 
@@ -148,6 +187,16 @@ public class GridLuceneFile implements Serializable {
         return dir;
     }
 
+    /** {@inheritDoc} */
+    @Override public long ramBytesUsed() {
+        return sizeInBytes;
+    }
+
+    /** {@inheritDoc} */
+    @Override public Collection<Accountable> getChildResources() {
+        return Collections.emptyList();
+    }
+
     /**
      * Simple expandable long[] wrapper.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/359777f2/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneIndex.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneIndex.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneIndex.java
index eed5ee4..c51eb5d 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneIndex.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneIndex.java
@@ -296,7 +296,8 @@ public class GridLuceneIndex implements AutoCloseable {
     /** {@inheritDoc} */
     @Override public void close() {
         U.closeQuiet(writer);
-        U.closeQuiet(dir);
+
+        dir.close();
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/359777f2/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneInputStream.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneInputStream.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneInputStream.java
index 4820af1..9b1bf0c 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneInputStream.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneInputStream.java
@@ -20,6 +20,7 @@ package org.apache.ignite.internal.processors.query.h2.opt;
 import java.io.EOFException;
 import java.io.IOException;
 import org.apache.ignite.internal.util.offheap.unsafe.GridUnsafeMemory;
+import org.apache.lucene.store.AlreadyClosedException;
 import org.apache.lucene.store.IndexInput;
 
 import static org.apache.ignite.internal.processors.query.h2.opt.GridLuceneOutputStream.BUFFER_SIZE;
@@ -27,7 +28,7 @@ import static org.apache.ignite.internal.processors.query.h2.opt.GridLuceneOutpu
 /**
  * A memory-resident {@link IndexInput} implementation.
  */
-public class GridLuceneInputStream extends IndexInput {
+public class GridLuceneInputStream extends IndexInput implements Cloneable {
     /** */
     private GridLuceneFile file;
 
@@ -52,6 +53,11 @@ public class GridLuceneInputStream extends IndexInput {
     /** */
     private final GridUnsafeMemory mem;
 
+    /** */
+    private volatile boolean closed;
+
+    /** */
+    private boolean isClone;
     /**
      * Constructor.
      *
@@ -91,7 +97,24 @@ public class GridLuceneInputStream extends IndexInput {
 
     /** {@inheritDoc} */
     @Override public void close() {
-        // nothing to do here
+        if (!isClone) {
+            closed = true;
+
+            file.releaseRef();
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public IndexInput clone() {
+        GridLuceneInputStream clone = (GridLuceneInputStream) super.clone();
+
+        if(closed)
+            throw new AlreadyClosedException(toString());
+
+        clone.isClone = true;
+
+        return clone;
+
     }
 
     /** {@inheritDoc} */
@@ -222,14 +245,16 @@ public class GridLuceneInputStream extends IndexInput {
         public SlicedInputStream(String newResourceDescription, long offset, long length) throws IOException {
             super(newResourceDescription, GridLuceneInputStream.this.file, offset + length);
 
+            // Avoid parent resource closing together with this.
+            super.isClone = true;
+
             this.offset = offset;
 
             seek(0L);
         }
 
         /** {@inheritDoc} */
-        @Override
-        public void seek(long pos) throws IOException {
+        @Override public void seek(long pos) throws IOException {
             if (pos < 0L) {
                 throw new IllegalArgumentException("Seeking to negative position: " + this);
             }
@@ -237,20 +262,17 @@ public class GridLuceneInputStream extends IndexInput {
         }
 
         /** {@inheritDoc} */
-        @Override
-        public long getFilePointer() {
+        @Override public long getFilePointer() {
             return super.getFilePointer() - offset;
         }
 
         /** {@inheritDoc} */
-        @Override
-        public long length() {
+        @Override public long length() {
             return super.length() - offset;
         }
 
         /** {@inheritDoc} */
-        @Override
-        public IndexInput slice(String sliceDescription, long ofs, long len) throws IOException {
+        @Override public IndexInput slice(String sliceDescription, long ofs, long len) throws IOException {
             return super.slice(sliceDescription, offset + ofs, len);
         }
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/359777f2/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneOutputStream.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneOutputStream.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneOutputStream.java
index caea226..d8f09df 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneOutputStream.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/opt/GridLuceneOutputStream.java
@@ -18,17 +18,21 @@
 package org.apache.ignite.internal.processors.query.h2.opt;
 
 import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.zip.CRC32;
 import java.util.zip.Checksum;
 import org.apache.ignite.internal.util.offheap.unsafe.GridUnsafeMemory;
 import org.apache.lucene.store.BufferedChecksum;
 import org.apache.lucene.store.DataInput;
 import org.apache.lucene.store.IndexOutput;
+import org.apache.lucene.util.Accountable;
+import org.apache.lucene.util.Accountables;
 
 /**
  * A memory-resident {@link IndexOutput} implementation.
  */
-public class GridLuceneOutputStream extends IndexOutput {
+public class GridLuceneOutputStream extends IndexOutput implements Accountable {
     /** Off-heap page size. */
     static final int BUFFER_SIZE = 32 * 1024;
 
@@ -93,6 +97,8 @@ public class GridLuceneOutputStream extends IndexOutput {
     /** {@inheritDoc} */
     @Override public void close() throws IOException {
         flush();
+
+        file.releaseRef();
     }
 
     /** {@inheritDoc} */
@@ -201,4 +207,14 @@ public class GridLuceneOutputStream extends IndexOutput {
             bufPosition += toCp;
         }
     }
+
+    /** {@inheritDoc} */
+    @Override public long ramBytesUsed() {
+        return file.getSizeInBytes();
+    }
+
+    /** {@inheritDoc} */
+    @Override public Collection<Accountable> getChildResources() {
+        return Collections.singleton(Accountables.namedAccountable("file", file));
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/359777f2/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheFullTextQueryNodeJoiningSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheFullTextQueryNodeJoiningSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheFullTextQueryNodeJoiningSelfTest.java
index ba0324f..162b1e5 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheFullTextQueryNodeJoiningSelfTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/IgniteCacheFullTextQueryNodeJoiningSelfTest.java
@@ -42,7 +42,6 @@ import static org.apache.ignite.cache.CacheMode.PARTITIONED;
 import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
 
 /**
- * TODO https://issues.apache.org/jira/browse/IGNITE-2229
  * Tests cache in-place modification logic with iterative value increment.
  */
 public class IgniteCacheFullTextQueryNodeJoiningSelfTest extends GridCommonAbstractTest {
@@ -107,6 +106,8 @@ public class IgniteCacheFullTextQueryNodeJoiningSelfTest extends GridCommonAbstr
      * @throws Exception If failed.
      */
     public void testFullTextQueryNodeJoin() throws Exception {
+        fail("https://issues.apache.org/jira/browse/IGNITE-2229");
+
         for (int r = 0; r < 5; r++) {
             startGrids(GRID_CNT);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/359777f2/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
index 258eed8..1ad0d4b 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteCacheQuerySelfTestSuite.java
@@ -47,6 +47,7 @@ import org.apache.ignite.internal.processors.cache.IgniteCacheCollocatedQuerySel
 import org.apache.ignite.internal.processors.cache.IgniteCacheDeleteSqlQuerySelfTest;
 import org.apache.ignite.internal.processors.cache.IgniteCacheDuplicateEntityConfigurationSelfTest;
 import org.apache.ignite.internal.processors.cache.IgniteCacheFieldsQueryNoDataSelfTest;
+import org.apache.ignite.internal.processors.cache.IgniteCacheFullTextQueryNodeJoiningSelfTest;
 import org.apache.ignite.internal.processors.cache.IgniteCacheInsertSqlQuerySelfTest;
 import org.apache.ignite.internal.processors.cache.IgniteCacheJoinPartitionedAndReplicatedTest;
 import org.apache.ignite.internal.processors.cache.IgniteCacheJoinQueryWithAffinityKeyTest;
@@ -273,6 +274,7 @@ public class IgniteCacheQuerySelfTestSuite extends TestSuite {
 
         // Full text queries.
         suite.addTestSuite(GridCacheFullTextQuerySelfTest.class);
+        suite.addTestSuite(IgniteCacheFullTextQueryNodeJoiningSelfTest.class);
 
         // Ignite cache and H2 comparison.
         suite.addTestSuite(BaseH2CompareQueryTest.class);


[06/30] ignite git commit: IGNITE-5126: Batch support for this JDBC driver. This closes #2162.

Posted by ag...@apache.org.
IGNITE-5126: Batch support for this JDBC driver. This closes #2162.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/1a7354fa
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/1a7354fa
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/1a7354fa

Branch: refs/heads/ignite-5872
Commit: 1a7354fa6b45c3c33d3cf3f8a9f4b56bfbf5f507
Parents: e8b355f
Author: tledkov-gridgain <tl...@gridgain.com>
Authored: Fri Aug 4 11:46:14 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Fri Aug 4 11:46:14 2017 +0300

----------------------------------------------------------------------
 .../jdbc/suite/IgniteJdbcDriverTestSuite.java   |   2 +
 .../ignite/jdbc/thin/JdbcThinBatchSelfTest.java | 333 +++++++++++++++++++
 .../jdbc/thin/JdbcThinPreparedStatement.java    |  16 +-
 .../internal/jdbc/thin/JdbcThinStatement.java   |  46 ++-
 .../internal/jdbc/thin/JdbcThinTcpIo.java       |  20 ++
 .../odbc/jdbc/JdbcBatchExecuteRequest.java      | 109 ++++++
 .../odbc/jdbc/JdbcBatchExecuteResult.java       |  96 ++++++
 .../processors/odbc/jdbc/JdbcQuery.java         |  95 ++++++
 .../processors/odbc/jdbc/JdbcRequest.java       |   8 +
 .../odbc/jdbc/JdbcRequestHandler.java           |  66 +++-
 .../processors/odbc/jdbc/JdbcResult.java        |  11 +
 11 files changed, 794 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/1a7354fa/modules/clients/src/test/java/org/apache/ignite/jdbc/suite/IgniteJdbcDriverTestSuite.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/suite/IgniteJdbcDriverTestSuite.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/suite/IgniteJdbcDriverTestSuite.java
index 8ca3d45..cf7ee8f 100644
--- a/modules/clients/src/test/java/org/apache/ignite/jdbc/suite/IgniteJdbcDriverTestSuite.java
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/suite/IgniteJdbcDriverTestSuite.java
@@ -33,6 +33,7 @@ import org.apache.ignite.jdbc.JdbcPreparedStatementSelfTest;
 import org.apache.ignite.jdbc.JdbcResultSetSelfTest;
 import org.apache.ignite.jdbc.JdbcStatementSelfTest;
 import org.apache.ignite.jdbc.thin.JdbcThinAutoCloseServerCursorTest;
+import org.apache.ignite.jdbc.thin.JdbcThinBatchSelfTest;
 import org.apache.ignite.jdbc.thin.JdbcThinComplexQuerySelfTest;
 import org.apache.ignite.jdbc.thin.JdbcThinConnectionSelfTest;
 import org.apache.ignite.jdbc.thin.JdbcThinDeleteStatementSelfTest;
@@ -121,6 +122,7 @@ public class IgniteJdbcDriverTestSuite extends TestSuite {
         suite.addTest(new TestSuite(JdbcThinMergeStatementSelfTest.class));
         suite.addTest(new TestSuite(JdbcThinDeleteStatementSelfTest.class));
         suite.addTest(new TestSuite(JdbcThinAutoCloseServerCursorTest.class));
+        suite.addTest(new TestSuite(JdbcThinBatchSelfTest.class));
 
         // New thin JDBC driver, DDL tests
         suite.addTest(new TestSuite(JdbcThinDynamicIndexAtomicPartitionedNearSelfTest.class));

http://git-wip-us.apache.org/repos/asf/ignite/blob/1a7354fa/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinBatchSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinBatchSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinBatchSelfTest.java
new file mode 100644
index 0000000..5781e00
--- /dev/null
+++ b/modules/clients/src/test/java/org/apache/ignite/jdbc/thin/JdbcThinBatchSelfTest.java
@@ -0,0 +1,333 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.jdbc.thin;
+
+import java.sql.BatchUpdateException;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.concurrent.Callable;
+import org.apache.ignite.testframework.GridTestUtils;
+
+/**
+ * Statement test.
+ */
+public class JdbcThinBatchSelfTest extends JdbcThinAbstractDmlStatementSelfTest {
+    /** SQL query. */
+    private static final String SQL_PREPARED = "insert into Person(_key, id, firstName, lastName, age) values " +
+        "(?, ?, ?, ?, ?)";
+
+    /** Statement. */
+    private Statement stmt;
+
+    /** Prepared statement. */
+    private PreparedStatement pstmt;
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        super.beforeTest();
+
+        stmt = conn.createStatement();
+
+        pstmt = conn.prepareStatement(SQL_PREPARED);
+
+        assertNotNull(stmt);
+        assertFalse(stmt.isClosed());
+
+        assertNotNull(pstmt);
+        assertFalse(pstmt.isClosed());
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        if (stmt != null && !stmt.isClosed())
+            stmt.close();
+
+        if (pstmt != null && !pstmt.isClosed())
+            pstmt.close();
+
+        assertTrue(pstmt.isClosed());
+        assertTrue(stmt.isClosed());
+
+        super.afterTest();
+    }
+
+    /**
+     * @throws SQLException If failed.
+     */
+    public void testBatch() throws SQLException {
+        final int BATCH_SIZE = 10;
+
+        for (int idx = 0, i = 0; i < BATCH_SIZE; ++i, idx += i) {
+            stmt.addBatch("insert into Person (_key, id, firstName, lastName, age) values "
+                + generateValues(idx, i + 1));
+        }
+
+        int [] updCnts = stmt.executeBatch();
+
+        assertEquals("Invalid update counts size", BATCH_SIZE, updCnts.length);
+
+        for (int i = 0; i < BATCH_SIZE; ++i)
+            assertEquals("Invalid update count",i + 1, updCnts[i]);
+    }
+
+    /**
+     * @throws SQLException If failed.
+     */
+    public void testBatchOnClosedStatement() throws SQLException {
+        final Statement stmt2 = conn.createStatement();
+        final PreparedStatement pstmt2 = conn.prepareStatement("");
+
+        stmt2.close();
+        pstmt2.close();
+
+        GridTestUtils.assertThrows(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                stmt2.addBatch("");
+
+                return null;
+            }
+        }, SQLException.class, "Statement is closed.");
+
+        GridTestUtils.assertThrows(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                stmt2.clearBatch();
+
+                return null;
+            }
+        }, SQLException.class, "Statement is closed.");
+
+        GridTestUtils.assertThrows(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                stmt2.executeBatch();
+
+                return null;
+            }
+        }, SQLException.class, "Statement is closed.");
+
+        GridTestUtils.assertThrows(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                pstmt2.addBatch();
+
+                return null;
+            }
+        }, SQLException.class, "Statement is closed.");
+
+        GridTestUtils.assertThrows(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                pstmt2.clearBatch();
+
+                return null;
+            }
+        }, SQLException.class, "Statement is closed.");
+
+        GridTestUtils.assertThrows(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                pstmt2.executeBatch();
+
+                return null;
+            }
+        }, SQLException.class, "Statement is closed.");
+    }
+
+    /**
+     * @throws SQLException If failed.
+     */
+    public void testBatchException() throws SQLException {
+        final int BATCH_SIZE = 7;
+
+        for (int idx = 0, i = 0; i < BATCH_SIZE; ++i, idx += i) {
+            stmt.addBatch("insert into Person (_key, id, firstName, lastName, age) values "
+                + generateValues(idx, i + 1));
+        }
+
+        stmt.addBatch("select * from Person");
+
+        stmt.addBatch("insert into Person (_key, id, firstName, lastName, age) values "
+            + generateValues(100, 1));
+
+        try {
+            stmt.executeBatch();
+
+            fail("BatchUpdateException must be thrown");
+        } catch(BatchUpdateException e) {
+            int [] updCnts = e.getUpdateCounts();
+
+            assertEquals("Invalid update counts size", BATCH_SIZE, updCnts.length);
+
+            for (int i = 0; i < BATCH_SIZE; ++i)
+                assertEquals("Invalid update count",i + 1, updCnts[i]);
+
+            if (!e.getMessage().contains("Query produced result set [qry=select * from Person, args=[]]")) {
+                log.error("Invalid exception: ", e);
+
+                fail();
+            }
+        }
+    }
+
+    /**
+     * @throws SQLException If failed.
+     */
+    public void testBatchClear() throws SQLException {
+        final int BATCH_SIZE = 7;
+
+        for (int idx = 0, i = 0; i < BATCH_SIZE; ++i, idx += i) {
+            stmt.addBatch("insert into Person (_key, id, firstName, lastName, age) values "
+                + generateValues(idx, i + 1));
+        }
+
+        stmt.clearBatch();
+
+        GridTestUtils.assertThrows(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                stmt.executeBatch();
+
+                return null;
+            }
+        }, SQLException.class, "Batch is empty.");
+    }
+
+    /**
+     * @throws SQLException If failed.
+     */
+    public void testBatchPrepared() throws SQLException {
+        final int BATCH_SIZE = 10;
+
+        for (int i = 0; i < BATCH_SIZE; ++i) {
+            int paramCnt = 1;
+
+            pstmt.setString(paramCnt++, "p" + i);
+            pstmt.setInt(paramCnt++, i);
+            pstmt.setString(paramCnt++, "Name" + i);
+            pstmt.setString(paramCnt++, "Lastname" + i);
+            pstmt.setInt(paramCnt++, 20 + i);
+
+            pstmt.addBatch();
+        }
+
+        int [] updCnts = pstmt.executeBatch();
+
+        assertEquals("Invalid update counts size", BATCH_SIZE, updCnts.length);
+
+        for (int i = 0; i < BATCH_SIZE; ++i)
+            assertEquals("Invalid update count",1, updCnts[i]);
+    }
+
+    /**
+     * @throws SQLException If failed.
+     */
+    public void testBatchExceptionPrepared() throws SQLException {
+        final int BATCH_SIZE = 7;
+
+        for (int i = 0; i < BATCH_SIZE; ++i) {
+            int paramCnt = 1;
+
+            pstmt.setString(paramCnt++, "p" + i);
+            pstmt.setInt(paramCnt++, i);
+            pstmt.setString(paramCnt++, "Name" + i);
+            pstmt.setString(paramCnt++, "Lastname" + i);
+            pstmt.setInt(paramCnt++, 20 + i);
+
+            pstmt.addBatch();
+        }
+
+        int paramCnt = 1;
+        pstmt.setString(paramCnt++, "p" + 100);
+        pstmt.setString(paramCnt++, "x");
+        pstmt.setString(paramCnt++, "Name" + 100);
+        pstmt.setString(paramCnt++, "Lastname" + 100);
+        pstmt.setInt(paramCnt++, 20 + 100);
+
+        pstmt.addBatch();
+
+        try {
+            pstmt.executeBatch();
+
+            fail("BatchUpdateException must be thrown");
+        } catch(BatchUpdateException e) {
+            int [] updCnts = e.getUpdateCounts();
+
+            assertEquals("Invalid update counts size", BATCH_SIZE, updCnts.length);
+
+            for (int i = 0; i < BATCH_SIZE; ++i)
+                assertEquals("Invalid update count",1, updCnts[i]);
+
+            if (!e.getMessage().contains("Failed to execute SQL query.")) {
+                log.error("Invalid exception: ", e);
+
+                fail();
+            }
+        }
+    }
+
+    /**
+     * @throws SQLException If failed.
+     */
+    public void testBatchClearPrepared() throws SQLException {
+        final int BATCH_SIZE = 10;
+
+        for (int i = 0; i < BATCH_SIZE; ++i) {
+            int paramCnt = 1;
+
+            pstmt.setString(paramCnt++, "p" + i);
+            pstmt.setInt(paramCnt++, i);
+            pstmt.setString(paramCnt++, "Name" + i);
+            pstmt.setString(paramCnt++, "Lastname" + i);
+            pstmt.setInt(paramCnt++, 20 + i);
+
+            pstmt.addBatch();
+        }
+
+        pstmt.clearBatch();
+
+        GridTestUtils.assertThrows(log, new Callable<Object>() {
+            @Override public Object call() throws Exception {
+                pstmt.executeBatch();
+
+                return null;
+            }
+        }, SQLException.class, "Batch is empty.");
+    }
+
+    /**
+     * @param beginIndex Begin row index.
+     * @param cnt Count of rows.
+     * @return String contains values for 'cnt' rows.
+     */
+    private String generateValues(int beginIndex, int cnt) {
+        StringBuilder sb = new StringBuilder();
+
+        int lastIdx = beginIndex + cnt - 1;
+
+        for (int i = beginIndex; i < lastIdx; ++i)
+            sb.append(valuesRow(i)).append(',');
+
+        sb.append(valuesRow(lastIdx));
+
+        return sb.toString();
+    }
+
+    /**
+     * @param idx Index of the row.
+     * @return String with row values.
+     */
+    private String valuesRow(int idx) {
+        return String.format("('p%d', %d, 'Name%d', 'Lastname%d', %d)", idx, idx, idx, idx, 20 + idx);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/1a7354fa/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java
index 0c78a13..455c80f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinPreparedStatement.java
@@ -40,6 +40,7 @@ import java.sql.Timestamp;
 import java.util.ArrayList;
 import java.util.Calendar;
 import org.apache.ignite.internal.processors.odbc.SqlListenerUtils;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQuery;
 
 /**
  * JDBC prepared statement implementation.
@@ -230,7 +231,20 @@ public class JdbcThinPreparedStatement extends JdbcThinStatement implements Prep
     @Override public void addBatch() throws SQLException {
         ensureNotClosed();
 
-        throw new SQLFeatureNotSupportedException("Updates are not supported.");
+        if (batch == null) {
+            batch = new ArrayList<>();
+
+            batch.add(new JdbcQuery(sql, args.toArray(new Object[args.size()])));
+        }
+        else
+            batch.add(new JdbcQuery(null, args.toArray(new Object[args.size()])));
+
+        args = null;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void addBatch(String sql) throws SQLException {
+        throw new SQLException("The method 'addBatch(String)' is called on PreparedStatement instance.");
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/1a7354fa/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java
index 2cad223..b01350a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinStatement.java
@@ -18,15 +18,20 @@
 package org.apache.ignite.internal.jdbc.thin;
 
 import java.io.IOException;
+import java.sql.BatchUpdateException;
 import java.sql.Connection;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.SQLFeatureNotSupportedException;
 import java.sql.SQLWarning;
 import java.sql.Statement;
+import java.util.ArrayList;
 import java.util.List;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.cache.query.SqlQuery;
+import org.apache.ignite.internal.processors.odbc.SqlListenerResponse;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcBatchExecuteResult;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQuery;
 import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQueryExecuteResult;
 
 import static java.sql.ResultSet.CONCUR_READ_ONLY;
@@ -62,6 +67,9 @@ public class JdbcThinStatement implements Statement {
     /** */
     private boolean alreadyRead;
 
+    /** Batch. */
+    protected List<JdbcQuery> batch;
+
     /**
      * Creates new statement.
      *
@@ -323,21 +331,53 @@ public class JdbcThinStatement implements Statement {
     @Override public void addBatch(String sql) throws SQLException {
         ensureNotClosed();
 
-        throw new SQLFeatureNotSupportedException("Updates are not supported.");
+        if (batch == null)
+            batch = new ArrayList<>();
+
+        batch.add(new JdbcQuery(sql, null));
     }
 
     /** {@inheritDoc} */
     @Override public void clearBatch() throws SQLException {
         ensureNotClosed();
 
-        throw new SQLFeatureNotSupportedException("Updates are not supported.");
+        batch = null;
     }
 
     /** {@inheritDoc} */
     @Override public int[] executeBatch() throws SQLException {
         ensureNotClosed();
 
-        throw new SQLFeatureNotSupportedException("Updates are not supported.");
+        if (rs != null) {
+            rs.close();
+
+            rs = null;
+        }
+
+        alreadyRead = false;
+
+        if (batch == null || batch.isEmpty())
+            throw new SQLException("Batch is empty.");
+
+        try {
+            JdbcBatchExecuteResult res = conn.io().batchExecute(conn.getSchema(), batch);
+
+            if (res.errorCode() != SqlListenerResponse.STATUS_SUCCESS)
+                throw new BatchUpdateException(res.errorMessage(), null, res.errorCode(), res.updateCounts());
+
+            return res.updateCounts();
+        }
+        catch (IOException e) {
+            conn.close();
+
+            throw new SQLException("Failed to query Ignite.", e);
+        }
+        catch (IgniteCheckedException e) {
+            throw new SQLException("Failed to query Ignite.", e);
+        }
+        finally {
+            batch = null;
+        }
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/1a7354fa/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
index be62a8d..f54d5fd 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc/thin/JdbcThinTcpIo.java
@@ -32,6 +32,9 @@ import org.apache.ignite.internal.processors.odbc.SqlListenerNioListener;
 import org.apache.ignite.internal.processors.odbc.SqlListenerProtocolVersion;
 import org.apache.ignite.internal.processors.odbc.SqlListenerRequest;
 import org.apache.ignite.internal.processors.odbc.SqlListenerResponse;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcBatchExecuteRequest;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcBatchExecuteResult;
+import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQuery;
 import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQueryCloseRequest;
 import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQueryExecuteRequest;
 import org.apache.ignite.internal.processors.odbc.jdbc.JdbcQueryExecuteResult;
@@ -58,6 +61,9 @@ public class JdbcThinTcpIo {
     /** Initial output for query message. */
     private static final int QUERY_EXEC_MSG_INIT_CAP = 256;
 
+    /** Maximum batch query count. */
+    private static final int MAX_BATCH_QRY_CNT = 32;
+
     /** Initial output for query fetch message. */
     private static final int QUERY_FETCH_MSG_SIZE = 13;
 
@@ -289,6 +295,20 @@ public class JdbcThinTcpIo {
     }
 
     /**
+     * @param schema Schema.
+     * @param batch Batch queries.
+     * @return Result.
+     * @throws IOException On error.
+     * @throws IgniteCheckedException On error.
+     */
+    public JdbcBatchExecuteResult batchExecute(String schema, List<JdbcQuery> batch)
+        throws IOException, IgniteCheckedException {
+        int cnt = Math.min(MAX_BATCH_QRY_CNT, batch.size());
+
+        return sendRequest(new JdbcBatchExecuteRequest(schema, batch), QUERY_EXEC_MSG_INIT_CAP * cnt);
+    }
+
+    /**
      * @param req ODBC request.
      * @throws IOException On error.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/1a7354fa/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcBatchExecuteRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcBatchExecuteRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcBatchExecuteRequest.java
new file mode 100644
index 0000000..9f71bff
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcBatchExecuteRequest.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.odbc.jdbc;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.internal.binary.BinaryReaderExImpl;
+import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+import org.apache.ignite.internal.util.tostring.GridToStringInclude;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * JDBC batch execute request.
+ */
+public class JdbcBatchExecuteRequest extends JdbcRequest {
+    /** Cache name. */
+    private String schema;
+
+    /** Sql query. */
+    @GridToStringInclude(sensitive = true)
+    private List<JdbcQuery> queries;
+
+    /**
+     * Default constructor.
+     */
+    public JdbcBatchExecuteRequest() {
+        super(BATCH_EXEC);
+    }
+
+    /**
+     * @param schema Schema.
+     * @param queries Queries.
+     */
+    public JdbcBatchExecuteRequest(String schema, List<JdbcQuery> queries) {
+        super(BATCH_EXEC);
+
+        assert !F.isEmpty(queries);
+
+        this.schema = schema;
+        this.queries = queries;
+    }
+
+    /**
+     * @return Schema.
+     */
+    @Nullable public String schema() {
+        return schema;
+    }
+
+    /**
+     * @return Queries.
+     */
+    public List<JdbcQuery> queries() {
+        return queries;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException {
+        super.writeBinary(writer);
+
+        writer.writeString(schema);
+        writer.writeInt(queries.size());
+
+        for (JdbcQuery q : queries)
+            q.writeBinary(writer);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException {
+        super.readBinary(reader);
+
+        schema = reader.readString();
+
+        int n = reader.readInt();
+
+        queries = new ArrayList<>(n);
+
+        for (int i = 0; i < n; ++i) {
+            JdbcQuery qry = new JdbcQuery();
+
+            qry.readBinary(reader);
+
+            queries.add(qry);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(JdbcBatchExecuteRequest.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/1a7354fa/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcBatchExecuteResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcBatchExecuteResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcBatchExecuteResult.java
new file mode 100644
index 0000000..7977c22
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcBatchExecuteResult.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.odbc.jdbc;
+
+import org.apache.ignite.binary.BinaryObjectException;
+import org.apache.ignite.internal.binary.BinaryReaderExImpl;
+import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+
+/**
+ * JDBC batch execute result.
+ */
+public class JdbcBatchExecuteResult extends JdbcResult {
+    /** Update counts. */
+    private int [] updateCnts;
+
+    /** Batch update error code. */
+    private int errCode;
+
+    /** Batch update error message. */
+    private String errMsg;
+
+    /**
+     * Condtructor.
+     */
+    public JdbcBatchExecuteResult() {
+        super(BATCH_EXEC);
+    }
+
+    /**
+     * @param updateCnts Update counts for batch.
+     * @param errCode Error code.
+     * @param errMsg Error message.
+     */
+    public JdbcBatchExecuteResult(int [] updateCnts, int errCode, String errMsg) {
+        super(BATCH_EXEC);
+
+        this.updateCnts = updateCnts;
+        this.errCode = errCode;
+        this.errMsg = errMsg;
+    }
+
+    /**
+     * @return Update count for DML queries.
+     */
+    public int[] updateCounts() {
+        return updateCnts;
+    }
+
+    /**
+     * @return Batch error code.
+     */
+    public int errorCode() {
+        return errCode;
+    }
+
+    /**
+     * @return Batch error message.
+     */
+    public String errorMessage() {
+        return errMsg;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeBinary(BinaryWriterExImpl writer) throws BinaryObjectException {
+        super.writeBinary(writer);
+
+        writer.writeInt(errCode);
+        writer.writeString(errMsg);
+        writer.writeIntArray(updateCnts);
+    }
+
+
+    /** {@inheritDoc} */
+    @Override public void readBinary(BinaryReaderExImpl reader) throws BinaryObjectException {
+        super.readBinary(reader);
+
+        errCode = reader.readInt();
+        errMsg = reader.readString();
+        updateCnts = reader.readIntArray();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/1a7354fa/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQuery.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQuery.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQuery.java
new file mode 100644
index 0000000..f7ffb99
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcQuery.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.odbc.jdbc;
+
+import org.apache.ignite.internal.binary.BinaryReaderExImpl;
+import org.apache.ignite.internal.binary.BinaryWriterExImpl;
+import org.apache.ignite.internal.processors.odbc.SqlListenerUtils;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * JDBC SQL query with parameters.
+ */
+public class JdbcQuery implements JdbcRawBinarylizable {
+    /** Query SQL. */
+    private String sql;
+
+    /** Arguments. */
+    private Object[] args;
+
+    /**
+     * Default constructor is used for serialization.
+     */
+    public JdbcQuery() {
+        // No-op.
+    }
+
+    /**
+     * @param sql Query SQL.
+     * @param args Arguments.
+     */
+    public JdbcQuery(String sql, Object[] args) {
+        this.sql = sql;
+        this.args = args;
+    }
+
+    /**
+     * @return Query SQL string.
+     */
+    public String sql() {
+        return sql;
+    }
+
+    /**
+     * @return Query arguments.
+     */
+    public Object[] args() {
+        return args;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void writeBinary(BinaryWriterExImpl writer) {
+        writer.writeString(sql);
+
+        if (args == null || args.length == 0)
+            writer.writeInt(0);
+        else {
+            writer.writeInt(args.length);
+
+            for (Object arg : args)
+                SqlListenerUtils.writeObject(writer, arg, false);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public void readBinary(BinaryReaderExImpl reader) {
+        sql = reader.readString();
+
+        int argsNum = reader.readInt();
+
+        args = new Object[argsNum];
+
+        for (int i = 0; i < argsNum; ++i)
+            args[i] = SqlListenerUtils.readObject(reader, false);
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(JdbcQuery.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/1a7354fa/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequest.java
index d6f8fd3..0e144cc 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequest.java
@@ -39,6 +39,9 @@ public class JdbcRequest extends SqlListenerRequest implements JdbcRawBinaryliza
     /** Get columns meta query. */
     public static final byte QRY_META = 5;
 
+    /** Batch queries. */
+    public static final byte BATCH_EXEC = 6;
+
     /** Request type. */
     private byte type;
 
@@ -97,6 +100,11 @@ public class JdbcRequest extends SqlListenerRequest implements JdbcRawBinaryliza
 
                 break;
 
+            case BATCH_EXEC:
+                req = new JdbcBatchExecuteRequest();
+
+                break;
+
             default:
                 throw new IgniteException("Unknown SQL listener request ID: [request ID=" + reqType + ']');
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1a7354fa/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
index 94ac433..60c08f9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcRequestHandler.java
@@ -17,6 +17,11 @@
 
 package org.apache.ignite.internal.processors.odbc.jdbc;
 
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicLong;
+import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.cache.query.FieldsQueryCursor;
 import org.apache.ignite.cache.query.SqlFieldsQuery;
@@ -31,10 +36,7 @@ import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
 
-import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicLong;
-
+import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest.BATCH_EXEC;
 import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest.QRY_CLOSE;
 import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest.QRY_EXEC;
 import static org.apache.ignite.internal.processors.odbc.jdbc.JdbcRequest.QRY_FETCH;
@@ -129,6 +131,9 @@ public class JdbcRequestHandler implements SqlListenerRequestHandler {
 
                 case QRY_META:
                     return getQueryMeta((JdbcQueryMetadataRequest)req);
+
+                case BATCH_EXEC:
+                    return executeBatch((JdbcBatchExecuteRequest)req);
             }
 
             return new JdbcResponse(SqlListenerResponse.STATUS_FAILED, "Unsupported JDBC request [req=" + req + ']');
@@ -307,4 +312,57 @@ public class JdbcRequestHandler implements SqlListenerRequestHandler {
             return new JdbcResponse(SqlListenerResponse.STATUS_FAILED, e.toString());
         }
     }
+
+    /**
+     * @param req Request.
+     * @return Response.
+     */
+    private SqlListenerResponse executeBatch(JdbcBatchExecuteRequest req) {
+        String schemaName = req.schema();
+
+        if (F.isEmpty(schemaName))
+            schemaName = QueryUtils.DFLT_SCHEMA;
+
+        int successQueries = 0;
+        int updCnts[] = new int[req.queries().size()];
+
+        try {
+            String sql = null;
+
+            for (JdbcQuery q : req.queries()) {
+                if (q.sql() != null)
+                    sql = q.sql();
+
+                SqlFieldsQuery qry = new SqlFieldsQuery(sql);
+
+                qry.setArgs(q.args());
+
+                qry.setDistributedJoins(distributedJoins);
+                qry.setEnforceJoinOrder(enforceJoinOrder);
+                qry.setCollocated(collocated);
+                qry.setReplicatedOnly(replicatedOnly);
+
+                qry.setSchema(schemaName);
+
+                QueryCursorImpl<List<?>> qryCur = (QueryCursorImpl<List<?>>)ctx.query()
+                    .querySqlFieldsNoCache(qry, true);
+
+                if (qryCur.isQuery())
+                    throw new IgniteCheckedException("Query produced result set [qry=" + q.sql() + ", args=" +
+                        Arrays.toString(q.args()) + ']');
+
+                List<List<?>> items = qryCur.getAll();
+
+                updCnts[successQueries++] = ((Long)items.get(0).get(0)).intValue();
+            }
+
+            return new JdbcResponse(new JdbcBatchExecuteResult(updCnts, SqlListenerResponse.STATUS_SUCCESS, null));
+        }
+        catch (Exception e) {
+            U.error(log, "Failed to execute batch query [reqId=" + req.requestId() + ", req=" + req + ']', e);
+
+            return new JdbcResponse(new JdbcBatchExecuteResult(Arrays.copyOf(updCnts, successQueries),
+                SqlListenerResponse.STATUS_FAILED, e.toString()));
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/1a7354fa/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResult.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResult.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResult.java
index 2d7666e..48affe9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResult.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/odbc/jdbc/JdbcResult.java
@@ -35,6 +35,9 @@ public class JdbcResult implements JdbcRawBinarylizable {
     /** Get columns meta query result. */
     public static final byte QRY_META = 4;
 
+    /** Batch queries. */
+    public static final byte BATCH_EXEC = 6;
+
     /** Success status. */
     private byte type;
 
@@ -70,14 +73,22 @@ public class JdbcResult implements JdbcRawBinarylizable {
         switch(resId) {
             case QRY_EXEC:
                 res = new JdbcQueryExecuteResult();
+
                 break;
 
             case QRY_FETCH:
                 res = new JdbcQueryFetchResult();
+
                 break;
 
             case QRY_META:
                 res = new JdbcQueryMetadataResult();
+
+                break;
+
+            case BATCH_EXEC:
+                res = new JdbcBatchExecuteResult();
+
                 break;
 
             default:


[26/30] ignite git commit: Merge remote-tracking branch 'community/ignite-2.1.3'

Posted by ag...@apache.org.
Merge remote-tracking branch 'community/ignite-2.1.3'


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/b5ad7296
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/b5ad7296
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/b5ad7296

Branch: refs/heads/ignite-5872
Commit: b5ad7296997185ed2d078614b3ed6e9a6f405670
Parents: 988ffe3 2e5c343
Author: Alexey Goncharuk <al...@gmail.com>
Authored: Thu Aug 10 12:08:41 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Thu Aug 10 12:08:41 2017 +0300

----------------------------------------------------------------------
 .../cache/persistence/tree/io/PagePartitionCountersIO.java         | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------



[18/30] ignite git commit: Merge remote-tracking branch 'origin/master'

Posted by ag...@apache.org.
Merge remote-tracking branch 'origin/master'


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/870ecf89
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/870ecf89
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/870ecf89

Branch: refs/heads/ignite-5872
Commit: 870ecf89d94c108c62442263e0ac298697d341d1
Parents: e28d0d6 c141ded
Author: devozerov <vo...@gridgain.com>
Authored: Tue Aug 8 15:17:18 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Tue Aug 8 15:17:18 2017 +0300

----------------------------------------------------------------------
 .../processors/cache/GridCacheAbstractLocalStoreSelfTest.java | 7 +++++++
 1 file changed, 7 insertions(+)
----------------------------------------------------------------------



[13/30] ignite git commit: IGNITE-5950 incorrect assertion fixed

Posted by ag...@apache.org.
IGNITE-5950 incorrect assertion fixed


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/2e5c343d
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/2e5c343d
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/2e5c343d

Branch: refs/heads/ignite-5872
Commit: 2e5c343d911e353c6d82630d09562664cc5e89e2
Parents: 0eedf46
Author: Sergey Chugunov <se...@gmail.com>
Authored: Mon Aug 7 11:34:01 2017 +0300
Committer: Sergey Chugunov <se...@gmail.com>
Committed: Mon Aug 7 11:34:01 2017 +0300

----------------------------------------------------------------------
 .../cache/persistence/tree/io/PagePartitionCountersIO.java         | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/2e5c343d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PagePartitionCountersIO.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PagePartitionCountersIO.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PagePartitionCountersIO.java
index 9bd806f..d5b81c1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PagePartitionCountersIO.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/PagePartitionCountersIO.java
@@ -129,7 +129,7 @@ public class PagePartitionCountersIO extends PageIO {
             long cacheSize = PageUtils.getLong(pageAddr, off);
             off += 8;
 
-            assert cacheSize > 0 : cacheSize;
+            assert cacheSize >= 0 : cacheSize;
 
             Long old = res.put(cacheId, cacheSize);
 


[21/30] ignite git commit: IGNITE-5897 Fix session init/end logic. This fixes tests.

Posted by ag...@apache.org.
IGNITE-5897 Fix session init/end logic. This fixes tests.

Signed-off-by: nikolay_tikhonov <nt...@gridgain.com>


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/5a559dfa
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/5a559dfa
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/5a559dfa

Branch: refs/heads/ignite-5872
Commit: 5a559dfa167db3ff90f35ac06624afc2688dacb9
Parents: aeafbf1
Author: Nikolay Izhikov <ni...@gmail.com>
Authored: Wed Aug 9 13:37:11 2017 +0300
Committer: nikolay_tikhonov <nt...@gridgain.com>
Committed: Wed Aug 9 13:37:11 2017 +0300

----------------------------------------------------------------------
 .../cache/store/CacheStoreManager.java          |  4 +++-
 .../store/GridCacheStoreManagerAdapter.java     | 20 +++++++++-----------
 .../cache/transactions/IgniteTxAdapter.java     |  9 +++++++--
 3 files changed, 19 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/5a559dfa/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/CacheStoreManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/CacheStoreManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/CacheStoreManager.java
index c56a25c..83428b3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/CacheStoreManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/CacheStoreManager.java
@@ -168,9 +168,11 @@ public interface CacheStoreManager extends GridCacheManager {
     /**
      * @param tx Transaction.
      * @param commit Commit.
+     * @param last {@code True} if this is last store in transaction.
+     * @param storeSessionEnded {@code True} if session for underlying store already ended.
      * @throws IgniteCheckedException If failed.
      */
-    public void sessionEnd(IgniteInternalTx tx, boolean commit, boolean last) throws IgniteCheckedException;
+    public void sessionEnd(IgniteInternalTx tx, boolean commit, boolean last, boolean storeSessionEnded) throws IgniteCheckedException;
 
     /**
      * End session initiated by write-behind store.

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a559dfa/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/GridCacheStoreManagerAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/GridCacheStoreManagerAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/GridCacheStoreManagerAdapter.java
index 83f07fb..9fe1f0c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/GridCacheStoreManagerAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/store/GridCacheStoreManagerAdapter.java
@@ -774,7 +774,8 @@ public abstract class GridCacheStoreManagerAdapter extends GridCacheManagerAdapt
     }
 
     /** {@inheritDoc} */
-    @Override public final void sessionEnd(IgniteInternalTx tx, boolean commit, boolean last) throws IgniteCheckedException {
+    @Override public final void sessionEnd(IgniteInternalTx tx, boolean commit, boolean last,
+        boolean storeSessionEnded) throws IgniteCheckedException {
         assert store != null;
 
         sessionInit0(tx);
@@ -785,7 +786,7 @@ public abstract class GridCacheStoreManagerAdapter extends GridCacheManagerAdapt
                     lsnr.onSessionEnd(locSes, commit);
             }
 
-            if (!sesHolder.get().ended(store))
+            if (!sesHolder.get().ended(store) && !storeSessionEnded)
                 store.sessionEnd(commit);
         }
         catch (Throwable e) {
@@ -854,7 +855,7 @@ public abstract class GridCacheStoreManagerAdapter extends GridCacheManagerAdapt
         sesHolder.set(ses);
 
         try {
-            if (sesLsnrs != null && !ses.started(this)) {
+            if (!ses.started(store) && sesLsnrs != null) {
                 for (CacheStoreSessionListener lsnr : sesLsnrs)
                     lsnr.onSessionStart(locSes);
             }
@@ -918,11 +919,8 @@ public abstract class GridCacheStoreManagerAdapter extends GridCacheManagerAdapt
         private Object attach;
 
         /** */
-        private final Set<CacheStoreManager> started =
-            new GridSetWrapper<>(new IdentityHashMap<CacheStoreManager, Object>());
-
-        /** */
-        private final Set<CacheStore> ended = new GridSetWrapper<>(new IdentityHashMap<CacheStore, Object>());
+        private final Set<CacheStore> started =
+            new GridSetWrapper<>(new IdentityHashMap<CacheStore, Object>());
 
         /**
          * @param tx Current transaction.
@@ -985,8 +983,8 @@ public abstract class GridCacheStoreManagerAdapter extends GridCacheManagerAdapt
         /**
          * @return If session is started.
          */
-        private boolean started(CacheStoreManager mgr) {
-            return !started.add(mgr);
+        private boolean started(CacheStore store) {
+            return !started.add(store);
         }
 
         /**
@@ -994,7 +992,7 @@ public abstract class GridCacheStoreManagerAdapter extends GridCacheManagerAdapt
          * @return Whether session already ended on this store instance.
          */
         private boolean ended(CacheStore store) {
-            return !ended.add(store);
+            return !started.remove(store);
         }
 
         /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/5a559dfa/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
index 61ca78c..eccb9c1 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
@@ -27,6 +27,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.IdentityHashMap;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -39,6 +40,7 @@ import javax.cache.expiry.ExpiryPolicy;
 import javax.cache.processor.EntryProcessor;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.cache.store.CacheStore;
 import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
@@ -60,6 +62,7 @@ import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
 import org.apache.ignite.internal.processors.cache.version.GridCacheVersionConflictContext;
 import org.apache.ignite.internal.processors.cache.version.GridCacheVersionedEntryEx;
 import org.apache.ignite.internal.transactions.IgniteTxTimeoutCheckedException;
+import org.apache.ignite.internal.util.GridSetWrapper;
 import org.apache.ignite.internal.util.future.GridFutureAdapter;
 import org.apache.ignite.internal.util.lang.GridMetadataAwareAdapter;
 import org.apache.ignite.internal.util.lang.GridTuple;
@@ -1159,13 +1162,15 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter implement
      * @param commit Commit flag.
      * @throws IgniteCheckedException In case of error.
      */
-    protected void sessionEnd(Collection<CacheStoreManager> stores, boolean commit) throws IgniteCheckedException {
+    protected void sessionEnd(final Collection<CacheStoreManager> stores, boolean commit) throws IgniteCheckedException {
         Iterator<CacheStoreManager> it = stores.iterator();
 
+        Set<CacheStore> visited = new GridSetWrapper<>(new IdentityHashMap<CacheStore, Object>());
+
         while (it.hasNext()) {
             CacheStoreManager store = it.next();
 
-            store.sessionEnd(this, commit, !it.hasNext());
+            store.sessionEnd(this, commit, !it.hasNext(), !visited.add(store.store()));
         }
     }
 


[23/30] ignite git commit: ignite-5918 Adding and searching objects in index tree produces a lot of garbage

Posted by ag...@apache.org.
ignite-5918 Adding and searching objects in index tree produces a lot of garbage


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/0e0c2c7d
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/0e0c2c7d
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/0e0c2c7d

Branch: refs/heads/ignite-5872
Commit: 0e0c2c7dc6cece3cc92a13c5430af605606bbcfe
Parents: 8d6e842
Author: Igor Seliverstov <gv...@gmail.com>
Authored: Wed Aug 9 18:46:53 2017 +0300
Committer: Yakov Zhdanov <yz...@gridgain.com>
Committed: Wed Aug 9 18:46:53 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/0e0c2c7d/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/0e0c2c7d/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 eb579c3..d186623 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/0e0c2c7d/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/0e0c2c7d/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/0e0c2c7d/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);
 


[20/30] ignite git commit: IGNITE-5734 Web Console: Fixed npm dependencies.

Posted by ag...@apache.org.
IGNITE-5734 Web Console: Fixed npm dependencies.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/aeafbf10
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/aeafbf10
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/aeafbf10

Branch: refs/heads/ignite-5872
Commit: aeafbf10c13af75556a019749e54c9e4251d91b7
Parents: ebed404
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Wed Aug 9 17:22:54 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Wed Aug 9 17:22:54 2017 +0700

----------------------------------------------------------------------
 modules/web-console/frontend/package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/aeafbf10/modules/web-console/frontend/package.json
----------------------------------------------------------------------
diff --git a/modules/web-console/frontend/package.json b/modules/web-console/frontend/package.json
index 6b049ff..f96c322 100644
--- a/modules/web-console/frontend/package.json
+++ b/modules/web-console/frontend/package.json
@@ -57,7 +57,7 @@
     "babel-polyfill": "6.23.0",
     "babel-preset-es2015": "6.24.1",
     "babel-preset-stage-1": "6.24.1",
-    "babel-runtime": "6.23.0",
+    "babel-runtime": "6.25.0",
     "bootstrap-sass": "3.3.7",
     "brace": "0.10.0",
     "copy-webpack-plugin": "4.0.1",


[15/30] ignite git commit: IGNITE-5211: Added new constructor: QueryEntity(Class keyCls, Class valCls). This closes #2371. This closes #2388. This closes #2407.

Posted by ag...@apache.org.
IGNITE-5211: Added new constructor: QueryEntity(Class keyCls, Class valCls). This closes #2371. This closes #2388. This closes #2407.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/9da69389
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/9da69389
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/9da69389

Branch: refs/heads/ignite-5872
Commit: 9da69389ed307357391e4eb87ae077751f30a58e
Parents: 488a6d2
Author: tledkov-gridgain <tl...@gridgain.com>
Authored: Tue Aug 8 12:05:36 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Tue Aug 8 12:05:36 2017 +0300

----------------------------------------------------------------------
 .../org/apache/ignite/cache/QueryEntity.java    | 229 +++++++
 .../configuration/CacheConfiguration.java       | 615 +------------------
 .../cache/query/QueryEntityClassProperty.java   | 116 ++++
 .../cache/query/QueryEntityIndexDescriptor.java | 121 ++++
 .../cache/query/QueryEntityTypeDescriptor.java  | 219 +++++++
 .../h2/sql/AbstractH2CompareQueryTest.java      |   4 +-
 6 files changed, 693 insertions(+), 611 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/9da69389/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java b/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
index 955e7d2..5180100 100644
--- a/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
+++ b/modules/core/src/main/java/org/apache/ignite/cache/QueryEntity.java
@@ -18,7 +18,9 @@
 package org.apache.ignite.cache;
 
 import java.io.Serializable;
+import java.lang.reflect.Field;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -27,10 +29,20 @@ import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import javax.cache.CacheException;
+import org.apache.ignite.cache.query.annotations.QueryGroupIndex;
+import org.apache.ignite.cache.query.annotations.QuerySqlField;
+import org.apache.ignite.cache.query.annotations.QueryTextField;
+import org.apache.ignite.internal.processors.cache.query.QueryEntityClassProperty;
+import org.apache.ignite.internal.processors.cache.query.QueryEntityTypeDescriptor;
+import org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor;
+import org.apache.ignite.internal.processors.query.QueryUtils;
 import org.apache.ignite.internal.util.tostring.GridToStringInclude;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.A;
 import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.jetbrains.annotations.Nullable;
 
 /**
  * Query entity is a description of {@link org.apache.ignite.IgniteCache cache} entry (composed of key and value)
@@ -111,6 +123,16 @@ public class QueryEntity implements Serializable {
     }
 
     /**
+     * Creates a query entity with the given key and value types.
+     *
+     * @param keyCls Key type.
+     * @param valCls Value type.
+     */
+    public QueryEntity(Class<?> keyCls, Class<?> valCls) {
+        this(convert(processKeyAndValueClasses(keyCls,valCls)));
+    }
+
+    /**
      * Gets key type for this query pair.
      *
      * @return Key type.
@@ -351,6 +373,213 @@ public class QueryEntity implements Serializable {
         return this;
     }
 
+    /**
+     * @param desc Type descriptor.
+     * @return Type metadata.
+     */
+    private static QueryEntity convert(QueryEntityTypeDescriptor desc) {
+        QueryEntity entity = new QueryEntity();
+
+        // Key and val types.
+        entity.setKeyType(desc.keyClass().getName());
+        entity.setValueType(desc.valueClass().getName());
+
+        for (QueryEntityClassProperty prop : desc.properties().values())
+            entity.addQueryField(prop.fullName(), U.box(prop.type()).getName(), prop.alias());
+
+        entity.setKeyFields(desc.keyProperties());
+
+        QueryIndex txtIdx = null;
+
+        Collection<QueryIndex> idxs = new ArrayList<>();
+
+        for (Map.Entry<String, GridQueryIndexDescriptor> idxEntry : desc.indexes().entrySet()) {
+            GridQueryIndexDescriptor idx = idxEntry.getValue();
+
+            if (idx.type() == QueryIndexType.FULLTEXT) {
+                assert txtIdx == null;
+
+                txtIdx = new QueryIndex();
+
+                txtIdx.setIndexType(QueryIndexType.FULLTEXT);
+
+                txtIdx.setFieldNames(idx.fields(), true);
+                txtIdx.setName(idxEntry.getKey());
+            }
+            else {
+                QueryIndex sortedIdx = new QueryIndex();
+
+                sortedIdx.setIndexType(idx.type());
+
+                LinkedHashMap<String, Boolean> fields = new LinkedHashMap<>();
+
+                for (String f : idx.fields())
+                    fields.put(f, !idx.descending(f));
+
+                sortedIdx.setFields(fields);
+
+                sortedIdx.setName(idxEntry.getKey());
+
+                idxs.add(sortedIdx);
+            }
+        }
+
+        if (desc.valueTextIndex()) {
+            if (txtIdx == null) {
+                txtIdx = new QueryIndex();
+
+                txtIdx.setIndexType(QueryIndexType.FULLTEXT);
+
+                txtIdx.setFieldNames(Arrays.asList(QueryUtils.VAL_FIELD_NAME), true);
+            }
+            else
+                txtIdx.getFields().put(QueryUtils.VAL_FIELD_NAME, true);
+        }
+
+        if (txtIdx != null)
+            idxs.add(txtIdx);
+
+        if (!F.isEmpty(idxs))
+            entity.setIndexes(idxs);
+
+        return entity;
+    }
+
+    /**
+     * @param keyCls Key class.
+     * @param valCls Value class.
+     * @return Type descriptor.
+     */
+    private static QueryEntityTypeDescriptor processKeyAndValueClasses(
+        Class<?> keyCls,
+        Class<?> valCls
+    ) {
+        QueryEntityTypeDescriptor d = new QueryEntityTypeDescriptor();
+
+        d.keyClass(keyCls);
+        d.valueClass(valCls);
+
+        processAnnotationsInClass(true, d.keyClass(), d, null);
+        processAnnotationsInClass(false, d.valueClass(), d, null);
+
+        return d;
+    }
+
+    /**
+     * Process annotations for class.
+     *
+     * @param key If given class relates to key.
+     * @param cls Class.
+     * @param type Type descriptor.
+     * @param parent Parent in case of embeddable.
+     */
+    private static void processAnnotationsInClass(boolean key, Class<?> cls, QueryEntityTypeDescriptor type,
+        @Nullable QueryEntityClassProperty parent) {
+        if (U.isJdk(cls) || QueryUtils.isGeometryClass(cls)) {
+            if (parent == null && !key && QueryUtils.isSqlType(cls)) { // We have to index primitive _val.
+                String idxName = cls.getSimpleName() + "_" + QueryUtils.VAL_FIELD_NAME + "_idx";
+
+                type.addIndex(idxName, QueryUtils.isGeometryClass(cls) ?
+                    QueryIndexType.GEOSPATIAL : QueryIndexType.SORTED);
+
+                type.addFieldToIndex(idxName, QueryUtils.VAL_FIELD_NAME, 0, false);
+            }
+
+            return;
+        }
+
+        if (parent != null && parent.knowsClass(cls))
+            throw new CacheException("Recursive reference found in type: " + cls.getName());
+
+        if (parent == null) { // Check class annotation at top level only.
+            QueryTextField txtAnnCls = cls.getAnnotation(QueryTextField.class);
+
+            if (txtAnnCls != null)
+                type.valueTextIndex(true);
+
+            QueryGroupIndex grpIdx = cls.getAnnotation(QueryGroupIndex.class);
+
+            if (grpIdx != null)
+                type.addIndex(grpIdx.name(), QueryIndexType.SORTED);
+
+            QueryGroupIndex.List grpIdxList = cls.getAnnotation(QueryGroupIndex.List.class);
+
+            if (grpIdxList != null && !F.isEmpty(grpIdxList.value())) {
+                for (QueryGroupIndex idx : grpIdxList.value())
+                    type.addIndex(idx.name(), QueryIndexType.SORTED);
+            }
+        }
+
+        for (Class<?> c = cls; c != null && !c.equals(Object.class); c = c.getSuperclass()) {
+            for (Field field : c.getDeclaredFields()) {
+                QuerySqlField sqlAnn = field.getAnnotation(QuerySqlField.class);
+                QueryTextField txtAnn = field.getAnnotation(QueryTextField.class);
+
+                if (sqlAnn != null || txtAnn != null) {
+                    QueryEntityClassProperty prop = new QueryEntityClassProperty(field);
+
+                    prop.parent(parent);
+
+                    // Add parent property before its possible nested properties so that
+                    // resulting parent column comes before columns corresponding to those
+                    // nested properties in the resulting table - that way nested
+                    // properties override will happen properly (first parent, then children).
+                    type.addProperty(prop, key, true);
+
+                    processAnnotation(key, sqlAnn, txtAnn, cls, c, field.getType(), prop, type);
+                }
+            }
+        }
+    }
+
+    /**
+     * Processes annotation at field or method.
+     *
+     * @param key If given class relates to key.
+     * @param sqlAnn SQL annotation, can be {@code null}.
+     * @param txtAnn H2 text annotation, can be {@code null}.
+     * @param cls Entity class.
+     * @param curCls Current entity class.
+     * @param fldCls Class of field or return type for method.
+     * @param prop Current property.
+     * @param desc Class description.
+     */
+    private static void processAnnotation(boolean key, QuerySqlField sqlAnn, QueryTextField txtAnn,
+        Class<?> cls, Class<?> curCls, Class<?> fldCls, QueryEntityClassProperty prop, QueryEntityTypeDescriptor desc) {
+        if (sqlAnn != null) {
+            processAnnotationsInClass(key, fldCls, desc, prop);
+
+            if (!sqlAnn.name().isEmpty())
+                prop.alias(sqlAnn.name());
+
+            if (sqlAnn.index()) {
+                String idxName = curCls.getSimpleName() + "_" + prop.alias() + "_idx";
+
+                if (cls != curCls)
+                    idxName = cls.getSimpleName() + "_" + idxName;
+
+                desc.addIndex(idxName, QueryUtils.isGeometryClass(prop.type()) ?
+                    QueryIndexType.GEOSPATIAL : QueryIndexType.SORTED);
+
+                desc.addFieldToIndex(idxName, prop.fullName(), 0, sqlAnn.descending());
+            }
+
+            if (!F.isEmpty(sqlAnn.groups())) {
+                for (String group : sqlAnn.groups())
+                    desc.addFieldToIndex(group, prop.fullName(), 0, false);
+            }
+
+            if (!F.isEmpty(sqlAnn.orderedGroups())) {
+                for (QuerySqlField.Group idx : sqlAnn.orderedGroups())
+                    desc.addFieldToIndex(idx.name(), prop.fullName(), idx.order(), idx.descending());
+            }
+        }
+
+        if (txtAnn != null)
+            desc.addFieldToTextIndex(prop.fullName());
+    }
+
+
     /** {@inheritDoc} */
     @Override public boolean equals(Object o) {
         if (this == o)

http://git-wip-us.apache.org/repos/asf/ignite/blob/9da69389/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 708913a..2b4ec1d 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
@@ -18,21 +18,10 @@
 package org.apache.ignite.configuration;
 
 import java.io.Serializable;
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Field;
-import java.lang.reflect.Member;
-import java.lang.reflect.Method;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
 import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
 import javax.cache.Cache;
 import javax.cache.CacheException;
 import javax.cache.configuration.CacheEntryListenerConfiguration;
@@ -53,26 +42,17 @@ import org.apache.ignite.cache.CacheRebalanceMode;
 import org.apache.ignite.cache.CacheWriteSynchronizationMode;
 import org.apache.ignite.cache.PartitionLossPolicy;
 import org.apache.ignite.cache.QueryEntity;
-import org.apache.ignite.cache.QueryIndex;
-import org.apache.ignite.cache.QueryIndexType;
 import org.apache.ignite.cache.affinity.AffinityFunction;
 import org.apache.ignite.cache.affinity.AffinityKeyMapper;
 import org.apache.ignite.cache.eviction.EvictionFilter;
 import org.apache.ignite.cache.eviction.EvictionPolicy;
-import org.apache.ignite.cache.query.annotations.QueryGroupIndex;
-import org.apache.ignite.cache.query.annotations.QuerySqlField;
 import org.apache.ignite.cache.query.annotations.QuerySqlFunction;
-import org.apache.ignite.cache.query.annotations.QueryTextField;
 import org.apache.ignite.cache.store.CacheStore;
 import org.apache.ignite.cache.store.CacheStoreSessionListener;
 import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.internal.binary.BinaryContext;
-import org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor;
 import org.apache.ignite.internal.processors.query.QueryUtils;
-import org.apache.ignite.internal.util.tostring.GridToStringExclude;
-import org.apache.ignite.internal.util.tostring.GridToStringInclude;
 import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.util.typedef.T2;
 import org.apache.ignite.internal.util.typedef.internal.A;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
@@ -1768,14 +1748,12 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
             Class<?> keyCls = newIndexedTypes[i];
             Class<?> valCls = newIndexedTypes[i + 1];
 
-            TypeDescriptor desc = processKeyAndValueClasses(keyCls, valCls);
-
-            QueryEntity converted = convert(desc);
+            QueryEntity newEntity = new QueryEntity(keyCls, valCls);
 
             boolean dup = false;
 
             for (QueryEntity entity : qryEntities) {
-                if (F.eq(entity.findValueType(), converted.findValueType())) {
+                if (F.eq(entity.findValueType(), newEntity.findValueType())) {
                     dup = true;
 
                     break;
@@ -1783,13 +1761,13 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
             }
 
             if (!dup)
-                qryEntities.add(converted);
+                qryEntities.add(newEntity);
 
             // Set key configuration if needed.
-            String affFieldName = desc.affinityFieldName();
+            String affFieldName = BinaryContext.affinityFieldName(keyCls);
 
             if (affFieldName != null) {
-                CacheKeyConfiguration newKeyCfg = new CacheKeyConfiguration(converted.getKeyType(), affFieldName);
+                CacheKeyConfiguration newKeyCfg = new CacheKeyConfiguration(newEntity.getKeyType(), affFieldName);
 
                 if (F.isEmpty(keyCfg))
                     keyCfg = new CacheKeyConfiguration[] { newKeyCfg };
@@ -2041,77 +2019,6 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
         return cfg;
     }
 
-    /**
-     * @param desc Type descriptor.
-     * @return Type metadata.
-     */
-    private static QueryEntity convert(TypeDescriptor desc) {
-        QueryEntity entity = new QueryEntity();
-
-        // Key and val types.
-        entity.setKeyType(desc.keyClass().getName());
-        entity.setValueType(desc.valueClass().getName());
-
-        for (ClassProperty prop : desc.props.values())
-            entity.addQueryField(prop.fullName(), U.box(prop.type()).getName(), prop.alias());
-
-        entity.setKeyFields(desc.keyProps);
-
-        QueryIndex txtIdx = null;
-
-        Collection<QueryIndex> idxs = new ArrayList<>();
-
-        for (Map.Entry<String, GridQueryIndexDescriptor> idxEntry : desc.indexes().entrySet()) {
-            GridQueryIndexDescriptor idx = idxEntry.getValue();
-
-            if (idx.type() == QueryIndexType.FULLTEXT) {
-                assert txtIdx == null;
-
-                txtIdx = new QueryIndex();
-
-                txtIdx.setIndexType(QueryIndexType.FULLTEXT);
-
-                txtIdx.setFieldNames(idx.fields(), true);
-                txtIdx.setName(idxEntry.getKey());
-            }
-            else {
-                QueryIndex sortedIdx = new QueryIndex();
-
-                sortedIdx.setIndexType(idx.type());
-
-                LinkedHashMap<String, Boolean> fields = new LinkedHashMap<>();
-
-                for (String f : idx.fields())
-                    fields.put(f, !idx.descending(f));
-
-                sortedIdx.setFields(fields);
-
-                sortedIdx.setName(idxEntry.getKey());
-
-                idxs.add(sortedIdx);
-            }
-        }
-
-        if (desc.valueTextIndex()) {
-            if (txtIdx == null) {
-                txtIdx = new QueryIndex();
-
-                txtIdx.setIndexType(QueryIndexType.FULLTEXT);
-
-                txtIdx.setFieldNames(Arrays.asList(QueryUtils.VAL_FIELD_NAME), true);
-            }
-            else
-                txtIdx.getFields().put(QueryUtils.VAL_FIELD_NAME, true);
-        }
-
-        if (txtIdx != null)
-            idxs.add(txtIdx);
-
-        if (!F.isEmpty(idxs))
-            entity.setIndexes(idxs);
-
-        return entity;
-    }
 
     /**
      * @param cls Class.
@@ -2123,141 +2030,6 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
         return QueryUtils.isSqlType(cls) ? cls : Object.class;
     }
 
-    /**
-     * @param keyCls Key class.
-     * @param valCls Value class.
-     * @return Type descriptor.
-     */
-    static TypeDescriptor processKeyAndValueClasses(
-        Class<?> keyCls,
-        Class<?> valCls
-    ) {
-        TypeDescriptor d = new TypeDescriptor();
-
-        d.keyClass(keyCls);
-        d.valueClass(valCls);
-
-        d.affinityFieldName(BinaryContext.affinityFieldName(keyCls));
-
-        processAnnotationsInClass(true, d.keyCls, d, null);
-        processAnnotationsInClass(false, d.valCls, d, null);
-
-        return d;
-    }
-
-    /**
-     * Process annotations for class.
-     *
-     * @param key If given class relates to key.
-     * @param cls Class.
-     * @param type Type descriptor.
-     * @param parent Parent in case of embeddable.
-     */
-    private static void processAnnotationsInClass(boolean key, Class<?> cls, TypeDescriptor type,
-        @Nullable ClassProperty parent) {
-        if (U.isJdk(cls) || QueryUtils.isGeometryClass(cls)) {
-            if (parent == null && !key && QueryUtils.isSqlType(cls)) { // We have to index primitive _val.
-                String idxName = cls.getSimpleName() + "_" + QueryUtils.VAL_FIELD_NAME + "_idx";
-
-                type.addIndex(idxName, QueryUtils.isGeometryClass(cls) ?
-                    QueryIndexType.GEOSPATIAL : QueryIndexType.SORTED);
-
-                type.addFieldToIndex(idxName, QueryUtils.VAL_FIELD_NAME, 0, false);
-            }
-
-            return;
-        }
-
-        if (parent != null && parent.knowsClass(cls))
-            throw new CacheException("Recursive reference found in type: " + cls.getName());
-
-        if (parent == null) { // Check class annotation at top level only.
-            QueryTextField txtAnnCls = cls.getAnnotation(QueryTextField.class);
-
-            if (txtAnnCls != null)
-                type.valueTextIndex(true);
-
-            QueryGroupIndex grpIdx = cls.getAnnotation(QueryGroupIndex.class);
-
-            if (grpIdx != null)
-                type.addIndex(grpIdx.name(), QueryIndexType.SORTED);
-
-            QueryGroupIndex.List grpIdxList = cls.getAnnotation(QueryGroupIndex.List.class);
-
-            if (grpIdxList != null && !F.isEmpty(grpIdxList.value())) {
-                for (QueryGroupIndex idx : grpIdxList.value())
-                    type.addIndex(idx.name(), QueryIndexType.SORTED);
-            }
-        }
-
-        for (Class<?> c = cls; c != null && !c.equals(Object.class); c = c.getSuperclass()) {
-            for (Field field : c.getDeclaredFields()) {
-                QuerySqlField sqlAnn = field.getAnnotation(QuerySqlField.class);
-                QueryTextField txtAnn = field.getAnnotation(QueryTextField.class);
-
-                if (sqlAnn != null || txtAnn != null) {
-                    ClassProperty prop = new ClassProperty(field);
-
-                    prop.parent(parent);
-
-                    // Add parent property before its possible nested properties so that
-                    // resulting parent column comes before columns corresponding to those
-                    // nested properties in the resulting table - that way nested
-                    // properties override will happen properly (first parent, then children).
-                    type.addProperty(prop, key, true);
-
-                    processAnnotation(key, sqlAnn, txtAnn, cls, c, field.getType(), prop, type);
-                }
-            }
-        }
-    }
-
-    /**
-     * Processes annotation at field or method.
-     *
-     * @param key If given class relates to key.
-     * @param sqlAnn SQL annotation, can be {@code null}.
-     * @param txtAnn H2 text annotation, can be {@code null}.
-     * @param cls Entity class.
-     * @param curCls Current entity class.
-     * @param fldCls Class of field or return type for method.
-     * @param prop Current property.
-     * @param desc Class description.
-     */
-    private static void processAnnotation(boolean key, QuerySqlField sqlAnn, QueryTextField txtAnn,
-        Class<?> cls, Class<?> curCls, Class<?> fldCls, ClassProperty prop, TypeDescriptor desc) {
-        if (sqlAnn != null) {
-            processAnnotationsInClass(key, fldCls, desc, prop);
-
-            if (!sqlAnn.name().isEmpty())
-                prop.alias(sqlAnn.name());
-
-            if (sqlAnn.index()) {
-                String idxName = curCls.getSimpleName() + "_" + prop.alias() + "_idx";
-
-                if (cls != curCls)
-                    idxName = cls.getSimpleName() + "_" + idxName;
-
-                desc.addIndex(idxName, QueryUtils.isGeometryClass(prop.type()) ?
-                    QueryIndexType.GEOSPATIAL : QueryIndexType.SORTED);
-
-                desc.addFieldToIndex(idxName, prop.fullName(), 0, sqlAnn.descending());
-            }
-
-            if (!F.isEmpty(sqlAnn.groups())) {
-                for (String group : sqlAnn.groups())
-                    desc.addFieldToIndex(group, prop.fullName(), 0, false);
-            }
-
-            if (!F.isEmpty(sqlAnn.orderedGroups())) {
-                for (QuerySqlField.Group idx : sqlAnn.orderedGroups())
-                    desc.addFieldToIndex(idx.name(), prop.fullName(), idx.order(), idx.descending());
-            }
-        }
-
-        if (txtAnn != null)
-            desc.addFieldToTextIndex(prop.fullName());
-    }
 
     /** {@inheritDoc} */
     @Override public CacheConfiguration<K, V> setStatisticsEnabled(boolean enabled) {
@@ -2370,381 +2142,4 @@ public class CacheConfiguration<K, V> extends MutableConfiguration<K, V> {
             return "IgniteAllNodesPredicate []";
         }
     }
-
-    /**
-     * Descriptor of type.
-     */
-    private static class TypeDescriptor {
-        /** Value field names and types with preserved order. */
-        @GridToStringInclude
-        private final Map<String, Class<?>> fields = new LinkedHashMap<>();
-
-        /** */
-        @GridToStringExclude
-        private final Map<String, ClassProperty> props = new LinkedHashMap<>();
-
-        /** */
-        @GridToStringInclude
-        private final Set<String> keyProps = new HashSet<>();
-
-        /** */
-        @GridToStringInclude
-        private final Map<String, IndexDescriptor> indexes = new HashMap<>();
-
-        /** */
-        private IndexDescriptor fullTextIdx;
-
-        /** */
-        private Class<?> keyCls;
-
-        /** */
-        private Class<?> valCls;
-
-        /** */
-        private boolean valTextIdx;
-
-        /** Affinity field name. */
-        private String affFieldName;
-
-        /**
-         * @return Indexes.
-         */
-        public Map<String, GridQueryIndexDescriptor> indexes() {
-            return Collections.<String, GridQueryIndexDescriptor>unmodifiableMap(indexes);
-        }
-
-        /**
-         * Adds index.
-         *
-         * @param idxName Index name.
-         * @param type Index type.
-         * @param inlineSize Inline size.
-         * @return Index descriptor.
-         */
-        public IndexDescriptor addIndex(String idxName, QueryIndexType type, int inlineSize) {
-            IndexDescriptor idx = new IndexDescriptor(type, inlineSize);
-
-            if (indexes.put(idxName, idx) != null)
-                throw new CacheException("Index with name '" + idxName + "' already exists.");
-
-            return idx;
-        }
-
-        /**
-         * Adds index.
-         *
-         * @param idxName Index name.
-         * @param type Index type.
-         * @return Index descriptor.
-         */
-        public IndexDescriptor addIndex(String idxName, QueryIndexType type) {
-            return addIndex(idxName, type, -1);
-        }
-
-        /**
-         * Adds field to index.
-         *
-         * @param idxName Index name.
-         * @param field Field name.
-         * @param orderNum Fields order number in index.
-         * @param descending Sorting order.
-         */
-        public void addFieldToIndex(String idxName, String field, int orderNum,
-            boolean descending) {
-            IndexDescriptor desc = indexes.get(idxName);
-
-            if (desc == null)
-                desc = addIndex(idxName, QueryIndexType.SORTED);
-
-            desc.addField(field, orderNum, descending);
-        }
-
-        /**
-         * Adds field to text index.
-         *
-         * @param field Field name.
-         */
-        public void addFieldToTextIndex(String field) {
-            if (fullTextIdx == null) {
-                fullTextIdx = new IndexDescriptor(QueryIndexType.FULLTEXT);
-
-                indexes.put(null, fullTextIdx);
-            }
-
-            fullTextIdx.addField(field, 0, false);
-        }
-
-        /**
-         * @return Value class.
-         */
-        public Class<?> valueClass() {
-            return valCls;
-        }
-
-        /**
-         * Sets value class.
-         *
-         * @param valCls Value class.
-         */
-        void valueClass(Class<?> valCls) {
-            this.valCls = valCls;
-        }
-
-        /**
-         * @return Key class.
-         */
-        public Class<?> keyClass() {
-            return keyCls;
-        }
-
-        /**
-         * Set key class.
-         *
-         * @param keyCls Key class.
-         */
-        void keyClass(Class<?> keyCls) {
-            this.keyCls = keyCls;
-        }
-
-        /**
-         * @return Affinity field name.
-         */
-        @Nullable public String affinityFieldName() {
-            return affFieldName;
-        }
-
-        /**
-         * @param affFieldName Affinity field name.
-         */
-        private void affinityFieldName(@Nullable String affFieldName) {
-            this.affFieldName = affFieldName;
-        }
-
-        /**
-         * Adds property to the type descriptor.
-         *
-         * @param prop Property.
-         * @param key Property ownership flag (key or not).
-         * @param failOnDuplicate Fail on duplicate flag.
-         */
-        void addProperty(ClassProperty prop, boolean key, boolean failOnDuplicate) {
-            String name = prop.fullName();
-
-            if (props.put(name, prop) != null && failOnDuplicate)
-                throw new CacheException("Property with name '" + name + "' already exists.");
-
-            fields.put(name, prop.type());
-
-            if (key)
-                keyProps.add(name);
-        }
-
-        /**
-         * @return {@code true} If we need to have a fulltext index on value.
-         */
-        public boolean valueTextIndex() {
-            return valTextIdx;
-        }
-
-        /**
-         * Sets if this value should be text indexed.
-         *
-         * @param valTextIdx Flag value.
-         */
-        public void valueTextIndex(boolean valTextIdx) {
-            this.valTextIdx = valTextIdx;
-        }
-
-        /** {@inheritDoc} */
-        @Override public String toString() {
-            return S.toString(TypeDescriptor.class, this);
-        }
-    }
-
-    /**
-     * Index descriptor.
-     */
-    private static class IndexDescriptor implements GridQueryIndexDescriptor {
-        /** Fields sorted by order number. */
-        private final Collection<T2<String, Integer>> fields = new TreeSet<>(
-            new Comparator<T2<String, Integer>>() {
-                @Override public int compare(T2<String, Integer> o1, T2<String, Integer> o2) {
-                    if (o1.get2().equals(o2.get2())) // Order is equal, compare field names to avoid replace in Set.
-                        return o1.get1().compareTo(o2.get1());
-
-                    return o1.get2() < o2.get2() ? -1 : 1;
-                }
-            });
-
-        /** Fields which should be indexed in descending order. */
-        private Collection<String> descendings;
-
-        /** */
-        private final QueryIndexType type;
-
-        /** */
-        private final int inlineSize;
-
-        /**
-         * @param type Type.
-         * @param inlineSize Inline size.
-         */
-        private IndexDescriptor(QueryIndexType type, int inlineSize) {
-            assert type != null;
-
-            this.type = type;
-            this.inlineSize = inlineSize;
-        }
-
-        /**
-         * @param type Type.
-         */
-        private IndexDescriptor(QueryIndexType type) {
-            this(type, -1);
-        }
-
-        /** {@inheritDoc} */
-        @Override public String name() {
-            return null;
-        }
-
-        /** {@inheritDoc} */
-        @Override public Collection<String> fields() {
-            Collection<String> res = new ArrayList<>(fields.size());
-
-            for (T2<String, Integer> t : fields)
-                res.add(t.get1());
-
-            return res;
-        }
-
-        /** {@inheritDoc} */
-        @Override public boolean descending(String field) {
-            return descendings != null && descendings.contains(field);
-        }
-
-        /**
-         * Adds field to this index.
-         *
-         * @param field Field name.
-         * @param orderNum Field order number in this index.
-         * @param descending Sort order.
-         */
-        public void addField(String field, int orderNum, boolean descending) {
-            fields.add(new T2<>(field, orderNum));
-
-            if (descending) {
-                if (descendings == null)
-                    descendings = new HashSet<>();
-
-                descendings.add(field);
-            }
-        }
-
-        /** {@inheritDoc} */
-        @Override public QueryIndexType type() {
-            return type;
-        }
-
-        /** {@inheritDoc} */
-        @Override public int inlineSize() {
-            return inlineSize;
-        }
-
-        /** {@inheritDoc} */
-        @Override public String toString() {
-            return S.toString(IndexDescriptor.class, this);
-        }
-    }
-
-    /**
-     * Description of type property.
-     */
-    private static class ClassProperty {
-        /** */
-        private final Member member;
-
-        /** */
-        private ClassProperty parent;
-
-        /** */
-        private String name;
-
-        /** */
-        private String alias;
-
-        /**
-         * Constructor.
-         *
-         * @param member Element.
-         */
-        ClassProperty(Member member) {
-            this.member = member;
-
-            name = member.getName();
-
-            if (member instanceof Method) {
-                if (member.getName().startsWith("get") && member.getName().length() > 3)
-                    name = member.getName().substring(3);
-
-                if (member.getName().startsWith("is") && member.getName().length() > 2)
-                    name = member.getName().substring(2);
-            }
-
-            ((AccessibleObject)member).setAccessible(true);
-        }
-
-        /**
-         * @param alias Alias.
-         */
-        public void alias(String alias) {
-            this.alias = alias;
-        }
-
-        /**
-         * @return Alias.
-         */
-        String alias() {
-            return F.isEmpty(alias) ? name : alias;
-        }
-
-        /**
-         * @return Type.
-         */
-        public Class<?> type() {
-            return member instanceof Field ? ((Field)member).getType() : ((Method)member).getReturnType();
-        }
-
-        /**
-         * @param parent Parent property if this is embeddable element.
-         */
-        public void parent(ClassProperty parent) {
-            this.parent = parent;
-        }
-
-        /** {@inheritDoc} */
-        @Override public String toString() {
-            return S.toString(ClassProperty.class, this);
-        }
-
-        /**
-         * @param cls Class.
-         * @return {@code true} If this property or some parent relates to member of the given class.
-         */
-        public boolean knowsClass(Class<?> cls) {
-            return member.getDeclaringClass() == cls || (parent != null && parent.knowsClass(cls));
-        }
-
-        /**
-         * @return Full name with all parents in dot notation.
-         */
-        public String fullName() {
-            assert name != null;
-
-            if (parent == null)
-                return name;
-
-            return parent.fullName() + '.' + name;
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/9da69389/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityClassProperty.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityClassProperty.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityClassProperty.java
new file mode 100644
index 0000000..e21b73c
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityClassProperty.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache.query;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * Description of type property.
+ */
+public class QueryEntityClassProperty {
+    /** */
+    private final Member member;
+
+    /** */
+    private QueryEntityClassProperty parent;
+
+    /** */
+    private String name;
+
+    /** */
+    private String alias;
+
+    /**
+     * Constructor.
+     *
+     * @param member Element.
+     */
+    public QueryEntityClassProperty(Member member) {
+        this.member = member;
+
+        name = member.getName();
+
+        if (member instanceof Method) {
+            if (member.getName().startsWith("get") && member.getName().length() > 3)
+                name = member.getName().substring(3);
+
+            if (member.getName().startsWith("is") && member.getName().length() > 2)
+                name = member.getName().substring(2);
+        }
+
+        ((AccessibleObject)member).setAccessible(true);
+    }
+
+    /**
+     * @param alias Alias.
+     */
+    public void alias(String alias) {
+        this.alias = alias;
+    }
+
+    /**
+     * @return Alias.
+     */
+    public String alias() {
+        return F.isEmpty(alias) ? name : alias;
+    }
+
+    /**
+     * @return Type.
+     */
+    public Class<?> type() {
+        return member instanceof Field ? ((Field)member).getType() : ((Method)member).getReturnType();
+    }
+
+    /**
+     * @param parent Parent property if this is embeddable element.
+     */
+    public void parent(QueryEntityClassProperty parent) {
+        this.parent = parent;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(QueryEntityClassProperty.class, this);
+    }
+
+    /**
+     * @param cls Class.
+     * @return {@code true} If this property or some parent relates to member of the given class.
+     */
+    public boolean knowsClass(Class<?> cls) {
+        return member.getDeclaringClass() == cls || (parent != null && parent.knowsClass(cls));
+    }
+
+    /**
+     * @return Full name with all parents in dot notation.
+     */
+    public String fullName() {
+        assert name != null;
+
+        if (parent == null)
+            return name;
+
+        return parent.fullName() + '.' + name;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/9da69389/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityIndexDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityIndexDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityIndexDescriptor.java
new file mode 100644
index 0000000..2fb5837
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityIndexDescriptor.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache.query;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.TreeSet;
+import org.apache.ignite.cache.QueryIndexType;
+import org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor;
+import org.apache.ignite.internal.util.typedef.T2;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * Index descriptor.
+ */
+public class QueryEntityIndexDescriptor implements GridQueryIndexDescriptor {
+    /** Fields sorted by order number. */
+    private final Collection<T2<String, Integer>> fields = new TreeSet<>(
+        new Comparator<T2<String, Integer>>() {
+            @Override public int compare(T2<String, Integer> o1, T2<String, Integer> o2) {
+                if (o1.get2().equals(o2.get2())) // Order is equal, compare field names to avoid replace in Set.
+                    return o1.get1().compareTo(o2.get1());
+
+                return o1.get2() < o2.get2() ? -1 : 1;
+            }
+        });
+    /** */
+    private final QueryIndexType type;
+    /** */
+    private final int inlineSize;
+    /** Fields which should be indexed in descending order. */
+    private Collection<String> descendings;
+
+    /**
+     * @param type Type.
+     * @param inlineSize Inline size.
+     */
+    QueryEntityIndexDescriptor(QueryIndexType type, int inlineSize) {
+        assert type != null;
+
+        this.type = type;
+        this.inlineSize = inlineSize;
+    }
+
+    /**
+     * @param type Type.
+     */
+    QueryEntityIndexDescriptor(QueryIndexType type) {
+        this(type, -1);
+    }
+
+    /** {@inheritDoc} */
+    @Override public String name() {
+        return null;
+    }
+
+    /** {@inheritDoc} */
+    @Override public Collection<String> fields() {
+        Collection<String> res = new ArrayList<>(fields.size());
+
+        for (T2<String, Integer> t : fields)
+            res.add(t.get1());
+
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean descending(String field) {
+        return descendings != null && descendings.contains(field);
+    }
+
+    /**
+     * Adds field to this index.
+     *
+     * @param field Field name.
+     * @param orderNum Field order number in this index.
+     * @param descending Sort order.
+     */
+    public void addField(String field, int orderNum, boolean descending) {
+        fields.add(new T2<>(field, orderNum));
+
+        if (descending) {
+            if (descendings == null)
+                descendings = new HashSet<>();
+
+            descendings.add(field);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override public QueryIndexType type() {
+        return type;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int inlineSize() {
+        return inlineSize;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(QueryEntityIndexDescriptor.class, this);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/9da69389/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityTypeDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityTypeDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityTypeDescriptor.java
new file mode 100644
index 0000000..47ab263
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/query/QueryEntityTypeDescriptor.java
@@ -0,0 +1,219 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache.query;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+import javax.cache.CacheException;
+import org.apache.ignite.cache.QueryIndexType;
+import org.apache.ignite.internal.processors.query.GridQueryIndexDescriptor;
+import org.apache.ignite.internal.util.tostring.GridToStringExclude;
+import org.apache.ignite.internal.util.tostring.GridToStringInclude;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ * Descriptor of type.
+ */
+public class QueryEntityTypeDescriptor {
+    /** Value field names and types with preserved order. */
+    @GridToStringInclude
+    private final Map<String, Class<?>> fields = new LinkedHashMap<>();
+
+    /** */
+    @GridToStringExclude
+    private final Map<String, QueryEntityClassProperty> props = new LinkedHashMap<>();
+
+    /** */
+    @GridToStringInclude
+    private final Set<String> keyProps = new HashSet<>();
+
+    /** */
+    @GridToStringInclude
+    private final Map<String, QueryEntityIndexDescriptor> indexes = new HashMap<>();
+
+    /** */
+    private QueryEntityIndexDescriptor fullTextIdx;
+
+    /** */
+    private Class<?> keyCls;
+
+    /** */
+    private Class<?> valCls;
+
+    /** */
+    private boolean valTextIdx;
+
+    /**
+     * @return Indexes.
+     */
+    public Map<String, GridQueryIndexDescriptor> indexes() {
+        return Collections.<String, GridQueryIndexDescriptor>unmodifiableMap(indexes);
+    }
+
+    /**
+     * Adds index.
+     *
+     * @param idxName Index name.
+     * @param type Index type.
+     * @param inlineSize Inline size.
+     * @return Index descriptor.
+     */
+    public QueryEntityIndexDescriptor addIndex(String idxName, QueryIndexType type, int inlineSize) {
+        QueryEntityIndexDescriptor idx = new QueryEntityIndexDescriptor(type, inlineSize);
+
+        if (indexes.put(idxName, idx) != null)
+            throw new CacheException("Index with name '" + idxName + "' already exists.");
+
+        return idx;
+    }
+
+    /**
+     * Adds index.
+     *
+     * @param idxName Index name.
+     * @param type Index type.
+     * @return Index descriptor.
+     */
+    public QueryEntityIndexDescriptor addIndex(String idxName, QueryIndexType type) {
+        return addIndex(idxName, type, -1);
+    }
+
+    /**
+     * Adds field to index.
+     *
+     * @param idxName Index name.
+     * @param field Field name.
+     * @param orderNum Fields order number in index.
+     * @param descending Sorting order.
+     */
+    public void addFieldToIndex(String idxName, String field, int orderNum,
+        boolean descending) {
+        QueryEntityIndexDescriptor desc = indexes.get(idxName);
+
+        if (desc == null)
+            desc = addIndex(idxName, QueryIndexType.SORTED);
+
+        desc.addField(field, orderNum, descending);
+    }
+
+    /**
+     * Adds field to text index.
+     *
+     * @param field Field name.
+     */
+    public void addFieldToTextIndex(String field) {
+        if (fullTextIdx == null) {
+            fullTextIdx = new QueryEntityIndexDescriptor(QueryIndexType.FULLTEXT);
+
+            indexes.put(null, fullTextIdx);
+        }
+
+        fullTextIdx.addField(field, 0, false);
+    }
+
+    /**
+     * @return Value class.
+     */
+    public Class<?> valueClass() {
+        return valCls;
+    }
+
+    /**
+     * Sets value class.
+     *
+     * @param valCls Value class.
+     */
+    public void valueClass(Class<?> valCls) {
+        this.valCls = valCls;
+    }
+
+    /**
+     * @return Key class.
+     */
+    public Class<?> keyClass() {
+        return keyCls;
+    }
+
+    /**
+     * Set key class.
+     *
+     * @param keyCls Key class.
+     */
+    public void keyClass(Class<?> keyCls) {
+        this.keyCls = keyCls;
+    }
+
+    /**
+     * Adds property to the type descriptor.
+     *
+     * @param prop Property.
+     * @param key Property ownership flag (key or not).
+     * @param failOnDuplicate Fail on duplicate flag.
+     */
+    public void addProperty(QueryEntityClassProperty prop, boolean key, boolean failOnDuplicate) {
+        String name = prop.fullName();
+
+        if (props.put(name, prop) != null && failOnDuplicate)
+            throw new CacheException("Property with name '" + name + "' already exists.");
+
+        fields.put(name, prop.type());
+
+        if (key)
+            keyProps.add(name);
+    }
+
+    /**
+     * @return Class properties.
+     */
+    public Map<String, QueryEntityClassProperty> properties() {
+        return props;
+    }
+
+    /**
+     * @return Properties keys.
+     */
+    public Set<String> keyProperties() {
+        return keyProps;
+    }
+
+    /**
+     * @return {@code true} If we need to have a fulltext index on value.
+     */
+    public boolean valueTextIndex() {
+        return valTextIdx;
+    }
+
+    /**
+     * Sets if this value should be text indexed.
+     *
+     * @param valTextIdx Flag value.
+     */
+    public void valueTextIndex(boolean valTextIdx) {
+        this.valTextIdx = valTextIdx;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(QueryEntityTypeDescriptor.class, this);
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/ignite/blob/9da69389/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/AbstractH2CompareQueryTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/AbstractH2CompareQueryTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/AbstractH2CompareQueryTest.java
index 5475311..1ddd252 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/AbstractH2CompareQueryTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/AbstractH2CompareQueryTest.java
@@ -25,6 +25,7 @@ import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -34,6 +35,7 @@ import org.apache.ignite.IgniteCache;
 import org.apache.ignite.cache.CacheAtomicityMode;
 import org.apache.ignite.cache.CacheMode;
 import org.apache.ignite.cache.CacheWriteSynchronizationMode;
+import org.apache.ignite.cache.QueryEntity;
 import org.apache.ignite.cache.query.SqlFieldsQuery;
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
@@ -94,7 +96,7 @@ public abstract class AbstractH2CompareQueryTest extends GridCommonAbstractTest
         cc.setCacheMode(mode);
         cc.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
         cc.setAtomicityMode(CacheAtomicityMode.TRANSACTIONAL);
-        cc.setIndexedTypes(clsK, clsV);
+        cc.setQueryEntities(Collections.singleton(new QueryEntity(clsK, clsV)));
 
         return cc;
     }


[05/30] ignite git commit: IGNITE-5920: Fixed CacheClientBinaryQueryExample": set CacheKeyConfiguration explicitly to enable affinity co-location. This closes #2389.

Posted by ag...@apache.org.
IGNITE-5920: Fixed CacheClientBinaryQueryExample": set CacheKeyConfiguration explicitly to enable affinity co-location. This closes #2389.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/eb336074
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/eb336074
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/eb336074

Branch: refs/heads/ignite-5872
Commit: eb336074c91da2e35aab4ca9f69a5d7191b3701b
Parents: 6bdad4d
Author: tledkov-gridgain <tl...@gridgain.com>
Authored: Fri Aug 4 11:16:52 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Fri Aug 4 11:18:09 2017 +0300

----------------------------------------------------------------------
 .../examples/binary/datagrid/CacheClientBinaryQueryExample.java   | 3 +++
 1 file changed, 3 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/eb336074/examples/src/main/java/org/apache/ignite/examples/binary/datagrid/CacheClientBinaryQueryExample.java
----------------------------------------------------------------------
diff --git a/examples/src/main/java/org/apache/ignite/examples/binary/datagrid/CacheClientBinaryQueryExample.java b/examples/src/main/java/org/apache/ignite/examples/binary/datagrid/CacheClientBinaryQueryExample.java
index c2d4964..a3c9996 100644
--- a/examples/src/main/java/org/apache/ignite/examples/binary/datagrid/CacheClientBinaryQueryExample.java
+++ b/examples/src/main/java/org/apache/ignite/examples/binary/datagrid/CacheClientBinaryQueryExample.java
@@ -25,6 +25,7 @@ import javax.cache.Cache;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.Ignition;
+import org.apache.ignite.cache.CacheKeyConfiguration;
 import org.apache.ignite.cache.CacheMode;
 import org.apache.ignite.cache.QueryEntity;
 import org.apache.ignite.cache.QueryIndex;
@@ -84,6 +85,8 @@ public class CacheClientBinaryQueryExample {
 
             employeeCacheCfg.setQueryEntities(Arrays.asList(createEmployeeQueryEntity()));
 
+            employeeCacheCfg.setKeyConfiguration(new CacheKeyConfiguration(EmployeeKey.class));
+
             try (IgniteCache<Integer, Organization> orgCache = ignite.getOrCreateCache(orgCacheCfg);
                  IgniteCache<EmployeeKey, Employee> employeeCache = ignite.getOrCreateCache(employeeCacheCfg)
             ) {


[03/30] ignite git commit: Merge branches 'ignite-2.1.3' and 'master'.

Posted by ag...@apache.org.
Merge branches 'ignite-2.1.3' and 'master'.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/80cc292c
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/80cc292c
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/80cc292c

Branch: refs/heads/ignite-5872
Commit: 80cc292c0d09acdb327047090c1d1448ffffef6b
Parents: d2cb2f7 6bdad4d
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Thu Aug 3 11:52:06 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Thu Aug 3 11:52:06 2017 +0700

----------------------------------------------------------------------
 modules/web-console/backend/app/mongo.js               |  2 +-
 modules/web-console/backend/middlewares/api.js         |  9 ++++-----
 modules/web-console/backend/services/activities.js     | 12 ++----------
 .../modules/configuration/generator/Maven.service.js   | 13 ++++++++++---
 4 files changed, 17 insertions(+), 19 deletions(-)
----------------------------------------------------------------------



[22/30] ignite git commit: IGNITE-5987 Added -nq (visor will not quit in batch mode) option for Visor Cmd.

Posted by ag...@apache.org.
IGNITE-5987 Added -nq (visor will not quit in batch mode) option for Visor Cmd.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/8d6e8420
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/8d6e8420
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/8d6e8420

Branch: refs/heads/ignite-5872
Commit: 8d6e8420fdf1fcd853277704fd68c2d48ac1012d
Parents: 5a559df
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Wed Aug 9 18:55:04 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Wed Aug 9 18:55:04 2017 +0700

----------------------------------------------------------------------
 .../org/apache/ignite/visor/commands/VisorConsole.scala | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/8d6e8420/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/VisorConsole.scala
----------------------------------------------------------------------
diff --git a/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/VisorConsole.scala b/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/VisorConsole.scala
index 19d130e..d53a0d5 100644
--- a/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/VisorConsole.scala
+++ b/modules/visor-console/src/main/scala/org/apache/ignite/visor/commands/VisorConsole.scala
@@ -92,6 +92,7 @@ class VisorConsole {
             println("        -cfg=<path>          - connect with specified configuration.")
             println("        -b=<path>            - batch mode with file.")
             println("        -e=cmd1;cmd2;...     - batch mode with commands.")
+            println("        -nq                  - batch mode will not quit after execution (useful for alerts monitoring).")
 
             visor.quit()
         }
@@ -103,6 +104,10 @@ class VisorConsole {
         val cfgFile = argValue("cfg", argLst)
         val batchFile = argValue("b", argLst)
         val batchCommand = argValue("e", argLst)
+        val noBatchQuit = hasArgName("nq", argLst)
+
+        if (noBatchQuit && batchFile.isEmpty && batchCommand.isEmpty)
+            visor.warn("Option \"-nq\" will be ignored because batch mode options \"-b\" or \"-e\" were not specified.")
 
         cfgFile.foreach(cfg => {
             if (cfg.trim.isEmpty) {
@@ -149,7 +154,10 @@ class VisorConsole {
             case Some(cmd) =>
                 visor.batchMode = true
 
-                new ByteArrayInputStream((cmd + "\nquit\n").getBytes("UTF-8"))
+                val script = if (noBatchQuit) cmd else cmd + "\nquit\n"
+
+                new ByteArrayInputStream(script.getBytes("UTF-8"))
+
             case None => new FileInputStream(FileDescriptor.in)
         }
 
@@ -159,7 +167,7 @@ class VisorConsole {
 
             new TerminalSupport(false) {}
         } catch {
-            case ignored: ClassNotFoundException => null
+            case _: ClassNotFoundException => null
         }
 
         val reader = new ConsoleReader(inputStream, System.out, term)


[24/30] ignite git commit: IGNITE-5658 Optimizations for data streamer

Posted by ag...@apache.org.
IGNITE-5658 Optimizations for data streamer


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/aa81dd14
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/aa81dd14
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/aa81dd14

Branch: refs/heads/ignite-5872
Commit: aa81dd14a7d0e21d448acf2bbbb3a8a3d4eca0f8
Parents: 0e0c2c7
Author: Igor Seliverstov <gv...@gmail.com>
Authored: Wed Aug 9 19:29:39 2017 +0300
Committer: Yakov Zhdanov <yz...@gridgain.com>
Committed: Wed Aug 9 19:29:39 2017 +0300

----------------------------------------------------------------------
 .../org/apache/ignite/IgniteDataStreamer.java   |  26 +-
 .../apache/ignite/IgniteSystemProperties.java   |   8 +
 .../ignite/internal/GridKernalContext.java      |   2 +-
 .../ignite/internal/GridKernalContextImpl.java  |   6 +-
 .../apache/ignite/internal/IgniteKernal.java    |   5 +-
 .../ignite/internal/IgniteNodeAttributes.java   |   3 +
 .../org/apache/ignite/internal/IgnitionEx.java  |  23 +-
 .../ignite/internal/jdbc2/JdbcConnection.java   |   5 +-
 .../managers/communication/GridIoManager.java   |   6 +
 .../managers/communication/GridIoMessage.java   |   3 +
 .../cache/persistence/freelist/PagesList.java   |  67 +++--
 .../wal/reader/StandaloneGridKernalContext.java |   2 +-
 .../datastreamer/DataStreamerImpl.java          | 281 ++++++++++++-------
 .../datastreamer/DataStreamerRequest.java       |  59 +++-
 .../ignite/internal/util/StripedExecutor.java   |  89 +++++-
 .../org/apache/ignite/thread/IgniteThread.java  |  10 +
 .../DataStreamProcessorSelfTest.java            |  14 +-
 .../datastreamer/DataStreamerImplSelfTest.java  |   3 +-
 18 files changed, 427 insertions(+), 185 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/aa81dd14/modules/core/src/main/java/org/apache/ignite/IgniteDataStreamer.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteDataStreamer.java b/modules/core/src/main/java/org/apache/ignite/IgniteDataStreamer.java
index e2473dc..b1f5851 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteDataStreamer.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteDataStreamer.java
@@ -20,6 +20,7 @@ package org.apache.ignite;
 import java.util.Collection;
 import java.util.Map;
 import javax.cache.CacheException;
+import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.lang.IgniteBiPredicate;
 import org.apache.ignite.lang.IgniteFuture;
 import org.apache.ignite.stream.StreamReceiver;
@@ -72,7 +73,7 @@ import org.jetbrains.annotations.Nullable;
  *      this setting limits maximum allowed number of parallel buffered stream messages that
  *      are being processed on remote nodes. If this number is exceeded, then
  *      {@link #addData(Object, Object)} method will block to control memory utilization.
- *      Default is defined by {@link #DFLT_MAX_PARALLEL_OPS} value.
+ *      Default is equal to CPU count on remote node multiply by {@link #DFLT_PARALLEL_OPS_MULTIPLIER}.
  *  </li>
  *  <li>
  *      {@link #autoFlushFrequency(long)} - automatic flush frequency in milliseconds. Essentially,
@@ -100,11 +101,23 @@ import org.jetbrains.annotations.Nullable;
  * </ul>
  */
 public interface IgniteDataStreamer<K, V> extends AutoCloseable {
-    /** Default max concurrent put operations count. */
+    /**
+     * Default max concurrent put operations count.
+     * @deprecated Is not used anymore.
+     */
+    @Deprecated
     public static final int DFLT_MAX_PARALLEL_OPS = 16;
 
-    /** Default per node buffer size. */
-    public static final int DFLT_PER_NODE_BUFFER_SIZE = 1024;
+    /**
+     * Default multiplier for data streamer pool size to get concurrent batches count for each remote node.
+     *
+     * @see IgniteConfiguration#getDataStreamerThreadPoolSize()
+     * @see #perNodeParallelOperations()
+     */
+    public static final int DFLT_PARALLEL_OPS_MULTIPLIER = 8;
+
+    /** Default operations batch size to sent to remote node for loading. */
+    public static final int DFLT_PER_NODE_BUFFER_SIZE = 512;
 
     /** Default timeout for streamer's operations. */
     public static final long DFLT_UNLIMIT_TIMEOUT = -1;
@@ -203,9 +216,11 @@ public interface IgniteDataStreamer<K, V> extends AutoCloseable {
      * <p>
      * This method should be called prior to {@link #addData(Object, Object)} call.
      * <p>
-     * If not provided, default value is {@link #DFLT_MAX_PARALLEL_OPS}.
+     * If not provided, default value is calculated as follows
+     * {@link #DFLT_PARALLEL_OPS_MULTIPLIER} * {@code DATA_STREAMER_POOL_SIZE_ON_REMOTE_NODE}.
      *
      * @param parallelOps Maximum number of parallel stream operations for a single node.
+     * @see IgniteConfiguration#getDataStreamerThreadPoolSize()
      */
     public void perNodeParallelOperations(int parallelOps);
 
@@ -450,5 +465,4 @@ public interface IgniteDataStreamer<K, V> extends AutoCloseable {
      */
     @Override public void close() throws CacheException, IgniteInterruptedException,
         IgniteDataStreamerTimeoutException;
-
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa81dd14/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
index 2fa52b6..8af66c4 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
@@ -703,6 +703,14 @@ public final class IgniteSystemProperties {
     public static final String IGNITE_ENABLE_FORCIBLE_NODE_KILL = "IGNITE_ENABLE_FORCIBLE_NODE_KILL";
 
     /**
+     * Tasks stealing will be started if tasks queue size per data-streamer thread exceeds this threshold.
+     * <p>
+     * Default value is {@code 4}.
+     */
+    public static final String IGNITE_DATA_STREAMING_EXECUTOR_SERVICE_TASKS_STEALING_THRESHOLD =
+            "IGNITE_DATA_STREAMING_EXECUTOR_SERVICE_TASKS_STEALING_THRESHOLD";
+
+    /**
      * Enforces singleton.
      */
     private IgniteSystemProperties() {

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa81dd14/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java
index ef4001f..48a1e3e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContext.java
@@ -532,7 +532,7 @@ public interface GridKernalContext extends Iterable<GridComponent> {
      *
      * @return Thread pool implementation to be used for data stream messages.
      */
-    public ExecutorService getDataStreamerExecutorService();
+    public StripedExecutor getDataStreamerExecutorService();
 
     /**
      * Should return an instance of fully configured thread pool to be used for

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa81dd14/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
index 42a9b2c..89ead1a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/GridKernalContextImpl.java
@@ -317,7 +317,7 @@ public class GridKernalContextImpl implements GridKernalContext, Externalizable
 
     /** */
     @GridToStringExclude
-    private ExecutorService dataStreamExecSvc;
+    private StripedExecutor dataStreamExecSvc;
 
     /** */
     @GridToStringExclude
@@ -423,7 +423,7 @@ public class GridKernalContextImpl implements GridKernalContext, Externalizable
         ExecutorService p2pExecSvc,
         ExecutorService mgmtExecSvc,
         ExecutorService igfsExecSvc,
-        ExecutorService dataStreamExecSvc,
+        StripedExecutor dataStreamExecSvc,
         ExecutorService restExecSvc,
         ExecutorService affExecSvc,
         @Nullable ExecutorService idxExecSvc,
@@ -976,7 +976,7 @@ public class GridKernalContextImpl implements GridKernalContext, Externalizable
     }
 
     /** {@inheritDoc} */
-    @Override public ExecutorService getDataStreamerExecutorService() {
+    @Override public StripedExecutor getDataStreamerExecutorService() {
         return dataStreamExecSvc;
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa81dd14/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
index 756f2ab..f5111c3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteKernal.java
@@ -213,6 +213,7 @@ import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_BUILD_VER;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_CLIENT_MODE;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_CONSISTENCY_CHECK_SKIPPED;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_DAEMON;
+import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_DATA_STREAMER_POOL_SIZE;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_DEPLOYMENT_MODE;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_IGNITE_INSTANCE_NAME;
 import static org.apache.ignite.internal.IgniteNodeAttributes.ATTR_IPS;
@@ -718,7 +719,7 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
         ExecutorService p2pExecSvc,
         ExecutorService mgmtExecSvc,
         ExecutorService igfsExecSvc,
-        ExecutorService dataStreamExecSvc,
+        StripedExecutor dataStreamExecSvc,
         ExecutorService restExecSvc,
         ExecutorService affExecSvc,
         @Nullable ExecutorService idxExecSvc,
@@ -1427,6 +1428,8 @@ public class IgniteKernal implements IgniteEx, IgniteMXBean, Externalizable {
      */
     @SuppressWarnings({"SuspiciousMethodCalls", "unchecked", "TypeMayBeWeakened"})
     private void fillNodeAttributes(boolean notifyEnabled) throws IgniteCheckedException {
+        ctx.addNodeAttribute(ATTR_DATA_STREAMER_POOL_SIZE, configuration().getDataStreamerThreadPoolSize());
+
         final String[] incProps = cfg.getIncludeProperties();
 
         try {

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa81dd14/modules/core/src/main/java/org/apache/ignite/internal/IgniteNodeAttributes.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgniteNodeAttributes.java b/modules/core/src/main/java/org/apache/ignite/internal/IgniteNodeAttributes.java
index a45f991..fe23f92 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgniteNodeAttributes.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgniteNodeAttributes.java
@@ -177,6 +177,9 @@ public final class IgniteNodeAttributes {
     /** Ignite security compatibility mode. */
     public static final String ATTR_SECURITY_COMPATIBILITY_MODE = ATTR_PREFIX + ".security.compatibility.enabled";
 
+    /** */
+    public static final String ATTR_DATA_STREAMER_POOL_SIZE = ATTR_PREFIX + ".data.streamer.pool.size";
+
     /**
      * Enforces singleton.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa81dd14/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java b/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java
index 23baeb3..07a5c43 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/IgnitionEx.java
@@ -1508,7 +1508,7 @@ public class IgnitionEx {
         private ThreadPoolExecutor igfsExecSvc;
 
         /** Data streamer executor service. */
-        private ThreadPoolExecutor dataStreamerExecSvc;
+        private StripedExecutor dataStreamerExecSvc;
 
         /** REST requests executor service. */
         private ThreadPoolExecutor restExecSvc;
@@ -1728,7 +1728,11 @@ public class IgnitionEx {
 
             validateThreadPoolSize(cfg.getStripedPoolSize(), "stripedPool");
 
-            stripedExecSvc = new StripedExecutor(cfg.getStripedPoolSize(), cfg.getIgniteInstanceName(), "sys", log);
+            stripedExecSvc = new StripedExecutor(
+                cfg.getStripedPoolSize(),
+                cfg.getIgniteInstanceName(),
+                "sys",
+                log);
 
             // Note that since we use 'LinkedBlockingQueue', number of
             // maximum threads has no effect.
@@ -1763,17 +1767,12 @@ public class IgnitionEx {
 
             p2pExecSvc.allowCoreThreadTimeOut(true);
 
-            // Note that we do not pre-start threads here as this pool may not be needed.
-            dataStreamerExecSvc = new IgniteThreadPoolExecutor(
-                "data-streamer",
-                cfg.getIgniteInstanceName(),
-                cfg.getDataStreamerThreadPoolSize(),
+            dataStreamerExecSvc = new StripedExecutor(
                 cfg.getDataStreamerThreadPoolSize(),
-                DFLT_THREAD_KEEP_ALIVE_TIME,
-                new LinkedBlockingQueue<Runnable>(),
-                GridIoPolicy.DATA_STREAMER_POOL);
-
-            dataStreamerExecSvc.allowCoreThreadTimeOut(true);
+                cfg.getIgniteInstanceName(),
+                "data-streamer",
+                log,
+                true);
 
             // Note that we do not pre-start threads here as igfs pool may not be needed.
             validateThreadPoolSize(cfg.getIgfsThreadPoolSize(), "IGFS");

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa81dd14/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcConnection.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcConnection.java b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcConnection.java
index 1bf51f2..6fb723e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcConnection.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/jdbc2/JdbcConnection.java
@@ -185,8 +185,9 @@ public class JdbcConnection implements Connection {
         streamFlushTimeout = Long.parseLong(props.getProperty(PROP_STREAMING_FLUSH_FREQ, "0"));
         streamNodeBufSize = Integer.parseInt(props.getProperty(PROP_STREAMING_PER_NODE_BUF_SIZE,
             String.valueOf(IgniteDataStreamer.DFLT_PER_NODE_BUFFER_SIZE)));
-        streamNodeParOps = Integer.parseInt(props.getProperty(PROP_STREAMING_PER_NODE_PAR_OPS,
-            String.valueOf(IgniteDataStreamer.DFLT_MAX_PARALLEL_OPS)));
+        // If value is zero, server data-streamer pool size multiplied
+        // by IgniteDataStreamer.DFLT_PARALLEL_OPS_MULTIPLIER will be used
+        streamNodeParOps = Integer.parseInt(props.getProperty(PROP_STREAMING_PER_NODE_PAR_OPS, "0"));
 
         String nodeIdProp = props.getProperty(PROP_NODE_ID);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa81dd14/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
index bb36b26..2005032 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoManager.java
@@ -1125,6 +1125,12 @@ public class GridIoManager extends GridManagerAdapter<CommunicationSpi<Serializa
             return;
         }
 
+        if (plc == GridIoPolicy.DATA_STREAMER_POOL && msg.partition() != GridIoMessage.STRIPE_DISABLED_PART) {
+            ctx.getDataStreamerExecutorService().execute(msg.partition(), c);
+
+            return;
+        }
+
         if (msg.topicOrdinal() == TOPIC_IO_TEST.ordinal()) {
             IgniteIoTestMessage msg0 = (IgniteIoTestMessage)msg.message();
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa81dd14/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessage.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessage.java b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessage.java
index dccd336..fe61aec 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessage.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/managers/communication/GridIoMessage.java
@@ -23,6 +23,7 @@ import java.nio.ByteBuffer;
 import org.apache.ignite.internal.ExecutorAwareMessage;
 import org.apache.ignite.internal.GridDirectTransient;
 import org.apache.ignite.internal.processors.cache.GridCacheMessage;
+import org.apache.ignite.internal.processors.datastreamer.DataStreamerRequest;
 import org.apache.ignite.internal.util.tostring.GridToStringInclude;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.plugin.extensions.communication.Message;
@@ -336,6 +337,8 @@ public class GridIoMessage implements Message {
     public int partition() {
         if (msg instanceof GridCacheMessage)
             return ((GridCacheMessage)msg).partition();
+        if (msg instanceof DataStreamerRequest)
+            return ((DataStreamerRequest)msg).partition();
         else
             return STRIPE_DISABLED_PART;
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa81dd14/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java
index 39a6865..6c355f6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java
@@ -47,6 +47,7 @@ import org.apache.ignite.internal.util.GridLongList;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.thread.IgniteThread;
 import org.jetbrains.annotations.Nullable;
 
 import static java.lang.Boolean.FALSE;
@@ -66,7 +67,7 @@ public abstract class PagesList extends DataStructure {
     /** */
     private static final int MAX_STRIPES_PER_BUCKET =
         IgniteSystemProperties.getInteger("IGNITE_PAGES_LIST_STRIPES_PER_BUCKET",
-            Math.min(8, Runtime.getRuntime().availableProcessors() * 2));
+            Math.max(8, Runtime.getRuntime().availableProcessors()));
 
     /** */
     protected final AtomicLong[] bucketsSize;
@@ -507,6 +508,21 @@ public abstract class PagesList extends DataStructure {
      * @throws IgniteCheckedException If failed.
      */
     private Stripe getPageForPut(int bucket) throws IgniteCheckedException {
+        // Striped pool optimization.
+        int stripeIdx; IgniteThread igniteThread = IgniteThread.current();
+
+        if (igniteThread != null && (stripeIdx = igniteThread.stripe()) != -1) {
+            Stripe[] tails = getBucket(bucket);
+
+            while (tails == null || stripeIdx >= tails.length) {
+                addStripe(bucket, true);
+
+                tails = getBucket(bucket);
+            }
+
+            return tails[stripeIdx];
+        }
+
         Stripe[] tails = getBucket(bucket);
 
         if (tails == null)
@@ -607,12 +623,8 @@ public abstract class PagesList extends DataStructure {
             try {
                 long tailAddr = writeLockPage(tailId, tailPage, bucket, lockAttempt++); // Explicit check.
 
-                if (tailAddr == 0L) {
-                    if (isReuseBucket(bucket) && lockAttempt == TRY_LOCK_ATTEMPTS)
-                        addStripeForReuseBucket(bucket);
-
+                if (tailAddr == 0L)
                     continue;
-                }
 
                 assert PageIO.getPageId(tailAddr) == tailId : "pageId = " + PageIO.getPageId(tailAddr) + ", tailId = " + tailId;
                 assert PageIO.getType(tailAddr) == PageIO.T_PAGE_LIST_NODE;
@@ -912,13 +924,26 @@ public abstract class PagesList extends DataStructure {
      * @param bucket Bucket index.
      * @return Page for take.
      */
-    private Stripe getPageForTake(int bucket) {
+    private Stripe getPageForTake(int bucket) throws IgniteCheckedException {
         Stripe[] tails = getBucket(bucket);
 
         if (tails == null || bucketsSize[bucket].get() == 0)
             return null;
 
         int len = tails.length;
+
+        // Striped pool optimization.
+        int stripeIdx; IgniteThread igniteThread = IgniteThread.current();
+
+        if (igniteThread != null && (stripeIdx = igniteThread.stripe()) != -1) {
+            if (stripeIdx >= len)
+                return null;
+
+            Stripe stripe = tails[stripeIdx];
+
+            return stripe.empty ? null : stripe;
+        }
+
         int init = randomInt(len);
         int cur = init;
 
@@ -943,6 +968,12 @@ public abstract class PagesList extends DataStructure {
      */
     private long writeLockPage(long pageId, long page, int bucket, int lockAttempt)
         throws IgniteCheckedException {
+        // Striped pool optimization.
+        IgniteThread igniteThread = IgniteThread.current();
+
+        if (igniteThread != null && igniteThread.stripe() != -1)
+            return writeLock(pageId, page);
+
         long pageAddr = tryWriteLock(pageId, page);
 
         if (pageAddr != 0L)
@@ -952,8 +983,7 @@ public abstract class PagesList extends DataStructure {
             Stripe[] stripes = getBucket(bucket);
 
             if (stripes == null || stripes.length < MAX_STRIPES_PER_BUCKET) {
-                if (!isReuseBucket(bucket))
-                    addStripe(bucket, true);
+                addStripe(bucket, !isReuseBucket(bucket));
 
                 return 0L;
             }
@@ -963,19 +993,6 @@ public abstract class PagesList extends DataStructure {
     }
 
     /**
-     * @param bucket Bucket.
-     * @throws IgniteCheckedException If failed.
-     */
-    private void addStripeForReuseBucket(int bucket) throws IgniteCheckedException {
-        assert isReuseBucket(bucket);
-
-        Stripe[] stripes = getBucket(bucket);
-
-        if (stripes == null || stripes.length < MAX_STRIPES_PER_BUCKET)
-            addStripe(bucket, false);
-    }
-
-    /**
      * @param bucket Bucket index.
      * @param initIoVers Optional IO to initialize page.
      * @return Removed page ID.
@@ -994,12 +1011,8 @@ public abstract class PagesList extends DataStructure {
             try {
                 long tailAddr = writeLockPage(tailId, tailPage, bucket, lockAttempt++); // Explicit check.
 
-                if (tailAddr == 0L) {
-                    if (isReuseBucket(bucket) && lockAttempt == TRY_LOCK_ATTEMPTS)
-                        addStripeForReuseBucket(bucket);
-
+                if (tailAddr == 0L)
                     continue;
-                }
 
                 if (stripe.empty) {
                     // Another thread took the last page.

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa81dd14/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java
index 02b9352..8752eaa 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/wal/reader/StandaloneGridKernalContext.java
@@ -421,7 +421,7 @@ public class StandaloneGridKernalContext implements GridKernalContext {
     }
 
     /** {@inheritDoc} */
-    @Override public ExecutorService getDataStreamerExecutorService() {
+    @Override public StripedExecutor getDataStreamerExecutorService() {
         return null;
     }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa81dd14/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java
index df51fac..eaced66 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImpl.java
@@ -17,6 +17,7 @@
 
 package org.apache.ignite.internal.processors.datastreamer;
 
+import java.lang.reflect.Array;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -60,8 +61,10 @@ import org.apache.ignite.internal.IgniteClientDisconnectedCheckedException;
 import org.apache.ignite.internal.IgniteFutureTimeoutCheckedException;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.IgniteInterruptedCheckedException;
+import org.apache.ignite.internal.IgniteNodeAttributes;
 import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
 import org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException;
+import org.apache.ignite.internal.managers.communication.GridIoMessage;
 import org.apache.ignite.internal.managers.communication.GridMessageListener;
 import org.apache.ignite.internal.managers.deployment.GridDeployment;
 import org.apache.ignite.internal.managers.eventstorage.GridLocalEventListener;
@@ -152,7 +155,7 @@ public class DataStreamerImpl<K, V> implements IgniteDataStreamer<K, V>, Delayed
     private int bufSize = DFLT_PER_NODE_BUFFER_SIZE;
 
     /** */
-    private int parallelOps = DFLT_MAX_PARALLEL_OPS;
+    private int parallelOps;
 
     /** */
     private long timeout = DFLT_UNLIMIT_TIMEOUT;
@@ -791,6 +794,9 @@ public class DataStreamerImpl<K, V> implements IgniteDataStreamer<K, V>, Delayed
                             initPda = false;
                         }
 
+                        if (key.partition() == -1)
+                            key.partition(cctx.affinity().partition(key, false));
+
                         nodes = nodes(key, topVer, cctx);
                     }
                     catch (IgniteCheckedException e) {
@@ -932,10 +938,10 @@ public class DataStreamerImpl<K, V> implements IgniteDataStreamer<K, V>, Delayed
                         }
                     };
 
-                    final GridFutureAdapter<?> f;
+                    final List<GridFutureAdapter<?>> futs;
 
                     try {
-                        f = buf.update(entriesForNode, topVer, lsnr, remap);
+                        futs = buf.update(entriesForNode, topVer, lsnr, remap);
                     }
                     catch (IgniteInterruptedCheckedException e1) {
                         resFut.onDone(e1);
@@ -951,9 +957,13 @@ public class DataStreamerImpl<K, V> implements IgniteDataStreamer<K, V>, Delayed
                                 @Override public void run() {
                                     buf0.onNodeLeft();
 
-                                    if (f != null)
-                                        f.onDone(new ClusterTopologyCheckedException("Failed to wait for request completion " +
-                                            "(node has left): " + nodeId));
+                                    if (futs != null) {
+                                        Throwable ex = new ClusterTopologyCheckedException(
+                                                "Failed to wait for request completion (node has left): " + nodeId);
+
+                                        for (int i = 0; i < futs.size(); i++)
+                                            futs.get(i).onDone(ex);
+                                    }
                                 }
                             }, ctx.discovery().topologyVersion(), false);
                         }
@@ -1311,11 +1321,7 @@ public class DataStreamerImpl<K, V> implements IgniteDataStreamer<K, V>, Delayed
         private final Collection<IgniteInternalFuture<Object>> locFuts;
 
         /** Buffered entries. */
-        private List<DataStreamerEntry> entries;
-
-        /** */
-        @GridToStringExclude
-        private GridFutureAdapter<Object> curFut;
+        private final PerStripeBuffer[] stripes;
 
         /** Local node flag. */
         private final boolean isLocNode;
@@ -1329,16 +1335,17 @@ public class DataStreamerImpl<K, V> implements IgniteDataStreamer<K, V>, Delayed
         /** */
         private final Semaphore sem;
 
-        /** Batch topology. */
-        private AffinityTopologyVersion batchTopVer;
+        /** */
+        private final int perNodeParallelOps;
 
         /** Closure to signal on task finish. */
         @GridToStringExclude
-        private final IgniteInClosure<IgniteInternalFuture<Object>> signalC = new IgniteInClosure<IgniteInternalFuture<Object>>() {
-            @Override public void apply(IgniteInternalFuture<Object> t) {
-                signalTaskFinished(t);
-            }
-        };
+        private final IgniteInClosure<IgniteInternalFuture<Object>> signalC =
+            new IgniteInClosure<IgniteInternalFuture<Object>>() {
+                @Override public void apply(IgniteInternalFuture<Object> t) {
+                    signalTaskFinished(t);
+                }
+            };
 
         /**
          * @param node Node.
@@ -1354,24 +1361,19 @@ public class DataStreamerImpl<K, V> implements IgniteDataStreamer<K, V>, Delayed
             // Cache local node flag.
             isLocNode = node.equals(ctx.discovery().localNode());
 
-            entries = newEntries();
-            curFut = new GridFutureAdapter<>();
-            curFut.listen(signalC);
+            Integer attrStreamerPoolSize = node.attribute(IgniteNodeAttributes.ATTR_DATA_STREAMER_POOL_SIZE);
 
-            sem = new Semaphore(parallelOps);
-        }
+            int streamerPoolSize = attrStreamerPoolSize != null ? attrStreamerPoolSize : node.metrics().getTotalCpus();
 
-        /**
-         * @param remap Remapping flag.
-         */
-        private void renewBatch(boolean remap) {
-            entries = newEntries();
-            curFut = new GridFutureAdapter<>();
+            perNodeParallelOps = parallelOps != 0 ? parallelOps :
+                streamerPoolSize * IgniteDataStreamer.DFLT_PARALLEL_OPS_MULTIPLIER;
 
-            batchTopVer = null;
+            sem = new Semaphore(perNodeParallelOps);
 
-            if (!remap)
-                curFut.listen(signalC);
+            stripes = (PerStripeBuffer[])Array.newInstance(PerStripeBuffer.class, streamerPoolSize);
+
+            for (int i = 0; i < stripes.length; i++)
+                stripes[i] = new PerStripeBuffer(i, signalC);
         }
 
         /**
@@ -1382,61 +1384,69 @@ public class DataStreamerImpl<K, V> implements IgniteDataStreamer<K, V>, Delayed
          * @return Future for operation.
          * @throws IgniteInterruptedCheckedException If failed.
          */
-        @Nullable GridFutureAdapter<?> update(Iterable<DataStreamerEntry> newEntries,
+        @Nullable List<GridFutureAdapter<?>> update(
+            Iterable<DataStreamerEntry> newEntries,
             AffinityTopologyVersion topVer,
             IgniteInClosure<IgniteInternalFuture<?>> lsnr,
-            boolean remap) throws IgniteInterruptedCheckedException {
-            List<DataStreamerEntry> entries0 = null;
+            boolean remap
+        ) throws IgniteInterruptedCheckedException {
+            List<GridFutureAdapter<?>> res = null;
 
-            GridFutureAdapter<Object> curFut0;
+            for (DataStreamerEntry entry : newEntries) {
+                List<DataStreamerEntry> entries0 = null;
+                AffinityTopologyVersion curBatchTopVer;
+
+                // Init buffer.
+                int part = entry.getKey().partition();
 
-            AffinityTopologyVersion curBatchTopVer;
+                GridFutureAdapter<Object> curFut0;
+                PerStripeBuffer b = stripes[part % stripes.length];
 
-            synchronized (this) {
-                curFut0 = curFut;
+                synchronized (b) {
+                    curFut0 = b.curFut;
 
-                curFut0.listen(lsnr);
+                    // Listener should be added only once per whole entries collection.
+                    // Should we simplify the model and get rid of all futures?
+                    curFut0.listen(lsnr);
 
-                if (batchTopVer == null)
-                    batchTopVer = topVer;
+                    if (b.batchTopVer == null)
+                        b.batchTopVer = topVer;
 
-                curBatchTopVer = batchTopVer;
+                    curBatchTopVer = b.batchTopVer;
 
-                for (DataStreamerEntry entry : newEntries)
-                    entries.add(entry);
+                    b.entries.add(entry);
 
-                if (entries.size() >= bufSize) {
-                    entries0 = entries;
+                    if (b.entries.size() >= bufSize) {
+                        entries0 = b.entries;
 
-                    renewBatch(remap);
+                        b.renewBatch(remap);
+                    }
                 }
-            }
 
-            if (!allowOverwrite() && !topVer.equals(curBatchTopVer)) {
-                renewBatch(remap);
+                if (res == null)
+                    res = new ArrayList<>();
 
-                curFut0.onDone(null, new IgniteCheckedException("Topology changed during batch preparation." +
-                    "[batchTopVer=" + curBatchTopVer + ", topVer=" + topVer + "]"));
-            }
-            else if (entries0 != null) {
-                submit(entries0, curBatchTopVer, curFut0, remap);
-
-                if (cancelled)
-                    curFut0.onDone(new IgniteCheckedException("Data streamer has been cancelled: " +
-                        DataStreamerImpl.this));
-                else if (ctx.clientDisconnected())
-                    curFut0.onDone(new IgniteClientDisconnectedCheckedException(ctx.cluster().clientReconnectFuture(),
-                        "Client node disconnected."));
-            }
+                res.add(curFut0);
 
-            return curFut0;
-        }
+                if (!allowOverwrite() && !topVer.equals(curBatchTopVer)) {
+                    b.renewBatch(remap);
 
-        /**
-         * @return Fresh collection with some space for outgrowth.
-         */
-        private List<DataStreamerEntry> newEntries() {
-            return new ArrayList<>((int)(bufSize * 1.2));
+                    curFut0.onDone(null, new IgniteCheckedException("Topology changed during batch preparation." +
+                        "[batchTopVer=" + curBatchTopVer + ", topVer=" + topVer + "]"));
+                }
+                else if (entries0 != null) {
+                    submit(entries0, curBatchTopVer, curFut0, remap, b.partId);
+
+                    if (cancelled)
+                        curFut0.onDone(new IgniteCheckedException("Data streamer has been cancelled: " +
+                            DataStreamerImpl.this));
+                    else if (ctx.clientDisconnected())
+                        curFut0.onDone(new IgniteClientDisconnectedCheckedException(ctx.cluster().clientReconnectFuture(),
+                            "Client node disconnected."));
+                }
+            }
+
+            return res;
         }
 
         /**
@@ -1444,24 +1454,26 @@ public class DataStreamerImpl<K, V> implements IgniteDataStreamer<K, V>, Delayed
          * @throws IgniteInterruptedCheckedException If thread has been interrupted.
          */
         @Nullable IgniteInternalFuture<?> flush() throws IgniteInterruptedCheckedException {
-            List<DataStreamerEntry> entries0 = null;
-            GridFutureAdapter<Object> curFut0 = null;
-
             acquireRemapSemaphore();
 
-            synchronized (this) {
-                if (!entries.isEmpty()) {
-                    entries0 = entries;
-                    curFut0 = curFut;
+            for (PerStripeBuffer b : stripes) {
+                AffinityTopologyVersion batchTopVer = null;
+                List<DataStreamerEntry> entries0 = null;
+                GridFutureAdapter<Object> curFut0 = null;
+
+                synchronized (b) {
+                    if (!b.entries.isEmpty()) {
+                        entries0 = b.entries;
+                        curFut0 = b.curFut;
+                        batchTopVer = b.batchTopVer;
 
-                    entries = newEntries();
-                    curFut = new GridFutureAdapter<>();
-                    curFut.listen(signalC);
+                        b.renewBatch(false);
+                    }
                 }
-            }
 
-            if (entries0 != null)
-                submit(entries0, batchTopVer, curFut0, false);
+                if (entries0 != null)
+                    submit(entries0, batchTopVer, curFut0, false, b.partId);
+            }
 
             // Create compound future for this flush.
             GridCompoundFuture<Object, Object> res = null;
@@ -1601,13 +1613,16 @@ public class DataStreamerImpl<K, V> implements IgniteDataStreamer<K, V>, Delayed
          * @param topVer Topology version.
          * @param curFut Current future.
          * @param remap Remapping flag.
+         * @param partId Partition ID.
          * @throws IgniteInterruptedCheckedException If interrupted.
          */
-        private void submit(final Collection<DataStreamerEntry> entries,
+        private void submit(
+            final Collection<DataStreamerEntry> entries,
             @Nullable AffinityTopologyVersion topVer,
             final GridFutureAdapter<Object> curFut,
-            boolean remap)
-            throws IgniteInterruptedCheckedException {
+            boolean remap,
+            int partId
+        ) throws IgniteInterruptedCheckedException {
             assert entries != null;
             assert !entries.isEmpty();
             assert curFut != null;
@@ -1668,7 +1683,8 @@ public class DataStreamerImpl<K, V> implements IgniteDataStreamer<K, V>, Delayed
                             cache.context().deploy().onEnter();
                     }
                     catch (IgniteCheckedException e) {
-                        U.error(log, "Failed to deploy class (request will not be sent): " + jobPda0.deployClass(), e);
+                        U.error(log, "Failed to deploy class (request will not be sent): " +
+                            jobPda0.deployClass(), e);
 
                         return;
                     }
@@ -1701,7 +1717,9 @@ public class DataStreamerImpl<K, V> implements IgniteDataStreamer<K, V>, Delayed
                     dep != null ? dep.participants() : null,
                     dep != null ? dep.classLoaderId() : null,
                     dep == null,
-                    topVer);
+                    topVer,
+                    (rcvr == ISOLATED_UPDATER) ?
+                        partId : GridIoMessage.STRIPE_DISABLED_PART);
 
                 try {
                     ctx.io().sendToGridTopic(node, TOPIC_DATASTREAM, req, plc);
@@ -1750,11 +1768,13 @@ public class DataStreamerImpl<K, V> implements IgniteDataStreamer<K, V>, Delayed
             // Make sure to complete current future.
             GridFutureAdapter<Object> curFut0;
 
-            synchronized (this) {
-                curFut0 = curFut;
-            }
+            for (PerStripeBuffer b : stripes) {
+                synchronized (b) {
+                    curFut0 = b.curFut;
+                }
 
-            curFut0.onDone(e);
+                curFut0.onDone(e);
+            }
         }
 
         /**
@@ -1828,10 +1848,14 @@ public class DataStreamerImpl<K, V> implements IgniteDataStreamer<K, V>, Delayed
 
         /** {@inheritDoc} */
         @Override public String toString() {
-            int size;
+            int size = 0;
 
-            synchronized (this) {
-                size = entries.size();
+            for (int i = 0; i < stripes.length; i++) {
+                PerStripeBuffer b = stripes[i];
+
+                synchronized (b) {
+                    size += b.entries.size();
+                }
             }
 
             return S.toString(Buffer.class, this,
@@ -1920,8 +1944,10 @@ public class DataStreamerImpl<K, V> implements IgniteDataStreamer<K, V>, Delayed
         private static final long serialVersionUID = 0L;
 
         /** {@inheritDoc} */
-        @Override public void receive(IgniteCache<KeyCacheObject, CacheObject> cache,
-            Collection<Map.Entry<KeyCacheObject, CacheObject>> entries) {
+        @Override public void receive(
+            IgniteCache<KeyCacheObject, CacheObject> cache,
+            Collection<Map.Entry<KeyCacheObject, CacheObject>> entries
+        ) {
             IgniteCacheProxy<KeyCacheObject, CacheObject> proxy = (IgniteCacheProxy<KeyCacheObject, CacheObject>)cache;
 
             GridCacheAdapter<KeyCacheObject, CacheObject> internalCache = proxy.context().cache();
@@ -2080,4 +2106,63 @@ public class DataStreamerImpl<K, V> implements IgniteDataStreamer<K, V>, Delayed
             return S.toString(KeyCacheObjectWrapper.class, this);
         }
     }
+
+    /**
+     *
+     */
+    private class PerStripeBuffer {
+        /** */
+        private final int partId;
+
+        /** */
+        private List<DataStreamerEntry> entries;
+
+        /** */
+        private GridFutureAdapter<Object> curFut;
+
+        /** Batch topology. */
+        private AffinityTopologyVersion batchTopVer;
+
+        /** */
+        private final IgniteInClosure<? super IgniteInternalFuture<Object>> signalC;
+
+        /**
+         * @param partId Partition ID.
+         * @param c Signal closure.
+         */
+        public PerStripeBuffer(
+            int partId,
+            IgniteInClosure<? super IgniteInternalFuture<Object>> c
+        ) {
+            this.partId = partId;
+            signalC = c;
+
+            renewBatch(false);
+        }
+
+        /**
+         * @param remap Remap.
+         */
+        synchronized void renewBatch(boolean remap) {
+            entries = newEntries();
+            curFut = new GridFutureAdapter<>();
+
+            batchTopVer = null;
+
+            if (!remap)
+                curFut.listen(signalC);
+        }
+
+        /**
+         * @return Fresh collection with some space for outgrowth.
+         */
+        private List<DataStreamerEntry> newEntries() {
+            return new ArrayList<>((int)(bufSize * 1.2));
+        }
+
+        /** {@inheritDoc} */
+        @Override public String toString() {
+            return S.toString(PerStripeBuffer.class, this, super.toString());
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa81dd14/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerRequest.java
index b4cbf66..f70ee9c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerRequest.java
@@ -90,6 +90,9 @@ public class DataStreamerRequest implements Message {
     /** Topology version. */
     private AffinityTopologyVersion topVer;
 
+    /** */
+    private int partId;
+
     /**
      * {@code Externalizable} support.
      */
@@ -113,8 +116,10 @@ public class DataStreamerRequest implements Message {
      * @param clsLdrId Class loader ID.
      * @param forceLocDep Force local deployment.
      * @param topVer Topology version.
+     * @param partId Partition ID.
      */
-    public DataStreamerRequest(long reqId,
+    public DataStreamerRequest(
+        long reqId,
         byte[] resTopicBytes,
         @Nullable String cacheName,
         byte[] updaterBytes,
@@ -128,7 +133,9 @@ public class DataStreamerRequest implements Message {
         Map<UUID, IgniteUuid> ldrParticipants,
         IgniteUuid clsLdrId,
         boolean forceLocDep,
-        @NotNull AffinityTopologyVersion topVer) {
+        @NotNull AffinityTopologyVersion topVer,
+        int partId
+    ) {
         assert topVer != null;
 
         this.reqId = reqId;
@@ -146,6 +153,7 @@ public class DataStreamerRequest implements Message {
         this.clsLdrId = clsLdrId;
         this.forceLocDep = forceLocDep;
         this.topVer = topVer;
+        this.partId = partId;
     }
 
     /**
@@ -253,6 +261,13 @@ public class DataStreamerRequest implements Message {
         return topVer;
     }
 
+    /**
+     * @return Partition ID.
+     */
+    public int partition() {
+        return partId;
+    }
+
     /** {@inheritDoc} */
     @Override public void onAckReceived() {
         // No-op.
@@ -324,42 +339,48 @@ public class DataStreamerRequest implements Message {
                 writer.incrementState();
 
             case 8:
-                if (!writer.writeLong("reqId", reqId))
+                if (!writer.writeInt("partId", partId))
                     return false;
 
                 writer.incrementState();
 
             case 9:
-                if (!writer.writeByteArray("resTopicBytes", resTopicBytes))
+                if (!writer.writeLong("reqId", reqId))
                     return false;
 
                 writer.incrementState();
 
             case 10:
-                if (!writer.writeString("sampleClsName", sampleClsName))
+                if (!writer.writeByteArray("resTopicBytes", resTopicBytes))
                     return false;
 
                 writer.incrementState();
 
             case 11:
-                if (!writer.writeBoolean("skipStore", skipStore))
+                if (!writer.writeString("sampleClsName", sampleClsName))
                     return false;
 
                 writer.incrementState();
 
             case 12:
-                if (!writer.writeMessage("topVer", topVer))
+                if (!writer.writeBoolean("skipStore", skipStore))
                     return false;
 
                 writer.incrementState();
 
             case 13:
-                if (!writer.writeByteArray("updaterBytes", updaterBytes))
+                if (!writer.writeMessage("topVer", topVer))
                     return false;
 
                 writer.incrementState();
 
             case 14:
+                if (!writer.writeByteArray("updaterBytes", updaterBytes))
+                    return false;
+
+                writer.incrementState();
+
+            case 15:
                 if (!writer.writeString("userVer", userVer))
                     return false;
 
@@ -447,7 +468,7 @@ public class DataStreamerRequest implements Message {
                 reader.incrementState();
 
             case 8:
-                reqId = reader.readLong("reqId");
+                partId = reader.readInt("partId");
 
                 if (!reader.isLastRead())
                     return false;
@@ -455,7 +476,7 @@ public class DataStreamerRequest implements Message {
                 reader.incrementState();
 
             case 9:
-                resTopicBytes = reader.readByteArray("resTopicBytes");
+                reqId = reader.readLong("reqId");
 
                 if (!reader.isLastRead())
                     return false;
@@ -463,7 +484,7 @@ public class DataStreamerRequest implements Message {
                 reader.incrementState();
 
             case 10:
-                sampleClsName = reader.readString("sampleClsName");
+                resTopicBytes = reader.readByteArray("resTopicBytes");
 
                 if (!reader.isLastRead())
                     return false;
@@ -471,7 +492,7 @@ public class DataStreamerRequest implements Message {
                 reader.incrementState();
 
             case 11:
-                skipStore = reader.readBoolean("skipStore");
+                sampleClsName = reader.readString("sampleClsName");
 
                 if (!reader.isLastRead())
                     return false;
@@ -479,7 +500,7 @@ public class DataStreamerRequest implements Message {
                 reader.incrementState();
 
             case 12:
-                topVer = reader.readMessage("topVer");
+                skipStore = reader.readBoolean("skipStore");
 
                 if (!reader.isLastRead())
                     return false;
@@ -487,7 +508,7 @@ public class DataStreamerRequest implements Message {
                 reader.incrementState();
 
             case 13:
-                updaterBytes = reader.readByteArray("updaterBytes");
+                topVer = reader.readMessage("topVer");
 
                 if (!reader.isLastRead())
                     return false;
@@ -495,6 +516,14 @@ public class DataStreamerRequest implements Message {
                 reader.incrementState();
 
             case 14:
+                updaterBytes = reader.readByteArray("updaterBytes");
+
+                if (!reader.isLastRead())
+                    return false;
+
+                reader.incrementState();
+
+            case 15:
                 userVer = reader.readString("userVer");
 
                 if (!reader.isLastRead())
@@ -514,6 +543,6 @@ public class DataStreamerRequest implements Message {
 
     /** {@inheritDoc} */
     @Override public byte fieldsCount() {
-        return 15;
+        return 16;
     }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa81dd14/modules/core/src/main/java/org/apache/ignite/internal/util/StripedExecutor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/StripedExecutor.java b/modules/core/src/main/java/org/apache/ignite/internal/util/StripedExecutor.java
index 6d5dc71..630d34c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/StripedExecutor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/StripedExecutor.java
@@ -20,10 +20,12 @@ package org.apache.ignite.internal.util;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Deque;
 import java.util.List;
 import java.util.Queue;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentLinkedDeque;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
@@ -36,6 +38,8 @@ import java.util.concurrent.locks.LockSupport;
 import org.apache.ignite.IgniteInterruptedException;
 import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.internal.managers.communication.GridIoPolicy;
+import org.apache.ignite.IgniteSystemProperties;
+import org.apache.ignite.internal.util.tostring.GridToStringExclude;
 import org.apache.ignite.internal.util.typedef.internal.A;
 import org.apache.ignite.internal.util.typedef.internal.S;
 import org.apache.ignite.internal.util.typedef.internal.U;
@@ -62,6 +66,17 @@ public class StripedExecutor implements ExecutorService {
      * @param log Logger.
      */
     public StripedExecutor(int cnt, String igniteInstanceName, String poolName, final IgniteLogger log) {
+        this(cnt, igniteInstanceName, poolName, log, false);
+    }
+
+    /**
+     * @param cnt Count.
+     * @param igniteInstanceName Node name.
+     * @param poolName Pool name.
+     * @param log Logger.
+     * @param stealTasks {@code True} to steal tasks.
+     */
+    public StripedExecutor(int cnt, String igniteInstanceName, String poolName, final IgniteLogger log, boolean stealTasks) {
         A.ensure(cnt > 0, "cnt > 0");
 
         boolean success = false;
@@ -76,14 +91,19 @@ public class StripedExecutor implements ExecutorService {
 
         try {
             for (int i = 0; i < cnt; i++) {
-                stripes[i] = new StripeConcurrentQueue(
+                stripes[i] = stealTasks ? new StripeConcurrentQueue(
                     igniteInstanceName,
                     poolName,
                     i,
-                    log);
+                    log, stripes) : new StripeConcurrentQueue(
+                        igniteInstanceName,
+                        poolName,
+                        i,
+                        log);
+            }
 
+            for (int i = 0; i < cnt; i++)
                 stripes[i].start();
-            }
 
             success = true;
         }
@@ -397,7 +417,7 @@ public class StripedExecutor implements ExecutorService {
         private final String poolName;
 
         /** */
-        private final int idx;
+        protected final int idx;
 
         /** */
         private final IgniteLogger log;
@@ -536,8 +556,17 @@ public class StripedExecutor implements ExecutorService {
      * Stripe.
      */
     private static class StripeConcurrentQueue extends Stripe {
+        /** */
+        private static final int IGNITE_TASKS_STEALING_THRESHOLD =
+            IgniteSystemProperties.getInteger(
+                IgniteSystemProperties.IGNITE_DATA_STREAMING_EXECUTOR_SERVICE_TASKS_STEALING_THRESHOLD, 4);
+
         /** Queue. */
-        private final Queue<Runnable> queue = new ConcurrentLinkedQueue<>();
+        private final Queue<Runnable> queue;
+
+        /** */
+        @GridToStringExclude
+        private final Stripe[] others;
 
         /** */
         private volatile boolean parked;
@@ -548,16 +577,37 @@ public class StripedExecutor implements ExecutorService {
          * @param idx Stripe index.
          * @param log Logger.
          */
-        public StripeConcurrentQueue(
+        StripeConcurrentQueue(
             String igniteInstanceName,
             String poolName,
             int idx,
             IgniteLogger log
         ) {
-            super(igniteInstanceName,
+            this(igniteInstanceName, poolName, idx, log, null);
+        }
+
+        /**
+         * @param igniteInstanceName Ignite instance name.
+         * @param poolName Pool name.
+         * @param idx Stripe index.
+         * @param log Logger.
+         */
+        StripeConcurrentQueue(
+            String igniteInstanceName,
+            String poolName,
+            int idx,
+            IgniteLogger log,
+            Stripe[] others
+        ) {
+            super(
+                igniteInstanceName,
                 poolName,
                 idx,
                 log);
+
+            this.others = others;
+
+            this.queue = others == null ? new ConcurrentLinkedQueue<Runnable>() : new ConcurrentLinkedDeque<Runnable>();
         }
 
         /** {@inheritDoc} */
@@ -580,6 +630,24 @@ public class StripedExecutor implements ExecutorService {
                     if (r != null)
                         return r;
 
+                    if(others != null) {
+                        int len = others.length;
+                        int init = ThreadLocalRandom.current().nextInt(len);
+                        int cur = init;
+
+                        while (true) {
+                            if(cur != idx) {
+                                Deque<Runnable> queue = (Deque<Runnable>) ((StripeConcurrentQueue) others[cur]).queue;
+
+                                if(queue.size() > IGNITE_TASKS_STEALING_THRESHOLD && (r = queue.pollLast()) != null)
+                                    return r;
+                            }
+
+                            if ((cur = (cur + 1) % len) == init)
+                                break;
+                        }
+                    }
+
                     LockSupport.park();
 
                     if (Thread.interrupted())
@@ -597,6 +665,13 @@ public class StripedExecutor implements ExecutorService {
 
             if (parked)
                 LockSupport.unpark(thread);
+
+            if(others != null && queueSize() > IGNITE_TASKS_STEALING_THRESHOLD) {
+                for (Stripe other : others) {
+                    if(((StripeConcurrentQueue)other).parked)
+                        LockSupport.unpark(other.thread);
+                }
+            }
         }
 
         /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa81dd14/modules/core/src/main/java/org/apache/ignite/thread/IgniteThread.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/thread/IgniteThread.java b/modules/core/src/main/java/org/apache/ignite/thread/IgniteThread.java
index c814625..14c3d4e 100644
--- a/modules/core/src/main/java/org/apache/ignite/thread/IgniteThread.java
+++ b/modules/core/src/main/java/org/apache/ignite/thread/IgniteThread.java
@@ -149,6 +149,16 @@ public class IgniteThread extends Thread {
     }
 
     /**
+     * @return IgniteThread or {@code null} if current thread is not an instance of IgniteThread.
+     */
+    public static IgniteThread current(){
+        Thread thread = Thread.currentThread();
+
+        return thread.getClass() == IgniteThread.class || thread instanceof IgniteThread ?
+            ((IgniteThread)thread) : null;
+    }
+
+    /**
      * Creates new thread name.
      *
      * @param num Thread number.

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa81dd14/modules/core/src/test/java/org/apache/ignite/internal/processors/datastreamer/DataStreamProcessorSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/datastreamer/DataStreamProcessorSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/datastreamer/DataStreamProcessorSelfTest.java
index ec5e6d0..ac89021 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/datastreamer/DataStreamProcessorSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/datastreamer/DataStreamProcessorSelfTest.java
@@ -962,8 +962,7 @@ public class DataStreamProcessorSelfTest extends GridCommonAbstractTest {
 
             final IgniteCache<String, String> cache = ignite.cache(DEFAULT_CACHE_NAME);
 
-            IgniteDataStreamer<String, String> ldr = ignite.dataStreamer(DEFAULT_CACHE_NAME);
-            try {
+            try (IgniteDataStreamer<String, String> ldr = ignite.dataStreamer(DEFAULT_CACHE_NAME)) {
                 ldr.receiver(new StreamReceiver<String, String>() {
                     @Override public void receive(IgniteCache<String, String> cache,
                         Collection<Map.Entry<String, String>> entries) throws IgniteException {
@@ -972,6 +971,7 @@ public class DataStreamProcessorSelfTest extends GridCommonAbstractTest {
                         cache.put("key", threadName);
                     }
                 });
+
                 ldr.addData("key", "value");
 
                 ldr.tryFlush();
@@ -982,9 +982,6 @@ public class DataStreamProcessorSelfTest extends GridCommonAbstractTest {
                     }
                 }, 3_000);
             }
-            finally {
-                ldr.close(true);
-            }
 
             assertNotNull(cache.get("key"));
 
@@ -1011,9 +1008,7 @@ public class DataStreamProcessorSelfTest extends GridCommonAbstractTest {
 
             final IgniteCache<String, String> cache = ignite.cache(DEFAULT_CACHE_NAME);
 
-            IgniteDataStreamer<String, String> ldr = client.dataStreamer(DEFAULT_CACHE_NAME);
-
-            try {
+            try (IgniteDataStreamer<String, String> ldr = client.dataStreamer(DEFAULT_CACHE_NAME)) {
                 ldr.receiver(new StringStringStreamReceiver());
 
                 ldr.addData("key", "value");
@@ -1026,9 +1021,6 @@ public class DataStreamProcessorSelfTest extends GridCommonAbstractTest {
                     }
                 }, 3_000);
             }
-            finally {
-                ldr.close(true);
-            }
 
             assertNotNull(cache.get("key"));
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/aa81dd14/modules/core/src/test/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImplSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImplSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImplSelfTest.java
index e72a9b4..6d3466b 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImplSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/datastreamer/DataStreamerImplSelfTest.java
@@ -346,7 +346,8 @@ public class DataStreamerImplSelfTest extends GridCommonAbstractTest {
                             req.participants(),
                             req.classLoaderId(),
                             req.forceLocalDeployment(),
-                            staleTop);
+                            staleTop,
+                            -1);
 
                         msg = new GridIoMessage(
                             GridTestUtils.<Byte>getFieldValue(ioMsg, "plc"),


[08/30] ignite git commit: IGNITE-5923: ODBC: SQLGetTypeInfo now works with SQL_ALL_TYPES

Posted by ag...@apache.org.
IGNITE-5923: ODBC: SQLGetTypeInfo now works with SQL_ALL_TYPES


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/48c914dc
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/48c914dc
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/48c914dc

Branch: refs/heads/ignite-5872
Commit: 48c914dcc3a092655636b0df5634c6336dd58a9d
Parents: ec115dc
Author: Igor Sapego <is...@gridgain.com>
Authored: Fri Aug 4 13:18:00 2017 +0300
Committer: Igor Sapego <is...@gridgain.com>
Committed: Fri Aug 4 13:18:00 2017 +0300

----------------------------------------------------------------------
 modules/platforms/cpp/odbc-test/Makefile.am     |   1 +
 .../cpp/odbc-test/include/complex_type.h        |  53 +++---
 .../cpp/odbc-test/project/vs/odbc-test.vcxproj  |   1 +
 .../project/vs/odbc-test.vcxproj.filters        |   3 +
 .../cpp/odbc-test/src/meta_queries_test.cpp     | 189 +++++++++++++++++++
 modules/platforms/cpp/odbc/src/odbc.cpp         |   2 +-
 .../cpp/odbc/src/query/type_info_query.cpp      |   2 +-
 modules/platforms/cpp/odbc/src/statement.cpp    |   2 +-
 8 files changed, 223 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/48c914dc/modules/platforms/cpp/odbc-test/Makefile.am
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/Makefile.am b/modules/platforms/cpp/odbc-test/Makefile.am
index 56ae56a..1d65468 100644
--- a/modules/platforms/cpp/odbc-test/Makefile.am
+++ b/modules/platforms/cpp/odbc-test/Makefile.am
@@ -61,6 +61,7 @@ ignite_odbc_tests_SOURCES = \
     src/column_test.cpp \
     src/configuration_test.cpp \
     src/row_test.cpp \
+    src/meta_queries_test.cpp \
     src/utility_test.cpp \
     src/queries_test.cpp \
     src/test_utils.cpp \

http://git-wip-us.apache.org/repos/asf/ignite/blob/48c914dc/modules/platforms/cpp/odbc-test/include/complex_type.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/include/complex_type.h b/modules/platforms/cpp/odbc-test/include/complex_type.h
index 8a1bd59..b4004ea 100644
--- a/modules/platforms/cpp/odbc-test/include/complex_type.h
+++ b/modules/platforms/cpp/odbc-test/include/complex_type.h
@@ -1,4 +1,4 @@
-/*
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
@@ -21,7 +21,6 @@
 #include <string>
 
 #include "ignite/ignite.h"
-#include "ignite/ignition.h"
 
 namespace ignite
 {
@@ -34,6 +33,18 @@ namespace ignite
             // No-op.
         }
 
+        friend bool operator==(TestObject const& lhs, TestObject const& rhs)
+        {
+            return lhs.f1 == rhs.f1 && lhs.f2 == rhs.f2;
+        }
+
+        friend std::ostream& operator<<(std::ostream& str, TestObject const& obj)
+        {
+            str << "TestObject::f1: " << obj.f1
+                << "TestObject::f2: " << obj.f2;
+            return str;
+        }
+
         int32_t f1;
         std::string f2;
     };
@@ -46,35 +57,23 @@ namespace ignite
             // No-op.
         }
 
+        friend bool operator==(ComplexType const& lhs, ComplexType const& rhs)
+        {
+            return lhs.i32Field == rhs.i32Field && lhs.objField == rhs.objField && lhs.strField == rhs.strField;
+        }
+
+        friend std::ostream& operator<<(std::ostream& str, ComplexType const& obj)
+        {
+            str << "ComplexType::i32Field: " << obj.i32Field
+                << "ComplexType::objField: " << obj.objField
+                << "ComplexType::strField: " << obj.strField;
+            return str;
+        }
+
         int32_t i32Field;
         TestObject objField;
         std::string strField;
     };
-
-    bool operator==(TestObject const& lhs, TestObject const& rhs)
-    {
-        return lhs.f1 == rhs.f1 && lhs.f2 == rhs.f2;
-    }
-
-    bool operator==(ComplexType const& lhs, ComplexType const& rhs)
-    {
-        return lhs.i32Field == rhs.i32Field && lhs.objField == rhs.objField && lhs.strField == rhs.strField;
-    }
-
-    std::ostream& operator<<(std::ostream& str, TestObject const& obj)
-    {
-        str << "TestObject::f1: " << obj.f1
-            << "TestObject::f2: " << obj.f2;
-        return str;
-    }
-
-    std::ostream& operator<<(std::ostream& str, ComplexType const& obj)
-    {
-        str << "ComplexType::i32Field: " << obj.i32Field
-            << "ComplexType::objField: " << obj.objField
-            << "ComplexType::strField: " << obj.strField;
-        return str;
-    }
 }
 
 namespace ignite

http://git-wip-us.apache.org/repos/asf/ignite/blob/48c914dc/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
index c332aad..ceecb3d 100644
--- a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
+++ b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj
@@ -168,6 +168,7 @@
     <ClCompile Include="..\..\src\configuration_test.cpp" />
     <ClCompile Include="..\..\src\connection_info_test.cpp" />
     <ClCompile Include="..\..\src\cursor_test.cpp" />
+    <ClCompile Include="..\..\src\meta_queries_test.cpp" />
     <ClCompile Include="..\..\src\queries_test.cpp" />
     <ClCompile Include="..\..\src\parser_test.cpp" />
     <ClCompile Include="..\..\src\row_test.cpp" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/48c914dc/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters
index 65f2ebf..91c029e 100644
--- a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters
+++ b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters
@@ -121,6 +121,9 @@
     <ClCompile Include="..\..\..\odbc\src\log.cpp">
       <Filter>Externals</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\meta_queries_test.cpp">
+      <Filter>Code</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\include\test_type.h">

http://git-wip-us.apache.org/repos/asf/ignite/blob/48c914dc/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp b/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
new file mode 100644
index 0000000..5b7ae59
--- /dev/null
+++ b/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
@@ -0,0 +1,189 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifdef _WIN32
+#   include <windows.h>
+#endif
+
+#include <sql.h>
+#include <sqlext.h>
+
+#include <vector>
+#include <string>
+#include <algorithm>
+
+#ifndef _MSC_VER
+#   define BOOST_TEST_DYN_LINK
+#endif
+
+#include <boost/test/unit_test.hpp>
+
+#include "ignite/ignition.h"
+
+#include "ignite/common/fixed_size_array.h"
+#include "ignite/impl/binary/binary_utils.h"
+
+#include "test_type.h"
+#include "complex_type.h"
+#include "test_utils.h"
+
+using namespace ignite;
+using namespace ignite::cache;
+using namespace ignite::cache::query;
+using namespace ignite::common;
+using namespace ignite_test;
+using namespace ignite::binary;
+using namespace ignite::impl::binary;
+using namespace ignite::impl::interop;
+
+using namespace boost::unit_test;
+
+/**
+ * Test setup fixture.
+ */
+struct MetaQueriesTestSuiteFixture 
+{
+    /**
+     * Establish connection to node.
+     *
+     * @param connectStr Connection string.
+     */
+    void Connect(const std::string& connectStr)
+    {
+        // Allocate an environment handle
+        SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
+
+        BOOST_REQUIRE(env != NULL);
+
+        // We want ODBC 3 support
+        SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, reinterpret_cast<void*>(SQL_OV_ODBC3), 0);
+
+        // Allocate a connection handle
+        SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
+
+        BOOST_REQUIRE(dbc != NULL);
+
+        // Connect string
+        std::vector<SQLCHAR> connectStr0;
+
+        connectStr0.reserve(connectStr.size() + 1);
+        std::copy(connectStr.begin(), connectStr.end(), std::back_inserter(connectStr0));
+
+        SQLCHAR outstr[ODBC_BUFFER_SIZE];
+        SQLSMALLINT outstrlen;
+
+        // Connecting to ODBC server.
+        SQLRETURN ret = SQLDriverConnect(dbc, NULL, &connectStr0[0], static_cast<SQLSMALLINT>(connectStr0.size()),
+            outstr, sizeof(outstr), &outstrlen, SQL_DRIVER_COMPLETE);
+
+        if (!SQL_SUCCEEDED(ret))
+        {
+            Ignition::Stop(grid.GetName(), true);
+
+            BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_DBC, dbc));
+        }
+
+        // Allocate a statement handle
+        SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
+
+        BOOST_REQUIRE(stmt != NULL);
+    }
+
+    void Disconnect()
+    {
+        // Releasing statement handle.
+        SQLFreeHandle(SQL_HANDLE_STMT, stmt);
+
+        // Disconneting from the server.
+        SQLDisconnect(dbc);
+
+        // Releasing allocated handles.
+        SQLFreeHandle(SQL_HANDLE_DBC, dbc);
+        SQLFreeHandle(SQL_HANDLE_ENV, env);
+    }
+
+    static Ignite StartAdditionalNode(const char* name)
+    {
+#ifdef IGNITE_TESTS_32
+        return StartNode("queries-test-noodbc-32.xml", name);
+#else
+        return StartNode("queries-test-noodbc.xml", name);
+#endif
+    }
+
+    /**
+     * Constructor.
+     */
+    MetaQueriesTestSuiteFixture() :
+        cache1(0),
+        cache2(0),
+        env(NULL),
+        dbc(NULL),
+        stmt(NULL)
+    {
+#ifdef IGNITE_TESTS_32
+        grid = StartNode("queries-test-32.xml", "NodeMain");
+#else
+        grid = StartNode("queries-test.xml", "NodeMain");
+#endif
+
+        cache1 = grid.GetCache<int64_t, TestType>("cache");
+        cache2 = grid.GetCache<int64_t, ComplexType>("cache2");
+    }
+
+    /**
+     * Destructor.
+     */
+    ~MetaQueriesTestSuiteFixture()
+    {
+        Disconnect();
+
+        Ignition::StopAll(true);
+    }
+
+    /** Node started during the test. */
+    Ignite grid;
+
+    /** Frist cache instance. */
+    Cache<int64_t, TestType> cache1;
+
+    /** Second cache instance. */
+    Cache<int64_t, ComplexType> cache2;
+
+    /** ODBC Environment. */
+    SQLHENV env;
+
+    /** ODBC Connect. */
+    SQLHDBC dbc;
+
+    /** ODBC Statement. */
+    SQLHSTMT stmt;
+};
+
+BOOST_FIXTURE_TEST_SUITE(MetaQueriesTestSuite, MetaQueriesTestSuiteFixture)
+
+BOOST_AUTO_TEST_CASE(TestGetTypeInfoAllTypes)
+{
+    Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
+
+    SQLRETURN ret = SQLGetTypeInfo(stmt, SQL_ALL_TYPES);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+}
+
+BOOST_AUTO_TEST_SUITE_END()

http://git-wip-us.apache.org/repos/asf/ignite/blob/48c914dc/modules/platforms/cpp/odbc/src/odbc.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/odbc.cpp b/modules/platforms/cpp/odbc/src/odbc.cpp
index b450903..1862465 100644
--- a/modules/platforms/cpp/odbc/src/odbc.cpp
+++ b/modules/platforms/cpp/odbc/src/odbc.cpp
@@ -1019,7 +1019,7 @@ namespace ignite
     {
         using odbc::Statement;
 
-        LOG_MSG("SQLGetTypeInfo called");
+        LOG_MSG("SQLGetTypeInfo called: [type=" << type << ']');
 
         Statement *statement = reinterpret_cast<Statement*>(stmt);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/48c914dc/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/query/type_info_query.cpp b/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
index 280477b..f6b3990 100644
--- a/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
+++ b/modules/platforms/cpp/odbc/src/query/type_info_query.cpp
@@ -155,7 +155,7 @@ namespace ignite
                 columnsMeta.push_back(ColumnMeta(sch, tbl, "NUM_PREC_RADIX",     IGNITE_TYPE_INT));
                 columnsMeta.push_back(ColumnMeta(sch, tbl, "INTERVAL_PRECISION", IGNITE_TYPE_SHORT));
 
-                assert(IsSqlTypeSupported(sqlType));
+                assert(IsSqlTypeSupported(sqlType) || sqlType == SQL_ALL_TYPES);
 
                 if (sqlType == SQL_ALL_TYPES)
                 {

http://git-wip-us.apache.org/repos/asf/ignite/blob/48c914dc/modules/platforms/cpp/odbc/src/statement.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/statement.cpp b/modules/platforms/cpp/odbc/src/statement.cpp
index adc7d6b..38a1e2e 100644
--- a/modules/platforms/cpp/odbc/src/statement.cpp
+++ b/modules/platforms/cpp/odbc/src/statement.cpp
@@ -671,7 +671,7 @@ namespace ignite
 
         SqlResult::Type Statement::InternalExecuteGetTypeInfoQuery(int16_t sqlType)
         {
-            if (!type_traits::IsSqlTypeSupported(sqlType))
+            if (sqlType != SQL_ALL_TYPES && !type_traits::IsSqlTypeSupported(sqlType))
             {
                 std::stringstream builder;
                 builder << "Data type is not supported. [typeId=" << sqlType << ']';


[04/30] ignite git commit: IGNITE-5920: Fixed CacheClientBinaryQueryExample": set CacheKeyConfiguration explicitly to enable affinity co-location. This closes #2389.

Posted by ag...@apache.org.
IGNITE-5920: Fixed CacheClientBinaryQueryExample": set CacheKeyConfiguration explicitly to enable affinity co-location. This closes #2389.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/e8b355f9
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/e8b355f9
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/e8b355f9

Branch: refs/heads/ignite-5872
Commit: e8b355f9d375e6d53a5fc55008a9c38864fba0a8
Parents: 80cc292
Author: tledkov-gridgain <tl...@gridgain.com>
Authored: Fri Aug 4 11:16:52 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Fri Aug 4 11:16:52 2017 +0300

----------------------------------------------------------------------
 .../examples/binary/datagrid/CacheClientBinaryQueryExample.java   | 3 +++
 1 file changed, 3 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/e8b355f9/examples/src/main/java/org/apache/ignite/examples/binary/datagrid/CacheClientBinaryQueryExample.java
----------------------------------------------------------------------
diff --git a/examples/src/main/java/org/apache/ignite/examples/binary/datagrid/CacheClientBinaryQueryExample.java b/examples/src/main/java/org/apache/ignite/examples/binary/datagrid/CacheClientBinaryQueryExample.java
index c2d4964..a3c9996 100644
--- a/examples/src/main/java/org/apache/ignite/examples/binary/datagrid/CacheClientBinaryQueryExample.java
+++ b/examples/src/main/java/org/apache/ignite/examples/binary/datagrid/CacheClientBinaryQueryExample.java
@@ -25,6 +25,7 @@ import javax.cache.Cache;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.IgniteCache;
 import org.apache.ignite.Ignition;
+import org.apache.ignite.cache.CacheKeyConfiguration;
 import org.apache.ignite.cache.CacheMode;
 import org.apache.ignite.cache.QueryEntity;
 import org.apache.ignite.cache.QueryIndex;
@@ -84,6 +85,8 @@ public class CacheClientBinaryQueryExample {
 
             employeeCacheCfg.setQueryEntities(Arrays.asList(createEmployeeQueryEntity()));
 
+            employeeCacheCfg.setKeyConfiguration(new CacheKeyConfiguration(EmployeeKey.class));
+
             try (IgniteCache<Integer, Organization> orgCache = ignite.getOrCreateCache(orgCacheCfg);
                  IgniteCache<EmployeeKey, Employee> employeeCache = ignite.getOrCreateCache(employeeCacheCfg)
             ) {


[14/30] ignite git commit: IGNITE-5880: BLAS integration phase 2

Posted by ag...@apache.org.
IGNITE-5880: BLAS integration phase 2


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/488a6d27
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/488a6d27
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/488a6d27

Branch: refs/heads/ignite-5872
Commit: 488a6d271bbeb60d424745fb20ef856c624e2fcb
Parents: 9b730e7
Author: Yury Babak <yb...@gridgain.com>
Authored: Mon Aug 7 17:24:21 2017 +0300
Committer: Igor Sapego <is...@gridgain.com>
Committed: Mon Aug 7 17:24:21 2017 +0300

----------------------------------------------------------------------
 .../java/org/apache/ignite/ml/math/Blas.java    | 157 ++++---------------
 .../ml/math/impls/matrix/AbstractMatrix.java    |   3 +-
 .../storage/vector/MatrixVectorStorage.java     |  11 ++
 .../vector/SparseLocalOnHeapVectorStorage.java  |   9 ++
 .../impls/matrix/MatrixImplementationsTest.java |   5 +-
 .../RandomAccessSparseVectorStorageTest.java    |   4 +-
 6 files changed, 56 insertions(+), 133 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/488a6d27/modules/ml/src/main/java/org/apache/ignite/ml/math/Blas.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/Blas.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/Blas.java
index 29312e5..a61d796 100644
--- a/modules/ml/src/main/java/org/apache/ignite/ml/math/Blas.java
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/Blas.java
@@ -19,8 +19,6 @@ package org.apache.ignite.ml.math;
 
 import com.github.fommil.netlib.BLAS;
 import com.github.fommil.netlib.F2jBLAS;
-import it.unimi.dsi.fastutil.ints.IntIterator;
-import it.unimi.dsi.fastutil.ints.IntSet;
 import java.util.Set;
 import org.apache.ignite.ml.math.exceptions.CardinalityException;
 import org.apache.ignite.ml.math.exceptions.MathIllegalArgumentException;
@@ -30,7 +28,10 @@ import org.apache.ignite.ml.math.impls.matrix.DenseLocalOnHeapMatrix;
 import org.apache.ignite.ml.math.impls.matrix.SparseBlockDistributedMatrix;
 import org.apache.ignite.ml.math.impls.matrix.SparseDistributedMatrix;
 import org.apache.ignite.ml.math.impls.matrix.SparseLocalOnHeapMatrix;
+import org.apache.ignite.ml.math.impls.vector.CacheVector;
+import org.apache.ignite.ml.math.impls.vector.DenseLocalOffHeapVector;
 import org.apache.ignite.ml.math.impls.vector.DenseLocalOnHeapVector;
+import org.apache.ignite.ml.math.impls.vector.SparseLocalOffHeapVector;
 import org.apache.ignite.ml.math.impls.vector.SparseLocalVector;
 import org.apache.ignite.ml.math.util.MatrixUtil;
 
@@ -244,9 +245,9 @@ public class Blas {
         else if (alpha == 0.0)
             scal(c, beta);
         else {
-            checkTypes(a, "gemm");
-            checkTypes(b, "gemm");
-            checkTypes(c, "gemm");
+            checkMatrixType(a, "gemm");
+            checkMatrixType(b, "gemm");
+            checkMatrixType(c, "gemm");
 
             double[] fA = a.getStorage().data();
             double[] fB = b.getStorage().data();
@@ -265,7 +266,7 @@ public class Blas {
     /**
      * Currently we support only local onheap matrices for BLAS.
      */
-    private static void checkTypes(Matrix a, String op){
+    private static void checkMatrixType(Matrix a, String op){
         if (a instanceof DenseLocalOffHeapMatrix || a instanceof SparseDistributedMatrix
             || a instanceof SparseBlockDistributedMatrix)
             throw new IllegalArgumentException("Operation doesn't support for matrix [class="
@@ -273,37 +274,12 @@ public class Blas {
     }
 
     /**
-     * y := alpha * A * x + beta * y.
-     *
-     * @param alpha Alpha.
-     * @param a Matrix a.
-     * @param x Vector x.
-     * @param beta Beta.
-     * @param y Vector y.
+     * Currently we support only local onheap vectors for BLAS.
      */
-    public static void gemv(double alpha, Matrix a, Vector x, double beta, DenseLocalOnHeapVector y) {
-        checkCardinality(a, x);
-        checkCardinality(a, y);
-
-        if (alpha == 0.0 && beta == 1.0)
-            return;
-
-        if (alpha == 0.0) {
-            scal(y, beta);
-            return;
-        }
-
-        if (a instanceof SparseLocalOnHeapMatrix && x instanceof DenseLocalOnHeapVector)
-            gemv(alpha, (SparseLocalOnHeapMatrix)a, (DenseLocalOnHeapVector)x, beta, y);
-        else if (a instanceof SparseLocalOnHeapMatrix && x instanceof SparseLocalVector)
-            gemv(alpha, (SparseLocalOnHeapMatrix)a, (SparseLocalVector)x, beta, y);
-        else if (a instanceof DenseLocalOnHeapMatrix && x instanceof DenseLocalOnHeapVector)
-            gemv(alpha, (DenseLocalOnHeapMatrix)a, (DenseLocalOnHeapVector)x, beta, y);
-        else if (a instanceof DenseLocalOnHeapMatrix && x instanceof SparseLocalVector)
-            gemv(alpha, (DenseLocalOnHeapMatrix)a, (SparseLocalVector)x, beta, y);
-        else
-            throw new IllegalArgumentException("Operation gemv doesn't support running thist input [matrix=" +
-                a.getClass().getSimpleName() + ", vector=" + x.getClass().getSimpleName()+"].");
+    private static void checkVectorType(Vector a, String op){
+        if (a instanceof DenseLocalOffHeapVector || a instanceof SparseLocalOffHeapVector || a instanceof CacheVector)
+            throw new IllegalArgumentException("Operation doesn't support for vector [class="
+                + a.getClass().getName() + ", operation="+op+"].");
     }
 
     /**
@@ -315,106 +291,32 @@ public class Blas {
      * @param beta Beta.
      * @param y Vector y.
      */
-    private static void gemv(double alpha, SparseLocalOnHeapMatrix a, DenseLocalOnHeapVector x, double beta,
-        DenseLocalOnHeapVector y) {
-
-        if (beta != 1.0)
-            scal(y, beta);
-
-        IntIterator rowIter = a.indexesMap().keySet().iterator();
-        while (rowIter.hasNext()) {
-            int row = rowIter.nextInt();
-
-            double sum = 0.0;
-            IntIterator colIter = a.indexesMap().get(row).iterator();
-            while (colIter.hasNext()) {
-                int col = colIter.nextInt();
-                sum += alpha * a.getX(row, col) * x.getX(col);
-            }
-
-            y.setX(row, y.getX(row) + sum);
-        }
-    }
+    public static void gemv(double alpha, Matrix a, Vector x, double beta, Vector y) {
+        checkCardinality(a, x);
 
-    /**
-     * y := alpha * A * x + beta * y.
-     *
-     * @param alpha Alpha.
-     * @param a Matrix a.
-     * @param x Vector x.
-     * @param beta Beta.
-     * @param y Vector y.
-     */
-    private static void gemv(double alpha, DenseLocalOnHeapMatrix a, DenseLocalOnHeapVector x, double beta,
-        DenseLocalOnHeapVector y) {
-        nativeBlas.dgemv("N", a.rowSize(), a.columnSize(), alpha, a.getStorage().data(), a.rowSize(), x.getStorage().data(), 1, beta,
-            y.getStorage().data(), 1);
-    }
+        if (a.rowSize() != y.size())
+            throw new CardinalityException(a.columnSize(), y.size());
 
-    /**
-     * y := alpha * A * x + beta * y.
-     *
-     * @param alpha Alpha.
-     * @param a Matrix a.
-     * @param x Vector x.
-     * @param beta Beta.
-     * @param y Vector y.
-     */
-    private static void gemv(double alpha, SparseLocalOnHeapMatrix a, SparseLocalVector x, double beta,
-        DenseLocalOnHeapVector y) {
+        checkMatrixType(a, "gemv");
+        checkVectorType(x,"gemv");
+        checkVectorType(y, "gemv");
 
+        if (alpha == 0.0 && beta == 1.0)
+            return;
 
-        if (beta != 1.0)
+        if (alpha == 0.0) {
             scal(y, beta);
-
-        IntIterator rowIter = a.indexesMap().keySet().iterator();
-        while (rowIter.hasNext()) {
-            int row = rowIter.nextInt();
-
-            double sum = 0.0;
-            IntIterator colIter = a.indexesMap().get(row).iterator();
-            while (colIter.hasNext()) {
-                int col = colIter.nextInt();
-
-                sum += alpha * a.getX(row, col) * x.getX(col);
-            }
-
-            y.set(row, y.get(row) + sum);
+            return;
         }
-    }
-
-    /**
-     * y := alpha * A * x + beta * y.
-     *
-     * @param alpha Alpha.
-     * @param a Matrix a.
-     * @param x Vector x.
-     * @param beta Beta.
-     * @param y Vector y.
-     */
-    private static void gemv(double alpha, DenseLocalOnHeapMatrix a, SparseLocalVector x, double beta,
-        DenseLocalOnHeapVector y) {
-        int rowCntrForA = 0;
-        int mA = a.rowSize();
-
-        double[] aData = a.getStorage().data();
-
-        IntSet indexes = x.indexes();
 
-        double[] yValues = y.getStorage().data();
+        double[] fA = a.getStorage().data();
+        double[] fX = x.getStorage().data();
+        double[] fY = y.getStorage().data();
 
-        while (rowCntrForA < mA) {
-            double sum = 0.0;
+        nativeBlas.dgemv("N", a.rowSize(), a.columnSize(), alpha, fA, a.rowSize(), fX, 1, beta, fY, 1);
 
-            IntIterator iter = indexes.iterator();
-            while (iter.hasNext()) {
-                int xIdx = iter.nextInt();
-                sum += x.getX(xIdx) * aData[xIdx * mA + rowCntrForA];
-            }
-
-            yValues[rowCntrForA] = sum * alpha + beta * yValues[rowCntrForA];
-            rowCntrForA++;
-        }
+        if (y instanceof SparseLocalVector)
+            y.assign(fY);
     }
 
     /**
@@ -427,7 +329,6 @@ public class Blas {
             for (int i = 0; i < m.rowSize(); i++)
                 for (int j = 0; j < m.columnSize(); j++)
                     m.setX(i, j, m.getX(i, j) * alpha);
-
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/488a6d27/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/matrix/AbstractMatrix.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/matrix/AbstractMatrix.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/matrix/AbstractMatrix.java
index b1680f4..2195a70 100644
--- a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/matrix/AbstractMatrix.java
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/matrix/AbstractMatrix.java
@@ -770,8 +770,7 @@ public abstract class AbstractMatrix implements Matrix {
 
         Vector res = likeVector(rows);
 
-        for (int x = 0; x < rows; x++)
-            res.setX(x, vec.dot(viewRow(x)));
+        Blas.gemv(1,this,vec,0,res);
 
         return res;
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/488a6d27/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/vector/MatrixVectorStorage.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/vector/MatrixVectorStorage.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/vector/MatrixVectorStorage.java
index 7700a7c..1e3680a 100644
--- a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/vector/MatrixVectorStorage.java
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/vector/MatrixVectorStorage.java
@@ -163,6 +163,17 @@ public class MatrixVectorStorage implements VectorStorage {
     }
 
     /** {@inheritDoc} */
+    //TODO: IGNITE-5925, tmp solution, wait this ticket.
+    @Override public double[] data() {
+        double[] res = new double[size];
+
+        for (int i = 0; i < size; i++)
+            res[i] = get(i);
+
+        return res;
+    }
+
+    /** {@inheritDoc} */
     @Override public void writeExternal(ObjectOutput out) throws IOException {
         out.writeObject(parent);
         out.writeInt(row);

http://git-wip-us.apache.org/repos/asf/ignite/blob/488a6d27/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/vector/SparseLocalOnHeapVectorStorage.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/vector/SparseLocalOnHeapVectorStorage.java b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/vector/SparseLocalOnHeapVectorStorage.java
index 3323a07..272f08d 100644
--- a/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/vector/SparseLocalOnHeapVectorStorage.java
+++ b/modules/ml/src/main/java/org/apache/ignite/ml/math/impls/storage/vector/SparseLocalOnHeapVectorStorage.java
@@ -158,6 +158,15 @@ public class SparseLocalOnHeapVectorStorage implements VectorStorage, StorageCon
     }
 
     /** {@inheritDoc} */
+    @Override public double[] data() {
+        double[] data = new double[size];
+
+        sto.forEach((idx, val) -> data[idx]=val);
+
+        return data;
+    }
+
+    /** {@inheritDoc} */
     @Override public boolean equals(Object o) {
         if (this == o)
             return true;

http://git-wip-us.apache.org/repos/asf/ignite/blob/488a6d27/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/matrix/MatrixImplementationsTest.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/matrix/MatrixImplementationsTest.java b/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/matrix/MatrixImplementationsTest.java
index e4c2938..89b6224 100644
--- a/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/matrix/MatrixImplementationsTest.java
+++ b/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/matrix/MatrixImplementationsTest.java
@@ -287,6 +287,9 @@ public class MatrixImplementationsTest extends ExternalizeTest<Matrix> {
             if (ignore(m.getClass()))
                 return;
 
+            if (m instanceof DenseLocalOffHeapMatrix)
+                return; //TODO: IGNITE-5535, waiting offheap support.
+
             double[][] data = fillAndReturn(m);
 
             double[] arr = fillArray(m.columnSize());
@@ -302,7 +305,7 @@ public class MatrixImplementationsTest extends ExternalizeTest<Matrix> {
                     exp += arr[j] * data[i][j];
 
                 assertEquals("Unexpected value for " + desc + " at " + i,
-                    times.get(i), exp, 0d);
+                    times.get(i), exp, DEFAULT_DELTA);
             }
 
             testInvalidCardinality(() -> m.times(new DenseLocalOnHeapVector(m.columnSize() + 1)), desc);

http://git-wip-us.apache.org/repos/asf/ignite/blob/488a6d27/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/storage/vector/RandomAccessSparseVectorStorageTest.java
----------------------------------------------------------------------
diff --git a/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/storage/vector/RandomAccessSparseVectorStorageTest.java b/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/storage/vector/RandomAccessSparseVectorStorageTest.java
index 6578e14..1c09ce9 100644
--- a/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/storage/vector/RandomAccessSparseVectorStorageTest.java
+++ b/modules/ml/src/test/java/org/apache/ignite/ml/math/impls/storage/vector/RandomAccessSparseVectorStorageTest.java
@@ -22,7 +22,7 @@ import org.apache.ignite.ml.math.impls.MathTestConstants;
 import org.junit.Test;
 
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertNotNull;
 
 /**
  * Unit tests for {@link SparseLocalOnHeapVectorStorage}.
@@ -36,7 +36,7 @@ public class RandomAccessSparseVectorStorageTest extends VectorBaseStorageTest<S
     /** */
     @Test
     public void data() throws Exception {
-        assertNull(MathTestConstants.NULL_VAL, storage.data());
+        assertNotNull(MathTestConstants.NULL_VAL, storage.data());
     }
 
     /** */


[02/30] ignite git commit: IGNITE-5906 Fixed race on activities merge.

Posted by ag...@apache.org.
IGNITE-5906 Fixed race on activities merge.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/6bdad4dd
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/6bdad4dd
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/6bdad4dd

Branch: refs/heads/ignite-5872
Commit: 6bdad4dd6a5d6f3210051f47af5a51f0bd52f73c
Parents: 20969c0
Author: Andrey Novikov <an...@gridgain.com>
Authored: Thu Aug 3 10:45:59 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Thu Aug 3 10:45:59 2017 +0700

----------------------------------------------------------------------
 modules/web-console/backend/app/mongo.js           |  2 +-
 modules/web-console/backend/middlewares/api.js     |  9 ++++-----
 modules/web-console/backend/services/activities.js | 12 ++----------
 3 files changed, 7 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/6bdad4dd/modules/web-console/backend/app/mongo.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/app/mongo.js b/modules/web-console/backend/app/mongo.js
index 57af928..0bc0e5c 100644
--- a/modules/web-console/backend/app/mongo.js
+++ b/modules/web-console/backend/app/mongo.js
@@ -1055,7 +1055,7 @@ module.exports.factory = function(passportMongo, settings, pluginMongo, mongoose
         date: Date,
         group: String,
         action: String,
-        amount: { type: Number, default: 1 }
+        amount: { type: Number, default: 0 }
     });
 
     ActivitiesSchema.index({ owner: 1, group: 1, action: 1, date: 1}, { unique: true });

http://git-wip-us.apache.org/repos/asf/ignite/blob/6bdad4dd/modules/web-console/backend/middlewares/api.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/middlewares/api.js b/modules/web-console/backend/middlewares/api.js
index 2c4c1bd..aa599ae 100644
--- a/modules/web-console/backend/middlewares/api.js
+++ b/modules/web-console/backend/middlewares/api.js
@@ -20,16 +20,15 @@
 // Fire me up!
 
 module.exports = {
-    implements: 'middlewares:api',
-    inject: ['require("mongodb-core")']
+    implements: 'middlewares:api'
 };
 
-module.exports.factory = (mongodb) => {
+module.exports.factory = () => {
     return (req, res, next) => {
         res.api = {
             error(err) {
-                if (err instanceof mongodb.MongoError)
-                    res.status(500).send(err.message);
+                if (err.name === 'MongoError')
+                    return res.status(500).send(err.message);
 
                 res.status(err.httpCode || err.code || 500).send(err.message);
             },

http://git-wip-us.apache.org/repos/asf/ignite/blob/6bdad4dd/modules/web-console/backend/services/activities.js
----------------------------------------------------------------------
diff --git a/modules/web-console/backend/services/activities.js b/modules/web-console/backend/services/activities.js
index afde8e7..a049f65 100644
--- a/modules/web-console/backend/services/activities.js
+++ b/modules/web-console/backend/services/activities.js
@@ -50,16 +50,8 @@ module.exports.factory = (_, mongo) => {
 
             const date = Date.UTC(now.getFullYear(), now.getMonth(), 1);
 
-            return mongo.Activities.findOne({owner, action, date}).exec()
-                .then((activity) => {
-                    if (activity) {
-                        activity.amount++;
-
-                        return activity.save();
-                    }
-
-                    return mongo.Activities.create({owner, action, group, date});
-                });
+            return mongo.Activities.findOneAndUpdate({owner, action, date},
+                {$set: {owner, group, action, date}, $inc: {amount: 1}}, {new: true, upsert: true}).exec();
         }
 
         static total({startDate, endDate}) {


[29/30] ignite git commit: IGNITE-5963: Add additional check to Thread.sleep to make test correct in all cases. - Fixes #2422.

Posted by ag...@apache.org.
IGNITE-5963: Add additional check to Thread.sleep to make test correct in all cases. - Fixes #2422.

Signed-off-by: Alexey Goncharuk <al...@gmail.com>


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/a7ac59f7
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/a7ac59f7
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/a7ac59f7

Branch: refs/heads/ignite-5872
Commit: a7ac59f7bb214fc9eb4fd4520aad7c40c4dd9ee9
Parents: 0d8d166
Author: Nikolay Izhikov <NI...@gmail.com>
Authored: Thu Aug 10 15:48:26 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Thu Aug 10 15:48:26 2017 +0300

----------------------------------------------------------------------
 .../distributed/IgniteOptimisticTxSuspendResumeTest.java | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/a7ac59f7/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteOptimisticTxSuspendResumeTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteOptimisticTxSuspendResumeTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteOptimisticTxSuspendResumeTest.java
index d16aebd..37003a7 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteOptimisticTxSuspendResumeTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/distributed/IgniteOptimisticTxSuspendResumeTest.java
@@ -32,6 +32,7 @@ import org.apache.ignite.configuration.NearCacheConfiguration;
 import org.apache.ignite.internal.IgniteEx;
 import org.apache.ignite.internal.util.typedef.CI1;
 import org.apache.ignite.internal.util.typedef.CI2;
+import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.testframework.GridTestUtils;
 import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
 import org.apache.ignite.transactions.Transaction;
@@ -428,7 +429,10 @@ public class IgniteOptimisticTxSuspendResumeTest extends GridCommonAbstractTest
 
                     tx.suspend();
 
-                    Thread.sleep(TX_TIMEOUT * 2);
+                    long start = U.currentTimeMillis();
+
+                    while(TX_TIMEOUT >= U.currentTimeMillis() - start)
+                        Thread.sleep(TX_TIMEOUT * 2);
 
                     GridTestUtils.assertThrowsWithCause(new Callable<Object>() {
                         @Override public Object call() throws Exception {
@@ -459,7 +463,10 @@ public class IgniteOptimisticTxSuspendResumeTest extends GridCommonAbstractTest
 
                     cache.put(1, 1);
 
-                    Thread.sleep(TX_TIMEOUT * 2);
+                    long start = U.currentTimeMillis();
+
+                    while(TX_TIMEOUT >= U.currentTimeMillis() - start)
+                        Thread.sleep(TX_TIMEOUT * 2);
 
                     GridTestUtils.assertThrowsWithCause(new Callable<Object>() {
                         @Override public Object call() throws Exception {


[07/30] ignite git commit: IGNITE-5927 .NET: Fix DataTable serialization

Posted by ag...@apache.org.
IGNITE-5927 .NET: Fix DataTable serialization

This closes #2395


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/ec115dcf
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/ec115dcf
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/ec115dcf

Branch: refs/heads/ignite-5872
Commit: ec115dcfa702aa7cc7db5b87c330755b7f37ea0b
Parents: 1a7354f
Author: Pavel Tupitsyn <pt...@apache.org>
Authored: Fri Aug 4 12:34:05 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Fri Aug 4 12:34:05 2017 +0300

----------------------------------------------------------------------
 .../Apache.Ignite.Core.Tests.csproj             |  1 +
 .../Serializable/AdvancedSerializationTest.cs   | 31 ++++++++++++++++++++
 .../BasicSerializableObjectsTest.cs             |  7 +++--
 .../Impl/Binary/SerializableSerializer.cs       | 18 ++++--------
 4 files changed, 42 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/ec115dcf/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
index e4f65bc..3f5f9b3 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj
@@ -61,6 +61,7 @@
     <Reference Include="System" />
     <Reference Include="System.configuration" />
     <Reference Include="System.Core" />
+    <Reference Include="System.Data" />
     <Reference Include="System.Runtime.Serialization" />
     <Reference Include="System.ServiceProcess" />
     <Reference Include="System.Transactions" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec115dcf/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/AdvancedSerializationTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/AdvancedSerializationTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/AdvancedSerializationTest.cs
index c96d111..dc208d0 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/AdvancedSerializationTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/AdvancedSerializationTest.cs
@@ -19,6 +19,7 @@ namespace Apache.Ignite.Core.Tests.Binary.Serializable
 {
     using System;
     using System.Collections.Generic;
+    using System.Data;
     using System.Linq;
     using System.Reflection;
     using System.Reflection.Emit;
@@ -146,6 +147,36 @@ namespace Apache.Ignite.Core.Tests.Binary.Serializable
 
             return typeBuilder.CreateType();
         }
+
+        /// <summary>
+        /// Tests the DataTable serialization.
+        /// </summary>
+        [Test]
+        public void TestDataTable()
+        {
+            var dt = new DataTable("foo");
+
+            dt.Columns.Add("intCol", typeof(int));
+            dt.Columns.Add("stringCol", typeof(string));
+
+            dt.Rows.Add(1, "1");
+            dt.Rows.Add(2, "2");
+
+            var cache = Ignition.GetIgnite().GetOrCreateCache<int, DataTable>("dataTables");
+            cache.Put(1, dt);
+
+            var res = cache.Get(1);
+
+            Assert.AreEqual("foo", res.TableName);
+
+            Assert.AreEqual(2, res.Columns.Count);
+            Assert.AreEqual("intCol", res.Columns[0].ColumnName);
+            Assert.AreEqual("stringCol", res.Columns[1].ColumnName);
+
+            Assert.AreEqual(2, res.Rows.Count);
+            Assert.AreEqual(new object[] {1, "1"}, res.Rows[0].ItemArray);
+            Assert.AreEqual(new object[] {2, "2"}, res.Rows[1].ItemArray);
+        }
     }
 
     [Serializable]

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec115dcf/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/BasicSerializableObjectsTest.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/BasicSerializableObjectsTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/BasicSerializableObjectsTest.cs
index 82deb3c..e9b5576 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/BasicSerializableObjectsTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Binary/Serializable/BasicSerializableObjectsTest.cs
@@ -19,7 +19,6 @@ namespace Apache.Ignite.Core.Tests.Binary.Serializable
 {
     using System;
     using System.Runtime.Serialization;
-    using Apache.Ignite.Core.Binary;
     using NUnit.Framework;
 
     /// <summary>
@@ -111,13 +110,15 @@ namespace Apache.Ignite.Core.Tests.Binary.Serializable
             /// </summary>
             private EmptyObject(SerializationInfo info, StreamingContext context)
             {
-                Assert.IsInstanceOf<IBinaryReader>(context.Context);
+                Assert.AreEqual(StreamingContextStates.All, context.State);
+                Assert.IsNull(context.Context);
             }
 
             /** <inheritdoc /> */
             public void GetObjectData(SerializationInfo info, StreamingContext context)
             {
-                Assert.IsInstanceOf<IBinaryWriter>(context.Context);
+                Assert.AreEqual(StreamingContextStates.All, context.State);
+                Assert.IsNull(context.Context);
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec115dcf/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/SerializableSerializer.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/SerializableSerializer.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/SerializableSerializer.cs
index 13310e4..e660cff 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/SerializableSerializer.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/SerializableSerializer.cs
@@ -53,7 +53,7 @@ namespace Apache.Ignite.Core.Impl.Binary
         /** <inheritdoc /> */
         public void WriteBinary<T>(T obj, BinaryWriter writer)
         {
-            var ctx = GetStreamingContext(writer);
+            var ctx = GetStreamingContext();
             _serializableTypeDesc.OnSerializing(obj, ctx);
 
             var serializable = (ISerializable) obj;
@@ -90,7 +90,7 @@ namespace Apache.Ignite.Core.Impl.Binary
         public T ReadBinary<T>(BinaryReader reader, IBinaryTypeDescriptor desc, int pos, Type typeOverride)
         {
             object res;
-            var ctx = GetStreamingContext(reader);
+            var ctx = GetStreamingContext();
 
             var type = typeOverride ?? desc.Type;
 
@@ -583,17 +583,11 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// <summary>
         /// Gets the streaming context.
         /// </summary>
-        private static StreamingContext GetStreamingContext(IBinaryReader reader)
+        private static StreamingContext GetStreamingContext()
         {
-            return new StreamingContext(StreamingContextStates.All, reader);
-        }
-
-        /// <summary>
-        /// Gets the streaming context.
-        /// </summary>
-        private static StreamingContext GetStreamingContext(IBinaryWriter writer)
-        {
-            return new StreamingContext(StreamingContextStates.All, writer);
+            // Additional parameter must be null, because some ISerializable implementations expect weird things there.
+            // For example, System.Data.DataTable calls Convert.ToBoolean on that value.
+            return new StreamingContext(StreamingContextStates.All, null);
         }
 
         /// <summary>


[30/30] ignite git commit: Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/ignite into ignite-5872

Posted by ag...@apache.org.
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/ignite into ignite-5872


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/855ece3b
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/855ece3b
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/855ece3b

Branch: refs/heads/ignite-5872
Commit: 855ece3b13aec4b63633ecaecc2ea7fbaa3c1de8
Parents: cfbd327 a7ac59f
Author: Alexey Goncharuk <al...@gmail.com>
Authored: Thu Aug 10 16:52:30 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Thu Aug 10 16:52:30 2017 +0300

----------------------------------------------------------------------
 .../datagrid/CacheClientBinaryQueryExample.java |   3 +
 .../tcp/redis/RedisProtocolStringSelfTest.java  |  44 ++
 .../jdbc/suite/IgniteJdbcDriverTestSuite.java   |   2 +
 .../ignite/jdbc/thin/JdbcThinBatchSelfTest.java | 333 ++++++++++
 .../java/org/apache/ignite/IgniteCache.java     |   1 -
 .../org/apache/ignite/IgniteDataStreamer.java   |  26 +-
 .../apache/ignite/IgniteSystemProperties.java   |   8 +
 .../org/apache/ignite/cache/QueryEntity.java    | 229 +++++++
 .../configuration/CacheConfiguration.java       | 615 +------------------
 .../ignite/internal/GridKernalContext.java      |   2 +-
 .../ignite/internal/GridKernalContextImpl.java  |   6 +-
 .../apache/ignite/internal/IgniteKernal.java    |   5 +-
 .../ignite/internal/IgniteNodeAttributes.java   |   3 +
 .../org/apache/ignite/internal/IgnitionEx.java  |  23 +-
 .../jdbc/thin/JdbcThinPreparedStatement.java    |  16 +-
 .../internal/jdbc/thin/JdbcThinStatement.java   |  46 +-
 .../internal/jdbc/thin/JdbcThinTcpIo.java       |  20 +
 .../ignite/internal/jdbc2/JdbcConnection.java   |   5 +-
 .../managers/communication/GridIoManager.java   |   6 +
 .../managers/communication/GridIoMessage.java   |   3 +
 .../internal/pagemem/store/PageStore.java       |   5 +
 .../cache/persistence/file/FilePageStore.java   |  54 +-
 .../persistence/file/FilePageStoreFactory.java  |  35 ++
 .../persistence/file/FilePageStoreManager.java  |  17 +-
 .../cache/persistence/file/FilePageStoreV2.java |  53 ++
 .../file/FileVersionCheckingFactory.java        | 116 ++++
 .../cache/persistence/freelist/PagesList.java   |  67 +-
 .../tree/io/PagePartitionCountersIO.java        |   2 +-
 .../wal/reader/StandaloneGridKernalContext.java |   2 +-
 .../cache/query/QueryEntityClassProperty.java   | 116 ++++
 .../cache/query/QueryEntityIndexDescriptor.java | 121 ++++
 .../cache/query/QueryEntityTypeDescriptor.java  | 219 +++++++
 .../cache/store/CacheStoreManager.java          |   4 +-
 .../store/GridCacheStoreManagerAdapter.java     |  20 +-
 .../cache/transactions/IgniteTxAdapter.java     |   9 +-
 .../datastreamer/DataStreamerImpl.java          | 281 ++++++---
 .../datastreamer/DataStreamerRequest.java       |  59 +-
 .../odbc/jdbc/JdbcBatchExecuteRequest.java      | 109 ++++
 .../odbc/jdbc/JdbcBatchExecuteResult.java       |  96 +++
 .../processors/odbc/jdbc/JdbcQuery.java         |  95 +++
 .../processors/odbc/jdbc/JdbcRequest.java       |   8 +
 .../odbc/jdbc/JdbcRequestHandler.java           |  66 +-
 .../processors/odbc/jdbc/JdbcResult.java        |  11 +
 .../processors/rest/GridRestCommand.java        |   3 +
 .../handlers/cache/GridCacheCommandHandler.java |  75 ++-
 .../key/GridRedisExpireCommandHandler.java      | 101 +++
 .../protocols/tcp/redis/GridRedisCommand.java   |   4 +
 .../tcp/redis/GridRedisNioListener.java         |   2 +
 .../ignite/internal/util/StripedExecutor.java   |  89 ++-
 .../org/apache/ignite/thread/IgniteThread.java  |  10 +
 .../GridCacheAbstractLocalStoreSelfTest.java    |   7 +
 .../IgniteOptimisticTxSuspendResumeTest.java    |  11 +-
 ...gnitePdsRecoveryAfterFileCorruptionTest.java |   2 +-
 .../DataStreamProcessorSelfTest.java            |  14 +-
 .../datastreamer/DataStreamerImplSelfTest.java  |   3 +-
 .../query/h2/opt/GridH2SpatialIndex.java        |   7 -
 .../processors/query/h2/H2RowDescriptor.java    |  11 -
 .../processors/query/h2/H2TableEngine.java      |   4 +-
 .../query/h2/database/H2PkHashIndex.java        |   7 -
 .../query/h2/database/H2TreeIndex.java          |  32 +-
 .../query/h2/database/InlineIndexHelper.java    | 414 ++++++++++++-
 .../query/h2/opt/GridH2IndexBase.java           |  93 +--
 .../query/h2/opt/GridH2QueryContext.java        |  59 --
 .../query/h2/opt/GridH2RowDescriptor.java       |   5 -
 .../processors/query/h2/opt/GridH2Table.java    | 186 +-----
 .../query/h2/opt/GridH2TreeIndex.java           | 602 ------------------
 .../query/h2/opt/GridLuceneDirectory.java       |  64 +-
 .../processors/query/h2/opt/GridLuceneFile.java |  91 ++-
 .../query/h2/opt/GridLuceneIndex.java           |   3 +-
 .../query/h2/opt/GridLuceneInputStream.java     |  42 +-
 .../query/h2/opt/GridLuceneOutputStream.java    |  18 +-
 .../query/h2/twostep/GridMapQueryExecutor.java  | 526 +---------------
 .../query/h2/twostep/MapNodeResults.java        | 108 ++++
 .../query/h2/twostep/MapQueryResult.java        | 258 ++++++++
 .../query/h2/twostep/MapQueryResults.java       | 155 +++++
 .../h2/twostep/MapReplicatedReservation.java    |  38 ++
 .../query/h2/twostep/MapRequestKey.java         |  65 ++
 .../query/h2/twostep/MapReservationKey.java     |  73 +++
 ...teCacheFullTextQueryNodeJoiningSelfTest.java |   3 +-
 .../h2/database/InlineIndexHelperTest.java      | 248 +++++++-
 .../query/h2/opt/GridH2TableSelfTest.java       | 172 ------
 .../h2/sql/AbstractH2CompareQueryTest.java      |   4 +-
 .../IgniteCacheQuerySelfTestSuite.java          |   2 +
 .../IgniteCacheWithIndexingTestSuite.java       |   3 +
 .../java/org/apache/ignite/ml/math/Blas.java    | 157 +----
 .../ml/math/impls/matrix/AbstractMatrix.java    |   3 +-
 .../storage/vector/MatrixVectorStorage.java     |  11 +
 .../vector/SparseLocalOnHeapVectorStorage.java  |   9 +
 .../impls/matrix/MatrixImplementationsTest.java |   5 +-
 .../RandomAccessSparseVectorStorageTest.java    |   4 +-
 .../impl/cache/query/query_fields_row_impl.h    |   2 +-
 modules/platforms/cpp/odbc-test/Makefile.am     |   1 +
 .../cpp/odbc-test/include/complex_type.h        |  53 +-
 .../cpp/odbc-test/include/test_utils.h          |   9 +
 .../cpp/odbc-test/project/vs/odbc-test.vcxproj  |   1 +
 .../project/vs/odbc-test.vcxproj.filters        |   3 +
 .../cpp/odbc-test/src/meta_queries_test.cpp     | 340 ++++++++++
 .../platforms/cpp/odbc-test/src/test_utils.cpp  |  13 +
 .../ignite/odbc/query/column_metadata_query.h   |   3 +
 .../ignite/odbc/query/table_metadata_query.h    |   3 +
 .../include/ignite/odbc/query/type_info_query.h |   3 +
 .../platforms/cpp/odbc/src/meta/column_meta.cpp |   3 +
 modules/platforms/cpp/odbc/src/odbc.cpp         |   2 +-
 .../cpp/odbc/src/query/batch_query.cpp          |   7 +-
 .../odbc/src/query/column_metadata_query.cpp    |  16 +-
 .../platforms/cpp/odbc/src/query/data_query.cpp |   7 +-
 .../cpp/odbc/src/query/table_metadata_query.cpp |  16 +-
 .../cpp/odbc/src/query/type_info_query.cpp      |  18 +-
 modules/platforms/cpp/odbc/src/statement.cpp    |   2 +-
 .../Apache.Ignite.Core.Tests.csproj             |   1 +
 .../Serializable/AdvancedSerializationTest.cs   |  31 +
 .../BasicSerializableObjectsTest.cs             |   7 +-
 .../Impl/Binary/SerializableSerializer.cs       |  18 +-
 .../ignite/visor/commands/VisorConsole.scala    |  12 +-
 modules/web-console/backend/app/mongo.js        |   2 +-
 modules/web-console/backend/middlewares/api.js  |   9 +-
 .../web-console/backend/services/activities.js  |  12 +-
 .../hide-on-state-change.directive.js           |   8 +-
 .../configuration/generator/Maven.service.js    |  13 +-
 modules/web-console/frontend/package.json       |   2 +-
 modules/web-console/frontend/views/index.pug    |   8 +
 121 files changed, 4583 insertions(+), 2806 deletions(-)
----------------------------------------------------------------------



[25/30] ignite git commit: IGNITE-5912: Redis EXPIRE/PEXPIRE commands. - Fixes #2383.

Posted by ag...@apache.org.
IGNITE-5912: Redis EXPIRE/PEXPIRE commands. - Fixes #2383.

Signed-off-by: shroman <rs...@yahoo.com>


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/988ffe3e
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/988ffe3e
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/988ffe3e

Branch: refs/heads/ignite-5872
Commit: 988ffe3e131792072e743e103f524ec20394f8e0
Parents: aa81dd1
Author: shroman <rs...@yahoo.com>
Authored: Thu Aug 10 09:51:05 2017 +0900
Committer: shroman <rs...@yahoo.com>
Committed: Thu Aug 10 09:51:05 2017 +0900

----------------------------------------------------------------------
 .../tcp/redis/RedisProtocolStringSelfTest.java  |  44 ++++++++
 .../processors/rest/GridRestCommand.java        |   3 +
 .../handlers/cache/GridCacheCommandHandler.java |  75 +++++++++++++-
 .../key/GridRedisExpireCommandHandler.java      | 101 +++++++++++++++++++
 .../protocols/tcp/redis/GridRedisCommand.java   |   4 +
 .../tcp/redis/GridRedisNioListener.java         |   2 +
 6 files changed, 228 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/988ffe3e/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/RedisProtocolStringSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/RedisProtocolStringSelfTest.java b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/RedisProtocolStringSelfTest.java
index 68b42c4..21a9882 100644
--- a/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/RedisProtocolStringSelfTest.java
+++ b/modules/clients/src/test/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/RedisProtocolStringSelfTest.java
@@ -423,4 +423,48 @@ public class RedisProtocolStringSelfTest extends RedisCommonAbstractTest {
             Assert.assertEquals(2, (long)jedis.exists("existsKey1", "existsKey2"));
         }
     }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testExpire() throws Exception {
+        testExpire(new Expiration() {
+            @Override public long expire(Jedis jedis, String key) {
+                return jedis.expire("k1", 2);
+            }
+        });
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testExpireMs() throws Exception {
+        testExpire(new Expiration() {
+            @Override public long expire(Jedis jedis, String key) {
+                return jedis.pexpire("k1", 2000);
+            }
+        });
+    }
+
+    private void testExpire(Expiration exp) throws Exception {
+        try (Jedis jedis = pool.getResource()) {
+            jedis.set("k1", "v1");
+
+            Assert.assertTrue(jedis.exists("k1"));
+
+            Assert.assertEquals(1L, exp.expire(jedis, "k1"));
+
+            Assert.assertEquals("v1", jedis.get("k1"));
+
+            Thread.sleep(2100);
+
+            Assert.assertFalse(jedis.exists("k1"));
+
+            Assert.assertEquals(0L, (long)jedis.expire("k1", 2));
+        }
+    }
+
+    private interface Expiration {
+        long expire(Jedis jedis, String key);
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/988ffe3e/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java
index 2ed370d..24b4bda 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/GridRestCommand.java
@@ -99,6 +99,9 @@ public enum GridRestCommand {
     /** Cache size. */
     CACHE_SIZE("size"),
 
+    /** Set TTL for the key. */
+    CACHE_UPDATE_TLL("updatettl"),
+
     /** Cache metadata. */
     CACHE_METADATA("metadata"),
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/988ffe3e/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cache/GridCacheCommandHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cache/GridCacheCommandHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cache/GridCacheCommandHandler.java
index f2ca071..53342c9 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cache/GridCacheCommandHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/cache/GridCacheCommandHandler.java
@@ -52,7 +52,10 @@ import org.apache.ignite.internal.IgniteEx;
 import org.apache.ignite.internal.IgniteInternalFuture;
 import org.apache.ignite.internal.IgniteKernal;
 import org.apache.ignite.internal.managers.discovery.GridDiscoveryManager;
+import org.apache.ignite.internal.processors.cache.CacheInvokeEntry;
 import org.apache.ignite.internal.processors.cache.GridCacheAdapter;
+import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
+import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException;
 import org.apache.ignite.internal.processors.cache.IgniteInternalCache;
 import org.apache.ignite.internal.processors.cache.query.GridCacheSqlMetadata;
 import org.apache.ignite.internal.processors.rest.GridRestCommand;
@@ -83,6 +86,7 @@ import static org.apache.ignite.internal.processors.rest.GridRestCommand.CACHE_C
 import static org.apache.ignite.internal.processors.rest.GridRestCommand.CACHE_CLEAR;
 import static org.apache.ignite.internal.processors.rest.GridRestCommand.CACHE_CONTAINS_KEY;
 import static org.apache.ignite.internal.processors.rest.GridRestCommand.CACHE_CONTAINS_KEYS;
+import static org.apache.ignite.internal.processors.rest.GridRestCommand.CACHE_UPDATE_TLL;
 import static org.apache.ignite.internal.processors.rest.GridRestCommand.CACHE_GET;
 import static org.apache.ignite.internal.processors.rest.GridRestCommand.CACHE_GET_ALL;
 import static org.apache.ignite.internal.processors.rest.GridRestCommand.CACHE_GET_AND_PUT;
@@ -136,6 +140,7 @@ public class GridCacheCommandHandler extends GridRestCommandHandlerAdapter {
         CACHE_PREPEND,
         CACHE_METRICS,
         CACHE_SIZE,
+        CACHE_UPDATE_TLL,
         CACHE_METADATA
     );
 
@@ -158,7 +163,8 @@ public class GridCacheCommandHandler extends GridRestCommandHandlerAdapter {
         ATOMIC_DECREMENT,
         CACHE_CAS,
         CACHE_APPEND,
-        CACHE_PREPEND
+        CACHE_PREPEND,
+        CACHE_UPDATE_TLL
     );
 
     /**
@@ -634,6 +640,15 @@ public class GridCacheCommandHandler extends GridRestCommandHandlerAdapter {
                     break;
                 }
 
+                case CACHE_UPDATE_TLL: {
+                    if (ttl == null)
+                        throw new IgniteCheckedException(GridRestCommandHandlerAdapter.missingParameter("ttl"));
+
+                    fut = executeCommand(req.destinationId(), req.clientId(), cacheName, key, new UpdateTllCommand(key, ttl));
+
+                    break;
+                }
+
                 default:
                     throw new IllegalArgumentException("Invalid command for cache handler: " + req);
             }
@@ -1621,4 +1636,62 @@ public class GridCacheCommandHandler extends GridRestCommandHandlerAdapter {
             return c.sizeAsync(new CachePeekMode[] {CachePeekMode.PRIMARY});
         }
     }
+
+    /** Update TTL on key. */
+    private static class UpdateTllCommand extends CacheCommand {
+        /** */
+        private static final long serialVersionUID = 0L;
+
+        /** */
+        private final Object key;
+
+        /** */
+        private final Long ttl;
+
+        /**
+         * @param key Key.
+         * @param ttl TTL.
+         */
+        UpdateTllCommand(Object key, Long ttl) {
+            this.key = key;
+            this.ttl = ttl;
+        }
+
+        /** {@inheritDoc} */
+        @Override public IgniteInternalFuture<?> applyx(final IgniteInternalCache<Object, Object> c,
+            GridKernalContext ctx) {
+            assert c != null;
+
+            return ctx.closure().callLocalSafe(new Callable<Object>() {
+                @Override public Object call() throws Exception {
+                    EntryProcessorResult<Boolean> res = c.invoke(key, new EntryProcessor<Object, Object, Boolean>() {
+                        @Override
+                        public Boolean process(MutableEntry<Object, Object> entry,
+                            Object... objects) throws EntryProcessorException {
+                            GridCacheEntryEx ex = ((CacheInvokeEntry)entry).entry();
+
+                            if (entry.getValue() == null)
+                                return false;
+
+                            try {
+                                ex.updateTtl(ex.version(), ttl);
+                            }
+                            catch (GridCacheEntryRemovedException e) {
+                                throw new EntryProcessorException(e.getCause());
+                            }
+
+                            return true;
+                        }
+                    });
+
+                    try {
+                        return res.get();
+                    }
+                    catch (EntryProcessorException e) {
+                        throw new IgniteCheckedException(e.getCause());
+                    }
+                }
+            }, false);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/988ffe3e/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/redis/key/GridRedisExpireCommandHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/redis/key/GridRedisExpireCommandHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/redis/key/GridRedisExpireCommandHandler.java
new file mode 100644
index 0000000..70ca504
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/handlers/redis/key/GridRedisExpireCommandHandler.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.rest.handlers.redis.key;
+
+import java.nio.ByteBuffer;
+import java.util.Collection;
+import java.util.List;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.internal.processors.rest.GridRestProtocolHandler;
+import org.apache.ignite.internal.processors.rest.GridRestResponse;
+import org.apache.ignite.internal.processors.rest.handlers.redis.GridRedisRestCommandHandler;
+import org.apache.ignite.internal.processors.rest.handlers.redis.exception.GridRedisGenericException;
+import org.apache.ignite.internal.processors.rest.protocols.tcp.redis.GridRedisCommand;
+import org.apache.ignite.internal.processors.rest.protocols.tcp.redis.GridRedisMessage;
+import org.apache.ignite.internal.processors.rest.protocols.tcp.redis.GridRedisProtocolParser;
+import org.apache.ignite.internal.processors.rest.request.GridRestCacheRequest;
+import org.apache.ignite.internal.processors.rest.request.GridRestRequest;
+import org.apache.ignite.internal.util.typedef.internal.U;
+
+import static org.apache.ignite.internal.processors.rest.GridRestCommand.CACHE_UPDATE_TLL;
+import static org.apache.ignite.internal.processors.rest.protocols.tcp.redis.GridRedisCommand.EXPIRE;
+import static org.apache.ignite.internal.processors.rest.protocols.tcp.redis.GridRedisCommand.PEXPIRE;
+
+/**
+ * Redis EXPIRE/PEXPIRE command handler.
+ */
+public class GridRedisExpireCommandHandler extends GridRedisRestCommandHandler {
+    /** Supported commands. */
+    private static final Collection<GridRedisCommand> SUPPORTED_COMMANDS = U.sealList(
+        EXPIRE,
+        PEXPIRE
+    );
+
+    /** TTL position in Redis message. */
+    private static final int TTL_POS = 2;
+
+    /**
+     * Handler constructor.
+     *
+     * @param log Logger to use.
+     * @param hnd Rest handler.
+     */
+    public GridRedisExpireCommandHandler(final IgniteLogger log, final GridRestProtocolHandler hnd) {
+        super(log, hnd);
+    }
+
+    /** {@inheritDoc} */
+    @Override public Collection<GridRedisCommand> supportedCommands() {
+        return SUPPORTED_COMMANDS;
+    }
+
+    /** {@inheritDoc} */
+    @Override public GridRestRequest asRestRequest(GridRedisMessage msg) throws IgniteCheckedException {
+        assert msg != null;
+
+        if (msg.messageSize() < 2)
+            throw new GridRedisGenericException("Wrong number of arguments (key is missing)");
+        else if (msg.messageSize() < 3)
+            throw new GridRedisGenericException("Wrong number of arguments (timeout value is missing)");
+
+        GridRestCacheRequest restReq = new GridRestCacheRequest();
+
+        restReq.clientId(msg.clientId());
+        restReq.key(msg.key());
+        restReq.command(CACHE_UPDATE_TLL);
+        restReq.cacheName(msg.cacheName());
+
+        switch (msg.command()) {
+            case EXPIRE:
+                restReq.ttl(Long.valueOf(msg.aux(TTL_POS)) * 1000);
+                break;
+            default:
+                // PEXPIRE
+                restReq.ttl(Long.valueOf(msg.aux(TTL_POS)));
+        }
+
+        return restReq;
+    }
+
+    /** {@inheritDoc} */
+    @Override public ByteBuffer makeResponse(final GridRestResponse restRes, List<String> params) {
+        return ((Boolean)restRes.getResponse() == true ? GridRedisProtocolParser.toInteger("1")
+            : GridRedisProtocolParser.toInteger("0"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/988ffe3e/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/GridRedisCommand.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/GridRedisCommand.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/GridRedisCommand.java
index bc3b9a2..bc32fb4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/GridRedisCommand.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/GridRedisCommand.java
@@ -67,6 +67,10 @@ public enum GridRedisCommand {
     DEL("DEL"),
     /** EXISTS. */
     EXISTS("EXISTS"),
+    /** EXPIRE. */
+    EXPIRE("EXPIRE"),
+    /** PEXPIRE. */
+    PEXPIRE("PEXPIRE"),
 
     // Server commands.
     /** DBSIZE. */

http://git-wip-us.apache.org/repos/asf/ignite/blob/988ffe3e/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/GridRedisNioListener.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/GridRedisNioListener.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/GridRedisNioListener.java
index 9436369..bc2daf2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/GridRedisNioListener.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/rest/protocols/tcp/redis/GridRedisNioListener.java
@@ -28,6 +28,7 @@ import org.apache.ignite.internal.processors.rest.handlers.redis.GridRedisComman
 import org.apache.ignite.internal.processors.rest.handlers.redis.GridRedisConnectionCommandHandler;
 import org.apache.ignite.internal.processors.rest.handlers.redis.key.GridRedisDelCommandHandler;
 import org.apache.ignite.internal.processors.rest.handlers.redis.key.GridRedisExistsCommandHandler;
+import org.apache.ignite.internal.processors.rest.handlers.redis.key.GridRedisExpireCommandHandler;
 import org.apache.ignite.internal.processors.rest.handlers.redis.server.GridRedisDbSizeCommandHandler;
 import org.apache.ignite.internal.processors.rest.handlers.redis.server.GridRedisFlushCommandHandler;
 import org.apache.ignite.internal.processors.rest.handlers.redis.string.GridRedisAppendCommandHandler;
@@ -87,6 +88,7 @@ public class GridRedisNioListener extends GridNioServerListenerAdapter<GridRedis
         // key commands.
         addCommandHandler(new GridRedisDelCommandHandler(log, hnd));
         addCommandHandler(new GridRedisExistsCommandHandler(log, hnd));
+        addCommandHandler(new GridRedisExpireCommandHandler(log, hnd));
 
         // server commands.
         addCommandHandler(new GridRedisDbSizeCommandHandler(log, hnd));


[12/30] ignite git commit: Merge branches 'ignite-2.1.3' and 'master'.

Posted by ag...@apache.org.
Merge branches 'ignite-2.1.3' and 'master'.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/9b730e73
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/9b730e73
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/9b730e73

Branch: refs/heads/ignite-5872
Commit: 9b730e732dcc7d307390f9a40cce8469e738e540
Parents: 70ffa2c 0eedf46
Author: Alexey Kuznetsov <ak...@apache.org>
Authored: Mon Aug 7 10:00:01 2017 +0700
Committer: Alexey Kuznetsov <ak...@apache.org>
Committed: Mon Aug 7 10:00:01 2017 +0700

----------------------------------------------------------------------
 .../hide-on-state-change/hide-on-state-change.directive.js   | 8 ++------
 modules/web-console/frontend/views/index.pug                 | 8 ++++++++
 2 files changed, 10 insertions(+), 6 deletions(-)
----------------------------------------------------------------------



[16/30] ignite git commit: IGNITE-5984 - Test fix: scan for a test key only after late affinity assignment changes

Posted by ag...@apache.org.
IGNITE-5984 - Test fix: scan for a test key only after late affinity assignment changes


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/c141ded2
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/c141ded2
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/c141ded2

Branch: refs/heads/ignite-5872
Commit: c141ded2565b0b277add5007f73a6fa7e97b3372
Parents: 9da6938
Author: Alexey Goncharuk <al...@gmail.com>
Authored: Tue Aug 8 14:53:34 2017 +0300
Committer: Alexey Goncharuk <al...@gmail.com>
Committed: Tue Aug 8 14:53:34 2017 +0300

----------------------------------------------------------------------
 .../processors/cache/GridCacheAbstractLocalStoreSelfTest.java | 7 +++++++
 1 file changed, 7 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/c141ded2/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractLocalStoreSelfTest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractLocalStoreSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractLocalStoreSelfTest.java
index ae9986d..328cde8 100644
--- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractLocalStoreSelfTest.java
+++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheAbstractLocalStoreSelfTest.java
@@ -47,6 +47,7 @@ import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.configuration.NearCacheConfiguration;
 import org.apache.ignite.events.Event;
 import org.apache.ignite.events.EventType;
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
 import org.apache.ignite.internal.processors.cache.store.CacheLocalStore;
 import org.apache.ignite.internal.util.lang.GridAbsPredicate;
 import org.apache.ignite.internal.util.typedef.G;
@@ -294,6 +295,12 @@ public abstract class GridCacheAbstractLocalStoreSelfTest extends GridCommonAbst
 
         awaitPartitionMapExchange();
 
+        // We need a backup key on grid 1, so we must wait for late affinity assignment to change.
+        AffinityTopologyVersion waitTopVer = new AffinityTopologyVersion(2, 1);
+
+        grid(1).context().cache().context().exchange().affinityReadyFuture(waitTopVer).get();
+        grid(2).context().cache().context().exchange().affinityReadyFuture(waitTopVer).get();
+
         final String name = BACKUP_CACHE_2;
 
         int key1 = -1;


[11/30] ignite git commit: IGNITE-5939: ODBC: SQLColAttributes now works with legacy attribute codes.

Posted by ag...@apache.org.
IGNITE-5939: ODBC: SQLColAttributes now works with legacy attribute codes.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/70ffa2cd
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/70ffa2cd
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/70ffa2cd

Branch: refs/heads/ignite-5872
Commit: 70ffa2cdf2a8210d42d32c2a35c9a21ee87aaa1f
Parents: 359777f
Author: Igor Sapego <is...@gridgain.com>
Authored: Fri Aug 4 18:34:27 2017 +0300
Committer: Igor Sapego <is...@gridgain.com>
Committed: Fri Aug 4 18:35:26 2017 +0300

----------------------------------------------------------------------
 .../cpp/odbc-test/src/meta_queries_test.cpp     | 51 ++++++++++++++++++++
 .../platforms/cpp/odbc/src/meta/column_meta.cpp |  3 ++
 2 files changed, 54 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/70ffa2cd/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp b/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
index 5b7ae59..454a989 100644
--- a/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/meta_queries_test.cpp
@@ -186,4 +186,55 @@ BOOST_AUTO_TEST_CASE(TestGetTypeInfoAllTypes)
         BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
 }
 
+BOOST_AUTO_TEST_CASE(TestColAttributesColumnLength)
+{
+    Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
+
+    SQLCHAR req[] = "select strField from TestType";
+    SQLExecDirect(stmt, req, SQL_NTS);
+
+    SQLLEN intVal;
+    SQLCHAR strBuf[1024];
+    SQLSMALLINT strLen;
+
+    SQLRETURN ret = SQLColAttribute(stmt, 1, SQL_COLUMN_LENGTH, strBuf, sizeof(strBuf), &strLen, &intVal);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+}
+
+BOOST_AUTO_TEST_CASE(TestColAttributesColumnPresicion)
+{
+    Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
+
+    SQLCHAR req[] = "select strField from TestType";
+    SQLExecDirect(stmt, req, SQL_NTS);
+
+    SQLLEN intVal;
+    SQLCHAR strBuf[1024];
+    SQLSMALLINT strLen;
+
+    SQLRETURN ret = SQLColAttribute(stmt, 1, SQL_COLUMN_PRECISION, strBuf, sizeof(strBuf), &strLen, &intVal);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+}
+
+BOOST_AUTO_TEST_CASE(TestColAttributesColumnScale)
+{
+    Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache");
+
+    SQLCHAR req[] = "select strField from TestType";
+    SQLExecDirect(stmt, req, SQL_NTS);
+
+    SQLLEN intVal;
+    SQLCHAR strBuf[1024];
+    SQLSMALLINT strLen;
+
+    SQLRETURN ret = SQLColAttribute(stmt, 1, SQL_COLUMN_SCALE, strBuf, sizeof(strBuf), &strLen, &intVal);
+
+    if (!SQL_SUCCEEDED(ret))
+        BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt));
+}
+
 BOOST_AUTO_TEST_SUITE_END()

http://git-wip-us.apache.org/repos/asf/ignite/blob/70ffa2cd/modules/platforms/cpp/odbc/src/meta/column_meta.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/src/meta/column_meta.cpp b/modules/platforms/cpp/odbc/src/meta/column_meta.cpp
index 12dbfc1..97fdf80 100644
--- a/modules/platforms/cpp/odbc/src/meta/column_meta.cpp
+++ b/modules/platforms/cpp/odbc/src/meta/column_meta.cpp
@@ -179,6 +179,7 @@ namespace ignite
 
                     case SQL_DESC_LENGTH:
                     case SQL_DESC_OCTET_LENGTH:
+                    case SQL_COLUMN_LENGTH:
                     {
                         value = type_traits::BinaryTypeTransferLength(dataType);
 
@@ -200,6 +201,7 @@ namespace ignite
                     }
 
                     case SQL_DESC_PRECISION:
+                    case SQL_COLUMN_PRECISION:
                     {
                         value = type_traits::BinaryTypeColumnSize(dataType);
 
@@ -207,6 +209,7 @@ namespace ignite
                     }
 
                     case SQL_DESC_SCALE:
+                    case SQL_COLUMN_SCALE:
                     {
                         value = type_traits::BinaryTypeDecimalDigits(dataType);
 


[17/30] ignite git commit: IGNITE-5982: GridMapQueryExecutor was split into several pieces.

Posted by ag...@apache.org.
IGNITE-5982: GridMapQueryExecutor was split into several pieces.


Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/e28d0d6c
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/e28d0d6c
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/e28d0d6c

Branch: refs/heads/ignite-5872
Commit: e28d0d6cc617a4b0c7b0e4c4a5197b69f0c3e4bc
Parents: 9da6938
Author: devozerov <vo...@gridgain.com>
Authored: Tue Aug 8 15:16:58 2017 +0300
Committer: devozerov <vo...@gridgain.com>
Committed: Tue Aug 8 15:16:58 2017 +0300

----------------------------------------------------------------------
 .../query/h2/twostep/GridMapQueryExecutor.java  | 501 ++-----------------
 .../query/h2/twostep/MapNodeResults.java        | 108 ++++
 .../query/h2/twostep/MapQueryResult.java        | 258 ++++++++++
 .../query/h2/twostep/MapQueryResults.java       | 155 ++++++
 .../h2/twostep/MapReplicatedReservation.java    |  38 ++
 .../query/h2/twostep/MapRequestKey.java         |  65 +++
 .../query/h2/twostep/MapReservationKey.java     |  73 +++
 7 files changed, 730 insertions(+), 468 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/e28d0d6c/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
index fcf5f10..19b628b 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/GridMapQueryExecutor.java
@@ -17,7 +17,6 @@
 
 package org.apache.ignite.internal.processors.query.h2.twostep;
 
-import java.lang.reflect.Field;
 import java.sql.Connection;
 import java.sql.ResultSet;
 import java.util.AbstractCollection;
@@ -31,7 +30,6 @@ import java.util.Objects;
 import java.util.UUID;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.atomic.AtomicReferenceArray;
 import javax.cache.CacheException;
 import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteException;
@@ -39,7 +37,6 @@ import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.cache.query.QueryCancelledException;
 import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.events.CacheQueryExecutedEvent;
-import org.apache.ignite.events.CacheQueryReadEvent;
 import org.apache.ignite.events.DiscoveryEvent;
 import org.apache.ignite.events.Event;
 import org.apache.ignite.events.EventType;
@@ -57,35 +54,29 @@ import org.apache.ignite.internal.processors.cache.query.CacheQueryType;
 import org.apache.ignite.internal.processors.cache.query.GridCacheQueryMarshallable;
 import org.apache.ignite.internal.processors.cache.query.GridCacheSqlQuery;
 import org.apache.ignite.internal.processors.cache.query.QueryTable;
-import org.apache.ignite.internal.processors.query.GridQueryCancel;
 import org.apache.ignite.internal.processors.query.h2.H2Utils;
 import org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing;
 import org.apache.ignite.internal.processors.query.h2.opt.DistributedJoinMode;
 import org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryContext;
 import org.apache.ignite.internal.processors.query.h2.opt.GridH2RetryException;
 import org.apache.ignite.internal.processors.query.h2.opt.GridH2Table;
-import org.apache.ignite.internal.processors.query.h2.opt.GridH2ValueCacheObject;
 import org.apache.ignite.internal.processors.query.h2.twostep.messages.GridQueryCancelRequest;
 import org.apache.ignite.internal.processors.query.h2.twostep.messages.GridQueryFailResponse;
 import org.apache.ignite.internal.processors.query.h2.twostep.messages.GridQueryNextPageRequest;
 import org.apache.ignite.internal.processors.query.h2.twostep.messages.GridQueryNextPageResponse;
 import org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2QueryRequest;
-import org.apache.ignite.internal.util.GridBoundedConcurrentLinkedHashMap;
 import org.apache.ignite.internal.util.GridSpinBusyLock;
 import org.apache.ignite.internal.util.typedef.CI1;
 import org.apache.ignite.internal.util.typedef.F;
-import org.apache.ignite.internal.util.typedef.T2;
 import org.apache.ignite.internal.util.typedef.X;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.plugin.extensions.communication.Message;
 import org.h2.jdbc.JdbcResultSet;
-import org.h2.result.ResultInterface;
 import org.h2.value.Value;
 import org.jetbrains.annotations.Nullable;
 import org.jsr166.ConcurrentHashMap8;
 
 import static org.apache.ignite.events.EventType.EVT_CACHE_QUERY_EXECUTED;
-import static org.apache.ignite.events.EventType.EVT_CACHE_QUERY_OBJECT_READ;
 import static org.apache.ignite.internal.managers.communication.GridIoPolicy.QUERY_POOL;
 import static org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion.NONE;
 import static org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionState.OWNING;
@@ -94,30 +85,13 @@ import static org.apache.ignite.internal.processors.query.h2.opt.DistributedJoin
 import static org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryType.MAP;
 import static org.apache.ignite.internal.processors.query.h2.opt.GridH2QueryType.REPLICATED;
 import static org.apache.ignite.internal.processors.query.h2.twostep.msg.GridH2ValueMessageFactory.toMessages;
-import static org.jsr166.ConcurrentLinkedHashMap.QueuePolicy.PER_SEGMENT_Q;
 
 /**
  * Map query executor.
  */
+@SuppressWarnings("ForLoopReplaceableByForEach")
 public class GridMapQueryExecutor {
     /** */
-    private static final Field RESULT_FIELD;
-
-    /*
-     * Initialize.
-     */
-    static {
-        try {
-            RESULT_FIELD = JdbcResultSet.class.getDeclaredField("result");
-
-            RESULT_FIELD.setAccessible(true);
-        }
-        catch (NoSuchFieldException e) {
-            throw new IllegalStateException("Check H2 version in classpath.", e);
-        }
-    }
-
-    /** */
     private IgniteLogger log;
 
     /** */
@@ -127,14 +101,13 @@ public class GridMapQueryExecutor {
     private IgniteH2Indexing h2;
 
     /** */
-    private ConcurrentMap<UUID, NodeResults> qryRess = new ConcurrentHashMap8<>();
+    private ConcurrentMap<UUID, MapNodeResults> qryRess = new ConcurrentHashMap8<>();
 
     /** */
     private final GridSpinBusyLock busyLock;
 
     /** */
-    private final ConcurrentMap<T2<String, AffinityTopologyVersion>, GridReservable> reservations =
-        new ConcurrentHashMap8<>();
+    private final ConcurrentMap<MapReservationKey, GridReservable> reservations = new ConcurrentHashMap8<>();
 
     /**
      * @param busyLock Busy lock.
@@ -162,7 +135,7 @@ public class GridMapQueryExecutor {
 
                 GridH2QueryContext.clearAfterDeadNode(locNodeId, nodeId);
 
-                NodeResults nodeRess = qryRess.remove(nodeId);
+                MapNodeResults nodeRess = qryRess.remove(nodeId);
 
                 if (nodeRess == null)
                     return;
@@ -172,6 +145,7 @@ public class GridMapQueryExecutor {
         }, EventType.EVT_NODE_FAILED, EventType.EVT_NODE_LEFT);
 
         ctx.io().addMessageListener(GridTopic.TOPIC_QUERY, new GridMessageListener() {
+            @SuppressWarnings("deprecation")
             @Override public void onMessage(UUID nodeId, Object msg, byte plc) {
                 if (!busyLock.enterBusy())
                     return;
@@ -228,7 +202,7 @@ public class GridMapQueryExecutor {
     private void onCancel(ClusterNode node, GridQueryCancelRequest msg) {
         long qryReqId = msg.queryRequestId();
 
-        NodeResults nodeRess = resultsForNode(node.id());
+        MapNodeResults nodeRess = resultsForNode(node.id());
 
         boolean clear = GridH2QueryContext.clear(ctx.localNodeId(), node.id(), qryReqId, MAP);
 
@@ -245,13 +219,13 @@ public class GridMapQueryExecutor {
      * @param nodeId Node ID.
      * @return Results for node.
      */
-    private NodeResults resultsForNode(UUID nodeId) {
-        NodeResults nodeRess = qryRess.get(nodeId);
+    private MapNodeResults resultsForNode(UUID nodeId) {
+        MapNodeResults nodeRess = qryRess.get(nodeId);
 
         if (nodeRess == null) {
-            nodeRess = new NodeResults();
+            nodeRess = new MapNodeResults();
 
-            NodeResults old = qryRess.putIfAbsent(nodeId, nodeRess);
+            MapNodeResults old = qryRess.putIfAbsent(nodeId, nodeRess);
 
             if (old != null)
                 nodeRess = old;
@@ -300,13 +274,12 @@ public class GridMapQueryExecutor {
                 continue;
 
             // For replicated cache topology version does not make sense.
-            final T2<String,AffinityTopologyVersion> grpKey =
-                new T2<>(cctx.name(), cctx.isReplicated() ? null : topVer);
+            final MapReservationKey grpKey = new MapReservationKey(cctx.name(), cctx.isReplicated() ? null : topVer);
 
             GridReservable r = reservations.get(grpKey);
 
             if (explicitParts == null && r != null) { // Try to reserve group partition if any and no explicits.
-                if (r != ReplicatedReservation.INSTANCE) {
+                if (r != MapReplicatedReservation.INSTANCE) {
                     if (!r.reserve())
                         return false; // We need explicit partitions here -> retry.
 
@@ -327,7 +300,7 @@ public class GridMapQueryExecutor {
                         }
 
                         // Mark that we checked this replicated cache.
-                        reservations.putIfAbsent(grpKey, ReplicatedReservation.INSTANCE);
+                        reservations.putIfAbsent(grpKey, MapReplicatedReservation.INSTANCE);
                     }
                 }
                 else { // Reserve primary partitions for partitioned cache (if no explicit given).
@@ -381,6 +354,7 @@ public class GridMapQueryExecutor {
             return Collections.emptySet();
 
         return new AbstractCollection<Integer>() {
+            @SuppressWarnings("NullableProblems")
             @Override public Iterator<Integer> iterator() {
                 return new Iterator<Integer>() {
                     /** */
@@ -537,9 +511,9 @@ public class GridMapQueryExecutor {
         GridCacheContext<?, ?> mainCctx =
             !F.isEmpty(cacheIds) ? ctx.cache().context().cacheContext(cacheIds.get(0)) : null;
 
-        NodeResults nodeRess = resultsForNode(node.id());
+        MapNodeResults nodeRess = resultsForNode(node.id());
 
-        QueryResults qr = null;
+        MapQueryResults qr = null;
 
         List<GridReservable> reserved = new ArrayList<>();
 
@@ -553,7 +527,7 @@ public class GridMapQueryExecutor {
                 }
             }
 
-            qr = new QueryResults(reqId, qrys.size(), mainCctx != null ? mainCctx.name() : null);
+            qr = new MapQueryResults(h2, reqId, qrys.size(), mainCctx != null ? mainCctx.name() : null);
 
             if (nodeRess.put(reqId, segmentId, qr) != null)
                 throw new IllegalStateException();
@@ -619,7 +593,7 @@ public class GridMapQueryExecutor {
                         rs = h2.executeSqlQueryWithTimer(conn, qry.query(),
                             F.asList(qry.parameters(params)), true,
                             timeout,
-                            qr.cancels[qryIdx]);
+                            qr.queryCancel(qryIdx));
 
                         if (evt) {
                             assert mainCctx != null;
@@ -644,7 +618,7 @@ public class GridMapQueryExecutor {
 
                     qr.addResult(qryIdx, qry, node.id(), rs, params);
 
-                    if (qr.canceled) {
+                    if (qr.cancelled()) {
                         qr.result(qryIdx).close();
 
                         throw new QueryCancelledException();
@@ -724,7 +698,7 @@ public class GridMapQueryExecutor {
      * @param req Request.
      */
     private void onNextPageRequest(ClusterNode node, GridQueryNextPageRequest req) {
-        NodeResults nodeRess = qryRess.get(node.id());
+        MapNodeResults nodeRess = qryRess.get(node.id());
 
         if (nodeRess == null) {
             sendError(node, req.queryRequestId(), new CacheException("No node result found for request: " + req));
@@ -736,11 +710,11 @@ public class GridMapQueryExecutor {
             return;
         }
 
-        QueryResults qr = nodeRess.get(req.queryRequestId(), req.segmentId());
+        MapQueryResults qr = nodeRess.get(req.queryRequestId(), req.segmentId());
 
         if (qr == null)
             sendError(node, req.queryRequestId(), new CacheException("No query result found for request: " + req));
-        else if (qr.canceled)
+        else if (qr.cancelled())
             sendError(node, req.queryRequestId(), new QueryCancelledException());
         else
             sendNextPage(nodeRess, node, qr, req.query(), req.segmentId(), req.pageSize());
@@ -754,16 +728,16 @@ public class GridMapQueryExecutor {
      * @param segmentId Index segment ID.
      * @param pageSize Page size.
      */
-    private void sendNextPage(NodeResults nodeRess, ClusterNode node, QueryResults qr, int qry, int segmentId,
+    private void sendNextPage(MapNodeResults nodeRess, ClusterNode node, MapQueryResults qr, int qry, int segmentId,
         int pageSize) {
-        QueryResult res = qr.result(qry);
+        MapQueryResult res = qr.result(qry);
 
         assert res != null;
 
-        if (res.closed)
+        if (res.closed())
             return;
 
-        int page = res.page;
+        int page = res.page();
 
         List<Value[]> rows = new ArrayList<>(Math.min(64, pageSize));
 
@@ -773,16 +747,16 @@ public class GridMapQueryExecutor {
             res.close();
 
             if (qr.isAllClosed())
-                nodeRess.remove(qr.qryReqId, segmentId, qr);
+                nodeRess.remove(qr.queryRequestId(), segmentId, qr);
         }
 
         try {
             boolean loc = node.isLocal();
 
-            GridQueryNextPageResponse msg = new GridQueryNextPageResponse(qr.qryReqId, segmentId, qry, page,
-                page == 0 ? res.rowCnt : -1,
-                res.cols,
-                loc ? null : toMessages(rows, new ArrayList<Message>(res.cols)),
+            GridQueryNextPageResponse msg = new GridQueryNextPageResponse(qr.queryRequestId(), segmentId, qry, page,
+                page == 0 ? res.rowCount() : -1,
+                res.columnCount(),
+                loc ? null : toMessages(rows, new ArrayList<Message>(res.columnCount())),
                 loc ? rows : null);
 
             if (loc)
@@ -828,418 +802,9 @@ public class GridMapQueryExecutor {
      */
     public void onCacheStop(String cacheName) {
         // Drop group reservations.
-        for (T2<String,AffinityTopologyVersion> grpKey : reservations.keySet()) {
-            if (F.eq(grpKey.get1(), cacheName))
+        for (MapReservationKey grpKey : reservations.keySet()) {
+            if (F.eq(grpKey.cacheName(), cacheName))
                 reservations.remove(grpKey);
         }
     }
-
-
-    /**
-     *
-     */
-    private static class NodeResults {
-        /** */
-        private final ConcurrentMap<RequestKey, QueryResults> res = new ConcurrentHashMap8<>();
-
-        /** */
-        private final GridBoundedConcurrentLinkedHashMap<Long, Boolean> qryHist =
-            new GridBoundedConcurrentLinkedHashMap<>(1024, 1024, 0.75f, 64, PER_SEGMENT_Q);
-
-        /**
-         * @param reqId Query Request ID.
-         * @return {@code False} if query was already cancelled.
-         */
-        boolean cancelled(long reqId) {
-            return qryHist.get(reqId) != null;
-        }
-
-        /**
-         * @param reqId Query Request ID.
-         * @return {@code True} if cancelled.
-         */
-        boolean onCancel(long reqId) {
-            Boolean old = qryHist.putIfAbsent(reqId, Boolean.FALSE);
-
-            return old == null;
-        }
-
-        /**
-         * @param reqId Query Request ID.
-         * @param segmentId Index segment ID.
-         * @return query partial results.
-         */
-        public QueryResults get(long reqId, int segmentId) {
-            return res.get(new RequestKey(reqId, segmentId));
-        }
-
-        /**
-         * Cancel all thread of given request.
-         * @param reqID Request ID.
-         */
-        public void cancelRequest(long reqID) {
-            for (RequestKey key : res.keySet()) {
-                if (key.reqId == reqID) {
-                    QueryResults removed = res.remove(key);
-
-                    if (removed != null)
-                        removed.cancel(true);
-                }
-
-            }
-        }
-
-        /**
-         * @param reqId Query Request ID.
-         * @param segmentId Index segment ID.
-         * @param qr Query Results.
-         * @return {@code True} if removed.
-         */
-        public boolean remove(long reqId, int segmentId, QueryResults qr) {
-            return res.remove(new RequestKey(reqId, segmentId), qr);
-        }
-
-        /**
-         * @param reqId Query Request ID.
-         * @param segmentId Index segment ID.
-         * @param qr Query Results.
-         * @return previous value.
-         */
-        public QueryResults put(long reqId, int segmentId, QueryResults qr) {
-            return res.put(new RequestKey(reqId, segmentId), qr);
-        }
-
-        /**
-         * Cancel all node queries.
-         */
-        public void cancelAll() {
-            for (QueryResults ress : res.values())
-                ress.cancel(true);
-        }
-
-        /**
-         *
-         */
-        private static class RequestKey {
-            /** */
-            private long reqId;
-
-            /** */
-            private int segmentId;
-
-            /** Constructor */
-            RequestKey(long reqId, int segmentId) {
-                this.reqId = reqId;
-                this.segmentId = segmentId;
-            }
-
-            /** {@inheritDoc} */
-            @Override public boolean equals(Object o) {
-                if (this == o)
-                    return true;
-                if (o == null || getClass() != o.getClass())
-                    return false;
-
-                RequestKey other = (RequestKey)o;
-
-                return reqId == other.reqId && segmentId == other.segmentId;
-
-            }
-
-            /** {@inheritDoc} */
-            @Override public int hashCode() {
-                int result = (int)(reqId ^ (reqId >>> 32));
-                result = 31 * result + segmentId;
-                return result;
-            }
-        }
-    }
-
-    /**
-     *
-     */
-    private class QueryResults {
-        /** */
-        private final long qryReqId;
-
-        /** */
-        private final AtomicReferenceArray<QueryResult> results;
-
-        /** */
-        private final GridQueryCancel[] cancels;
-
-        /** */
-        private final String cacheName;
-
-        /** */
-        private volatile boolean canceled;
-
-        /**
-         * @param qryReqId Query request ID.
-         * @param qrys Number of queries.
-         * @param cacheName Cache name.
-         */
-        @SuppressWarnings("unchecked")
-        private QueryResults(long qryReqId, int qrys, @Nullable String cacheName) {
-            this.qryReqId = qryReqId;
-            this.cacheName = cacheName;
-
-            results = new AtomicReferenceArray<>(qrys);
-            cancels = new GridQueryCancel[qrys];
-
-            for (int i = 0; i < cancels.length; i++)
-                cancels[i] = new GridQueryCancel();
-        }
-
-        /**
-         * @param qry Query result index.
-         * @return Query result.
-         */
-        QueryResult result(int qry) {
-            return results.get(qry);
-        }
-
-        /**
-         * @param qry Query result index.
-         * @param q Query object.
-         * @param qrySrcNodeId Query source node.
-         * @param rs Result set.
-         */
-        void addResult(int qry, GridCacheSqlQuery q, UUID qrySrcNodeId, ResultSet rs, Object[] params) {
-            if (!results.compareAndSet(qry, null, new QueryResult(rs, ctx, cacheName, qrySrcNodeId, q, params)))
-                throw new IllegalStateException();
-        }
-
-        /**
-         * @return {@code true} If all results are closed.
-         */
-        boolean isAllClosed() {
-            for (int i = 0; i < results.length(); i++) {
-                QueryResult res = results.get(i);
-
-                if (res == null || !res.closed)
-                    return false;
-            }
-
-            return true;
-        }
-
-        /**
-         * Cancels the query.
-         */
-        void cancel(boolean forceQryCancel) {
-            if (canceled)
-                return;
-
-            canceled = true;
-
-            for (int i = 0; i < results.length(); i++) {
-                QueryResult res = results.get(i);
-
-                if (res != null) {
-                    res.close();
-
-                    continue;
-                }
-
-                if (forceQryCancel) {
-                    GridQueryCancel cancel = cancels[i];
-
-                    if (cancel != null)
-                        cancel.cancel();
-                }
-            }
-        }
-    }
-
-    /**
-     * Result for a single part of the query.
-     */
-    private class QueryResult implements AutoCloseable {
-        /** */
-        private final ResultInterface res;
-
-        /** */
-        private final ResultSet rs;
-
-        /** Kernal context. */
-        private final GridKernalContext ctx;
-
-        /** */
-        private final String cacheName;
-
-        /** */
-        private final GridCacheSqlQuery qry;
-
-        /** */
-        private final UUID qrySrcNodeId;
-
-        /** */
-        private final int cols;
-
-        /** */
-        private int page;
-
-        /** */
-        private final int rowCnt;
-
-        /** */
-        private boolean cpNeeded;
-
-        /** */
-        private volatile boolean closed;
-
-        /** */
-        private final Object[] params;
-
-        /**
-         * @param rs Result set.
-         * @param ctx Kernal context.
-         * @param cacheName Cache name.
-         * @param qrySrcNodeId Query source node.
-         * @param qry Query.
-         * @param params Query params.
-         */
-        private QueryResult(ResultSet rs, GridKernalContext ctx, @Nullable String cacheName,
-            UUID qrySrcNodeId, GridCacheSqlQuery qry, Object[] params) {
-            this.ctx = ctx;
-            this.cacheName = cacheName;
-            this.qry = qry;
-            this.params = params;
-            this.qrySrcNodeId = qrySrcNodeId;
-            this.cpNeeded = F.eq(ctx.localNodeId(), qrySrcNodeId);
-
-            if (rs != null) {
-                this.rs = rs;
-                try {
-                    res = (ResultInterface)RESULT_FIELD.get(rs);
-                }
-                catch (IllegalAccessException e) {
-                    throw new IllegalStateException(e); // Must not happen.
-                }
-
-                rowCnt = res.getRowCount();
-                cols = res.getVisibleColumnCount();
-            }
-            else {
-                this.rs = null;
-                this.res = null;
-                this.cols = -1;
-                this.rowCnt = -1;
-
-                closed = true;
-            }
-        }
-
-        /**
-         * @param rows Collection to fetch into.
-         * @param pageSize Page size.
-         * @return {@code true} If there are no more rows available.
-         */
-        synchronized boolean fetchNextPage(List<Value[]> rows, int pageSize) {
-            if (closed)
-                return true;
-
-            boolean readEvt = cacheName != null && ctx.event().isRecordable(EVT_CACHE_QUERY_OBJECT_READ);
-
-            page++;
-
-            for (int i = 0 ; i < pageSize; i++) {
-                if (!res.next())
-                    return true;
-
-                Value[] row = res.currentRow();
-
-                if (cpNeeded) {
-                    boolean copied = false;
-
-                    for (int j = 0; j < row.length; j++) {
-                        Value val = row[j];
-
-                        if (val instanceof GridH2ValueCacheObject) {
-                            GridH2ValueCacheObject valCacheObj = (GridH2ValueCacheObject)val;
-
-                            row[j] = new GridH2ValueCacheObject(valCacheObj.getCacheObject(), h2.objectContext()) {
-                                @Override public Object getObject() {
-                                    return getObject(true);
-                                }
-                            };
-
-                            copied = true;
-                        }
-                    }
-
-                    if (i == 0 && !copied)
-                        cpNeeded = false; // No copy on read caches, skip next checks.
-                }
-
-                assert row != null;
-
-                if (readEvt) {
-                    ctx.event().record(new CacheQueryReadEvent<>(
-                        ctx.discovery().localNode(),
-                        "SQL fields query result set row read.",
-                        EVT_CACHE_QUERY_OBJECT_READ,
-                        CacheQueryType.SQL.name(),
-                        cacheName,
-                        null,
-                        qry.query(),
-                        null,
-                        null,
-                        params,
-                        qrySrcNodeId,
-                        null,
-                        null,
-                        null,
-                        null,
-                        row(row)));
-                }
-
-                rows.add(res.currentRow());
-            }
-
-            return false;
-        }
-
-        /**
-         * @param row Values array row.
-         * @return Objects list row.
-         */
-        private List<?> row(Value[] row) {
-            List<Object> res = new ArrayList<>(row.length);
-
-            for (Value v : row)
-                res.add(v.getObject());
-
-            return res;
-        }
-
-        /** {@inheritDoc} */
-        @Override public synchronized void close() {
-            if (closed)
-                return;
-
-            closed = true;
-
-            U.close(rs, log);
-        }
-    }
-
-    /**
-     * Fake reservation object for replicated caches.
-     */
-    private static class ReplicatedReservation implements GridReservable {
-        /** */
-        static final ReplicatedReservation INSTANCE = new ReplicatedReservation();
-
-        /** {@inheritDoc} */
-        @Override public boolean reserve() {
-            throw new IllegalStateException();
-        }
-
-        /** {@inheritDoc} */
-        @Override public void release() {
-            throw new IllegalStateException();
-        }
-    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/e28d0d6c/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapNodeResults.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapNodeResults.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapNodeResults.java
new file mode 100644
index 0000000..d5ea357
--- /dev/null
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapNodeResults.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.query.h2.twostep;
+
+import org.apache.ignite.internal.util.GridBoundedConcurrentLinkedHashMap;
+import org.jsr166.ConcurrentHashMap8;
+
+import java.util.concurrent.ConcurrentMap;
+
+import static org.jsr166.ConcurrentLinkedHashMap.QueuePolicy.PER_SEGMENT_Q;
+
+/**
+ * Mapper node results.
+ */
+class MapNodeResults {
+    /** */
+    private final ConcurrentMap<MapRequestKey, MapQueryResults> res = new ConcurrentHashMap8<>();
+
+    /** */
+    private final GridBoundedConcurrentLinkedHashMap<Long, Boolean> qryHist =
+        new GridBoundedConcurrentLinkedHashMap<>(1024, 1024, 0.75f, 64, PER_SEGMENT_Q);
+
+    /**
+     * @param reqId Query Request ID.
+     * @return {@code False} if query was already cancelled.
+     */
+    boolean cancelled(long reqId) {
+        return qryHist.get(reqId) != null;
+    }
+
+    /**
+     * @param reqId Query Request ID.
+     * @return {@code True} if cancelled.
+     */
+    boolean onCancel(long reqId) {
+        Boolean old = qryHist.putIfAbsent(reqId, Boolean.FALSE);
+
+        return old == null;
+    }
+
+    /**
+     * @param reqId Query Request ID.
+     * @param segmentId Index segment ID.
+     * @return query partial results.
+     */
+    public MapQueryResults get(long reqId, int segmentId) {
+        return res.get(new MapRequestKey(reqId, segmentId));
+    }
+
+    /**
+     * Cancel all thread of given request.
+     * @param reqId Request ID.
+     */
+    public void cancelRequest(long reqId) {
+        for (MapRequestKey key : res.keySet()) {
+            if (key.requestId() == reqId) {
+                MapQueryResults removed = res.remove(key);
+
+                if (removed != null)
+                    removed.cancel(true);
+            }
+        }
+    }
+
+    /**
+     * @param reqId Query Request ID.
+     * @param segmentId Index segment ID.
+     * @param qr Query Results.
+     * @return {@code True} if removed.
+     */
+    public boolean remove(long reqId, int segmentId, MapQueryResults qr) {
+        return res.remove(new MapRequestKey(reqId, segmentId), qr);
+    }
+
+    /**
+     * @param reqId Query Request ID.
+     * @param segmentId Index segment ID.
+     * @param qr Query Results.
+     * @return previous value.
+     */
+    public MapQueryResults put(long reqId, int segmentId, MapQueryResults qr) {
+        return res.put(new MapRequestKey(reqId, segmentId), qr);
+    }
+
+    /**
+     * Cancel all node queries.
+     */
+    public void cancelAll() {
+        for (MapQueryResults ress : res.values())
+            ress.cancel(true);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/e28d0d6c/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapQueryResult.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapQueryResult.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapQueryResult.java
new file mode 100644
index 0000000..4799e03
--- /dev/null
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapQueryResult.java
@@ -0,0 +1,258 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.query.h2.twostep;
+
+import org.apache.ignite.events.CacheQueryReadEvent;
+import org.apache.ignite.internal.GridKernalContext;
+import org.apache.ignite.internal.processors.cache.query.CacheQueryType;
+import org.apache.ignite.internal.processors.cache.query.GridCacheSqlQuery;
+import org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing;
+import org.apache.ignite.internal.processors.query.h2.opt.GridH2ValueCacheObject;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.h2.jdbc.JdbcResultSet;
+import org.h2.result.ResultInterface;
+import org.h2.value.Value;
+import org.jetbrains.annotations.Nullable;
+
+import java.lang.reflect.Field;
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import static org.apache.ignite.events.EventType.EVT_CACHE_QUERY_OBJECT_READ;
+
+/**
+ * Mapper result for a single part of the query.
+ */
+class MapQueryResult implements AutoCloseable {
+    /** */
+    private static final Field RESULT_FIELD;
+
+    /*
+     * Initialize.
+     */
+    static {
+        try {
+            RESULT_FIELD = JdbcResultSet.class.getDeclaredField("result");
+
+            RESULT_FIELD.setAccessible(true);
+        }
+        catch (NoSuchFieldException e) {
+            throw new IllegalStateException("Check H2 version in classpath.", e);
+        }
+    }
+
+    /** Indexing. */
+    private final IgniteH2Indexing h2;
+
+    /** */
+    private final ResultInterface res;
+
+    /** */
+    private final ResultSet rs;
+
+    /** */
+    private final String cacheName;
+
+    /** */
+    private final GridCacheSqlQuery qry;
+
+    /** */
+    private final UUID qrySrcNodeId;
+
+    /** */
+    private final int cols;
+
+    /** */
+    private int page;
+
+    /** */
+    private final int rowCnt;
+
+    /** */
+    private boolean cpNeeded;
+
+    /** */
+    private volatile boolean closed;
+
+    /** */
+    private final Object[] params;
+
+    /**
+     * @param rs Result set.
+     * @param cacheName Cache name.
+     * @param qrySrcNodeId Query source node.
+     * @param qry Query.
+     * @param params Query params.
+     */
+    MapQueryResult(IgniteH2Indexing h2, ResultSet rs, @Nullable String cacheName,
+        UUID qrySrcNodeId, GridCacheSqlQuery qry, Object[] params) {
+        this.h2 = h2;
+        this.cacheName = cacheName;
+        this.qry = qry;
+        this.params = params;
+        this.qrySrcNodeId = qrySrcNodeId;
+        this.cpNeeded = F.eq(h2.kernalContext().localNodeId(), qrySrcNodeId);
+
+        if (rs != null) {
+            this.rs = rs;
+            try {
+                res = (ResultInterface)RESULT_FIELD.get(rs);
+            }
+            catch (IllegalAccessException e) {
+                throw new IllegalStateException(e); // Must not happen.
+            }
+
+            rowCnt = res.getRowCount();
+            cols = res.getVisibleColumnCount();
+        }
+        else {
+            this.rs = null;
+            this.res = null;
+            this.cols = -1;
+            this.rowCnt = -1;
+
+            closed = true;
+        }
+    }
+
+    /**
+     * @return Page number.
+     */
+    int page() {
+        return page;
+    }
+
+    /**
+     * @return Row count.
+     */
+    int rowCount() {
+        return rowCnt;
+    }
+
+    /**
+     * @return Column ocunt.
+     */
+    int columnCount() {
+        return cols;
+    }
+
+    /**
+     * @return Closed flag.
+     */
+    boolean closed() {
+        return closed;
+    }
+
+    /**
+     * @param rows Collection to fetch into.
+     * @param pageSize Page size.
+     * @return {@code true} If there are no more rows available.
+     */
+    synchronized boolean fetchNextPage(List<Value[]> rows, int pageSize) {
+        if (closed)
+            return true;
+
+        boolean readEvt = cacheName != null && h2.kernalContext().event().isRecordable(EVT_CACHE_QUERY_OBJECT_READ);
+
+        page++;
+
+        for (int i = 0 ; i < pageSize; i++) {
+            if (!res.next())
+                return true;
+
+            Value[] row = res.currentRow();
+
+            if (cpNeeded) {
+                boolean copied = false;
+
+                for (int j = 0; j < row.length; j++) {
+                    Value val = row[j];
+
+                    if (val instanceof GridH2ValueCacheObject) {
+                        GridH2ValueCacheObject valCacheObj = (GridH2ValueCacheObject)val;
+
+                        row[j] = new GridH2ValueCacheObject(valCacheObj.getCacheObject(), h2.objectContext()) {
+                            @Override public Object getObject() {
+                                return getObject(true);
+                            }
+                        };
+
+                        copied = true;
+                    }
+                }
+
+                if (i == 0 && !copied)
+                    cpNeeded = false; // No copy on read caches, skip next checks.
+            }
+
+            assert row != null;
+
+            if (readEvt) {
+                GridKernalContext ctx = h2.kernalContext();
+
+                ctx.event().record(new CacheQueryReadEvent<>(
+                    ctx.discovery().localNode(),
+                    "SQL fields query result set row read.",
+                    EVT_CACHE_QUERY_OBJECT_READ,
+                    CacheQueryType.SQL.name(),
+                    cacheName,
+                    null,
+                    qry.query(),
+                    null,
+                    null,
+                    params,
+                    qrySrcNodeId,
+                    null,
+                    null,
+                    null,
+                    null,
+                    row(row)));
+            }
+
+            rows.add(res.currentRow());
+        }
+
+        return false;
+    }
+
+    /**
+     * @param row Values array row.
+     * @return Objects list row.
+     */
+    private List<?> row(Value[] row) {
+        List<Object> res = new ArrayList<>(row.length);
+
+        for (Value v : row)
+            res.add(v.getObject());
+
+        return res;
+    }
+
+    /** {@inheritDoc} */
+    @Override public synchronized void close() {
+        if (closed)
+            return;
+
+        closed = true;
+
+        U.closeQuiet(rs);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/e28d0d6c/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapQueryResults.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapQueryResults.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapQueryResults.java
new file mode 100644
index 0000000..7ad1d14
--- /dev/null
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapQueryResults.java
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.query.h2.twostep;
+
+import org.apache.ignite.internal.processors.cache.query.GridCacheSqlQuery;
+import org.apache.ignite.internal.processors.query.GridQueryCancel;
+import org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing;
+import org.jetbrains.annotations.Nullable;
+
+import java.sql.ResultSet;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicReferenceArray;
+
+/**
+ * Mapper query results.
+ */
+class MapQueryResults {
+    /** H@ indexing. */
+    private final IgniteH2Indexing h2;
+
+    /** */
+    private final long qryReqId;
+
+    /** */
+    private final AtomicReferenceArray<MapQueryResult> results;
+
+    /** */
+    private final GridQueryCancel[] cancels;
+
+    /** */
+    private final String cacheName;
+
+    /** */
+    private volatile boolean cancelled;
+
+    /**
+     * @param qryReqId Query request ID.
+     * @param qrys Number of queries.
+     * @param cacheName Cache name.
+     */
+    @SuppressWarnings("unchecked")
+    MapQueryResults(IgniteH2Indexing h2, long qryReqId, int qrys,
+        @Nullable String cacheName) {
+        this.h2 = h2;
+        this.qryReqId = qryReqId;
+        this.cacheName = cacheName;
+
+        results = new AtomicReferenceArray<>(qrys);
+        cancels = new GridQueryCancel[qrys];
+
+        for (int i = 0; i < cancels.length; i++)
+            cancels[i] = new GridQueryCancel();
+    }
+
+    /**
+     * @param qry Query result index.
+     * @return Query result.
+     */
+    MapQueryResult result(int qry) {
+        return results.get(qry);
+    }
+
+    /**
+     * Get cancel token for query.
+     *
+     * @param qryIdx Query index.
+     * @return Cancel token.
+     */
+    GridQueryCancel queryCancel(int qryIdx) {
+        return cancels[qryIdx];
+    }
+
+    /**
+     * @param qry Query result index.
+     * @param q Query object.
+     * @param qrySrcNodeId Query source node.
+     * @param rs Result set.
+     */
+    void addResult(int qry, GridCacheSqlQuery q, UUID qrySrcNodeId, ResultSet rs, Object[] params) {
+        MapQueryResult res = new MapQueryResult(h2, rs, cacheName, qrySrcNodeId, q, params);
+
+        if (!results.compareAndSet(qry, null, res))
+            throw new IllegalStateException();
+    }
+
+    /**
+     * @return {@code true} If all results are closed.
+     */
+    boolean isAllClosed() {
+        for (int i = 0; i < results.length(); i++) {
+            MapQueryResult res = results.get(i);
+
+            if (res == null || !res.closed())
+                return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Cancels the query.
+     */
+    void cancel(boolean forceQryCancel) {
+        if (cancelled)
+            return;
+
+        cancelled = true;
+
+        for (int i = 0; i < results.length(); i++) {
+            MapQueryResult res = results.get(i);
+
+            if (res != null) {
+                res.close();
+
+                continue;
+            }
+
+            if (forceQryCancel) {
+                GridQueryCancel cancel = cancels[i];
+
+                if (cancel != null)
+                    cancel.cancel();
+            }
+        }
+    }
+
+    /**
+     * @return Cancel flag.
+     */
+    boolean cancelled() {
+        return cancelled;
+    }
+
+    /**
+     * @return Query request ID.
+     */
+    long queryRequestId() {
+        return qryReqId;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/e28d0d6c/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapReplicatedReservation.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapReplicatedReservation.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapReplicatedReservation.java
new file mode 100644
index 0000000..dd8237b
--- /dev/null
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapReplicatedReservation.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.query.h2.twostep;
+
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridReservable;
+
+/**
+ * Mapper fake reservation object for replicated caches.
+ */
+class MapReplicatedReservation implements GridReservable {
+    /** */
+    static final MapReplicatedReservation INSTANCE = new MapReplicatedReservation();
+
+    /** {@inheritDoc} */
+    @Override public boolean reserve() {
+        throw new IllegalStateException();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void release() {
+        throw new IllegalStateException();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/e28d0d6c/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapRequestKey.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapRequestKey.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapRequestKey.java
new file mode 100644
index 0000000..6feb8ea
--- /dev/null
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapRequestKey.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.query.h2.twostep;
+
+/**
+ * Mapper request key.
+ */
+class MapRequestKey {
+    /** */
+    private long reqId;
+
+    /** */
+    private int segmentId;
+
+    /** Constructor */
+    MapRequestKey(long reqId, int segmentId) {
+        this.reqId = reqId;
+        this.segmentId = segmentId;
+    }
+
+    /**
+     * @return Request ID.
+     */
+    public long requestId() {
+        return reqId;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+
+        if (o == null || getClass() != o.getClass())
+            return false;
+
+        MapRequestKey other = (MapRequestKey)o;
+
+        return reqId == other.reqId && segmentId == other.segmentId;
+
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        int res = (int)(reqId ^ (reqId >>> 32));
+
+        res = 31 * res + segmentId;
+
+        return res;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/e28d0d6c/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapReservationKey.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapReservationKey.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapReservationKey.java
new file mode 100644
index 0000000..9d2d7ba
--- /dev/null
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/twostep/MapReservationKey.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.query.h2.twostep;
+
+import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
+import org.apache.ignite.internal.util.typedef.F;
+
+/**
+ * Mapper reservation key.
+ */
+public class MapReservationKey {
+    /** Cache name. */
+    private final String cacheName;
+
+    /** Topology version. */
+    private final AffinityTopologyVersion topVer;
+
+    /**
+     * Constructor.
+     *
+     * @param cacheName Cache name.
+     * @param topVer Topology version.
+     */
+    public MapReservationKey(String cacheName, AffinityTopologyVersion topVer) {
+        this.cacheName = cacheName;
+        this.topVer = topVer;
+    }
+
+    /**
+     * @return Cache name.
+     */
+    public String cacheName() {
+        return cacheName;
+    }
+
+    /** {@inheritDoc} */
+    @Override public boolean equals(Object o) {
+        if (this == o)
+            return true;
+
+        if (o == null || getClass() != o.getClass())
+            return false;
+
+        MapReservationKey other = (MapReservationKey)o;
+
+        return F.eq(cacheName, other.cacheName) && F.eq(topVer, other.topVer);
+
+    }
+
+    /** {@inheritDoc} */
+    @Override public int hashCode() {
+        int res = cacheName != null ? cacheName.hashCode() : 0;
+
+        res = 31 * res + (topVer != null ? topVer.hashCode() : 0);
+
+        return res;
+    }
+}