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/04/06 10:46:12 UTC

[35/50] [abbrv] ignite git commit: IGNITE-3585: CPP: Container-based methods now accept iterators

IGNITE-3585: CPP: Container-based methods now accept iterators


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

Branch: refs/heads/ignite-3477-master
Commit: d34a4d06dcab2b23cfc07544102f75f1b9d47d10
Parents: ece4928
Author: Igor Sapego <is...@gridgain.com>
Authored: Mon Apr 3 16:15:58 2017 +0300
Committer: Igor Sapego <is...@gridgain.com>
Committed: Mon Apr 3 16:39:01 2017 +0300

----------------------------------------------------------------------
 .../include/ignite/impl/binary/binary_utils.h   |  13 +-
 .../cpp/core-test/include/ignite/test_utils.h   |  11 +
 .../cpp/core-test/src/cache_query_test.cpp      | 225 ++++++++++++++-----
 .../platforms/cpp/core-test/src/cache_test.cpp  | 204 +++++++++++++++++
 .../cpp/core-test/src/cluster_test.cpp          |   4 +-
 .../cpp/core/include/ignite/cache/cache.h       | 161 +++++++++++++
 .../cpp/core/include/ignite/cache/cache_entry.h |  15 ++
 .../include/ignite/cache/query/query_cursor.h   |  28 ++-
 .../ignite/impl/cache/query/query_impl.h        |   7 +
 .../cpp/core/include/ignite/impl/helpers.h      |  57 +++++
 .../cpp/core/include/ignite/impl/operations.h   | 136 ++++++++++-
 .../platforms/cpp/core/project/vs/core.vcxproj  |   1 +
 .../cpp/core/project/vs/core.vcxproj.filters    |   3 +
 .../core/src/impl/cache/query/query_impl.cpp    |  39 +++-
 14 files changed, 830 insertions(+), 74 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ignite/blob/d34a4d06/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_utils.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_utils.h b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_utils.h
index 6cd90b0..268c2d8 100644
--- a/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_utils.h
+++ b/modules/platforms/cpp/binary/include/ignite/impl/binary/binary_utils.h
@@ -20,14 +20,15 @@
 
 #include <stdint.h>
 
-#include "ignite/common/utils.h"
+#include <ignite/common/utils.h>
 
-#include "ignite/guid.h"
-#include "ignite/date.h"
-#include "ignite/timestamp.h"
-#include "ignite/time.h"
+#include <ignite/guid.h>
+#include <ignite/date.h>
+#include <ignite/timestamp.h>
+#include <ignite/time.h>
 
-#include "ignite/binary/binary_type.h"
+#include <ignite/binary/binary_type.h>
+#include <ignite/impl/binary/binary_writer_impl.h>
 
 namespace ignite
 {

http://git-wip-us.apache.org/repos/asf/ignite/blob/d34a4d06/modules/platforms/cpp/core-test/include/ignite/test_utils.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/include/ignite/test_utils.h b/modules/platforms/cpp/core-test/include/ignite/test_utils.h
index 2336626..67fda95 100644
--- a/modules/platforms/cpp/core-test/include/ignite/test_utils.h
+++ b/modules/platforms/cpp/core-test/include/ignite/test_utils.h
@@ -58,6 +58,17 @@ namespace ignite_test
      * @return New node.
      */
     ignite::Ignite StartNode(const char* cfgFile, const char* name);
+
+    /**
+     * Check if the error is generic.
+     *
+     * @param err Error.
+     * @return True if the error is generic.
+     */
+    inline bool IsGenericError(const ignite::IgniteError& err)
+    {
+        return err.GetCode() == ignite::IgniteError::IGNITE_ERR_GENERIC;
+    }
 }
 
 #endif // _IGNITE_CORE_TEST_TEST_UTILS
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/d34a4d06/modules/platforms/cpp/core-test/src/cache_query_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/cache_query_test.cpp b/modules/platforms/cpp/core-test/src/cache_query_test.cpp
index abb374a..871f66a 100644
--- a/modules/platforms/cpp/core-test/src/cache_query_test.cpp
+++ b/modules/platforms/cpp/core-test/src/cache_query_test.cpp
@@ -20,6 +20,7 @@
 #endif
 
 #include <sstream>
+#include <iterator>
 
 #include <boost/test/unit_test.hpp>
 
@@ -321,16 +322,7 @@ int CountRecords(Cursor& cur)
 template<typename Cursor>
 void CheckHasNextFail(Cursor& cur)
 {
-    try
-    {
-        cur.HasNext();
-
-        BOOST_FAIL("Must fail.");
-    }
-    catch (IgniteError& err)
-    {
-        BOOST_REQUIRE(err.GetCode() == IgniteError::IGNITE_ERR_GENERIC);
-    }
+    BOOST_CHECK_EXCEPTION(cur.HasNext(), IgniteError, ignite_test::IsGenericError);
 }
 
 /**
@@ -341,16 +333,7 @@ void CheckHasNextFail(Cursor& cur)
 template<typename Cursor>
 void CheckGetNextFail(Cursor& cur)
 {
-    try
-    {
-        cur.GetNext();
-
-        BOOST_FAIL("Must fail.");
-    }
-    catch (IgniteError& err)
-    {
-        BOOST_REQUIRE(err.GetCode() == IgniteError::IGNITE_ERR_GENERIC);
-    }
+    BOOST_CHECK_EXCEPTION(cur.GetNext(), IgniteError, ignite_test::IsGenericError);
 }
 
 /**
@@ -360,18 +343,21 @@ void CheckGetNextFail(Cursor& cur)
  */
 void CheckGetAllFail(QueryCursor<int, QueryPerson>& cur)
 {
-    try 
-    {
-        std::vector<CacheEntry<int, QueryPerson> > res;
+    std::vector<CacheEntry<int, QueryPerson> > res;
 
-        cur.GetAll(res);
+    BOOST_CHECK_EXCEPTION(cur.GetAll(res), IgniteError, ignite_test::IsGenericError);
+}
 
-        BOOST_FAIL("Must fail.");
-    }
-    catch (IgniteError& err)
-    {
-        BOOST_REQUIRE(err.GetCode() == IgniteError::IGNITE_ERR_GENERIC);
-    }
+/**
+ * Ensure that iter version of GetAll() fails.
+ *
+ * @param cur Cursor.
+ */
+void CheckGetAllFailIter(QueryCursor<int, QueryPerson>& cur)
+{
+    std::vector<CacheEntry<int, QueryPerson> > res;
+
+    BOOST_CHECK_EXCEPTION(cur.GetAll(std::back_inserter(res)), IgniteError, ignite_test::IsGenericError);
 }
 
 /**
@@ -417,12 +403,29 @@ void CheckEmptyGetAll(QueryCursor<int, QueryPerson>& cur)
 }
 
 /**
+ * Check empty result through iter version of GetAll().
+ *
+ * @param cur Cursor.
+ */
+void CheckEmptyGetAllIter(QueryCursor<int, QueryPerson>& cur)
+{
+    std::vector<CacheEntry<int, QueryPerson> > res;
+
+    cur.GetAll(std::back_inserter(res));
+
+    BOOST_REQUIRE(res.size() == 0);
+
+    CheckHasNextFail(cur);
+    CheckGetNextFail(cur);
+}
+
+/**
  * Check single result through iteration.
  *
  * @param cur Cursor.
- * @param key1 Key.
- * @param name1 Name.
- * @param age1 Age.
+ * @param key Key.
+ * @param name Name.
+ * @param age Age.
  */
 void CheckSingle(QueryCursor<int, QueryPerson>& cur, int key, const std::string& name, int age)
 {
@@ -472,9 +475,9 @@ void CheckSingle(QueryFieldsCursor& cur, int key, const std::string& name, int a
  * Check single result through GetAll().
  *
  * @param cur Cursor.
- * @param key1 Key.
- * @param name1 Name.
- * @param age1 Age.
+ * @param key Key.
+ * @param name Name.
+ * @param age Age.
  */
 void CheckSingleGetAll(QueryCursor<int, QueryPerson>& cur, int key, const std::string& name, int age)
 {
@@ -486,11 +489,40 @@ void CheckSingleGetAll(QueryCursor<int, QueryPerson>& cur, int key, const std::s
     CheckGetNextFail(cur);
     CheckGetAllFail(cur);
 
-    BOOST_REQUIRE(res.size() == 1);
+    BOOST_CHECK_EQUAL(res.size(), 1);
 
-    BOOST_REQUIRE(res[0].GetKey() == 1);    
-    BOOST_REQUIRE(res[0].GetValue().GetName().compare(name) == 0);
-    BOOST_REQUIRE(res[0].GetValue().GetAge() == age);
+    BOOST_CHECK_EQUAL(res[0].GetKey(), key);
+    BOOST_CHECK_EQUAL(res[0].GetValue().GetName(), name);
+    BOOST_CHECK_EQUAL(res[0].GetValue().GetAge(), age);
+
+    CheckHasNextFail(cur);
+    CheckGetNextFail(cur);
+    CheckGetAllFail(cur);
+}
+
+/**
+ * Check single result through iter version of GetAll().
+ *
+ * @param cur Cursor.
+ * @param key Key.
+ * @param name Name.
+ * @param age Age.
+ */
+void CheckSingleGetAllIter(QueryCursor<int, QueryPerson>& cur, int key, const std::string& name, int age)
+{
+    std::vector<CacheEntry<int, QueryPerson> > res;
+
+    cur.GetAll(std::back_inserter(res));
+
+    CheckHasNextFail(cur);
+    CheckGetNextFail(cur);
+    CheckGetAllFail(cur);
+
+    BOOST_CHECK_EQUAL(res.size(), 1);
+
+    BOOST_CHECK_EQUAL(res[0].GetKey(), key);
+    BOOST_CHECK_EQUAL(res[0].GetValue().GetName(), name);
+    BOOST_CHECK_EQUAL(res[0].GetValue().GetAge(), age);
 
     CheckHasNextFail(cur);
     CheckGetNextFail(cur);
@@ -523,18 +555,18 @@ void CheckMultiple(QueryCursor<int, QueryPerson>& cur, int key1, const std::stri
 
         if (entry.GetKey() == key1)
         {
-            BOOST_REQUIRE(entry.GetValue().GetName().compare(name1) == 0);
-            BOOST_REQUIRE(entry.GetValue().GetAge() == age1);            
+            BOOST_CHECK_EQUAL(entry.GetValue().GetName(), name1);
+            BOOST_CHECK_EQUAL(entry.GetValue().GetAge(), age1);
         }
         else if (entry.GetKey() == key2)
         {
-            BOOST_REQUIRE(entry.GetValue().GetName().compare(name2) == 0);
-            BOOST_REQUIRE(entry.GetValue().GetAge() == age2);            
+            BOOST_CHECK_EQUAL(entry.GetValue().GetName(), name2);
+            BOOST_CHECK_EQUAL(entry.GetValue().GetAge(), age2);
         }
         else
             BOOST_FAIL("Unexpected entry.");
     }
-    
+
     BOOST_REQUIRE(!cur.HasNext());
 
     CheckGetNextFail(cur);
@@ -563,7 +595,7 @@ void CheckMultipleGetAll(QueryCursor<int, QueryPerson>& cur, int key1, const std
     CheckGetNextFail(cur);
     CheckGetAllFail(cur);
 
-    BOOST_REQUIRE(res.size() == 2);
+    BOOST_REQUIRE_EQUAL(res.size(), 2);
 
     for (int i = 0; i < 2; i++)
     {
@@ -571,13 +603,56 @@ void CheckMultipleGetAll(QueryCursor<int, QueryPerson>& cur, int key1, const std
 
         if (entry.GetKey() == key1)
         {
-            BOOST_REQUIRE(entry.GetValue().GetName().compare(name1) == 0);
-            BOOST_REQUIRE(entry.GetValue().GetAge() == age1);            
+            BOOST_CHECK_EQUAL(entry.GetValue().GetName(), name1);
+            BOOST_CHECK_EQUAL(entry.GetValue().GetAge(), age1);
         }
         else if (entry.GetKey() == key2)
         {
-            BOOST_REQUIRE(entry.GetValue().GetName().compare(name2) == 0);
-            BOOST_REQUIRE(entry.GetValue().GetAge() == age2);
+            BOOST_CHECK_EQUAL(entry.GetValue().GetName(), name2);
+            BOOST_CHECK_EQUAL(entry.GetValue().GetAge(), age2);
+        }
+        else
+            BOOST_FAIL("Unexpected entry.");
+    }
+}
+
+/**
+ * Check multiple results through iter verion of GetAll().
+ *
+ * @param cur Cursor.
+ * @param key1 Key 1.
+ * @param name1 Name 1.
+ * @param age1 Age 1.
+ * @param key2 Key 2.
+ * @param name2 Name 2.
+ * @param age2 Age 2.
+ */
+void CheckMultipleGetAllIter(QueryCursor<int, QueryPerson>& cur, int key1, const std::string& name1,
+    int age1, int key2, const std::string& name2, int age2)
+{
+    std::vector<CacheEntry<int, QueryPerson> > res;
+
+    cur.GetAll(std::back_inserter(res));
+
+    CheckHasNextFail(cur);
+    CheckGetNextFail(cur);
+    CheckGetAllFail(cur);
+
+    BOOST_REQUIRE_EQUAL(res.size(), 2);
+
+    for (int i = 0; i < 2; i++)
+    {
+        CacheEntry<int, QueryPerson> entry = res[i];
+
+        if (entry.GetKey() == key1)
+        {
+            BOOST_CHECK_EQUAL(entry.GetValue().GetName(), name1);
+            BOOST_CHECK_EQUAL(entry.GetValue().GetAge(), age1);
+        }
+        else if (entry.GetKey() == key2)
+        {
+            BOOST_CHECK_EQUAL(entry.GetValue().GetName(), name2);
+            BOOST_CHECK_EQUAL(entry.GetValue().GetAge(), age2);
         }
         else
             BOOST_FAIL("Unexpected entry.");
@@ -708,6 +783,9 @@ BOOST_AUTO_TEST_CASE(TestSqlQuery)
     cursor = cache.Query(qry);
     CheckEmptyGetAll(cursor);
 
+    cursor = cache.Query(qry);
+    CheckEmptyGetAllIter(cursor);
+
     // Test simple query.
     cache.Put(1, QueryPerson("A1", 10, MakeDateGmt(1990, 03, 18),
         MakeTimestampGmt(2016, 02, 10, 17, 39, 34, 579304685)));
@@ -721,6 +799,9 @@ BOOST_AUTO_TEST_CASE(TestSqlQuery)
     cursor = cache.Query(qry);
     CheckSingleGetAll(cursor, 1, "A1", 10);
 
+    cursor = cache.Query(qry);
+    CheckSingleGetAllIter(cursor, 1, "A1", 10);
+
     // Test simple distributed joins query.
     BOOST_CHECK(!qry.IsDistributedJoins());
     qry.SetDistributedJoins(true);
@@ -732,6 +813,9 @@ BOOST_AUTO_TEST_CASE(TestSqlQuery)
     cursor = cache.Query(qry);
     CheckSingleGetAll(cursor, 1, "A1", 10);
 
+    cursor = cache.Query(qry);
+    CheckSingleGetAllIter(cursor, 1, "A1", 10);
+
     qry.SetDistributedJoins(false);
 
     // Test simple local query.
@@ -745,6 +829,9 @@ BOOST_AUTO_TEST_CASE(TestSqlQuery)
     cursor = cache.Query(qry);
     CheckSingleGetAll(cursor, 1, "A1", 10);
 
+    cursor = cache.Query(qry);
+    CheckSingleGetAllIter(cursor, 1, "A1", 10);
+
     // Test query with arguments.
     qry.SetSql("age < ? AND name = ?");
     qry.AddArgument<int>(20);
@@ -756,6 +843,9 @@ BOOST_AUTO_TEST_CASE(TestSqlQuery)
     cursor = cache.Query(qry);
     CheckSingleGetAll(cursor, 1, "A1", 10);
 
+    cursor = cache.Query(qry);
+    CheckSingleGetAllIter(cursor, 1, "A1", 10);
+
     // Test query returning multiple entries.
     qry = SqlQuery("QueryPerson", "age < 30");
 
@@ -764,6 +854,9 @@ BOOST_AUTO_TEST_CASE(TestSqlQuery)
 
     cursor = cache.Query(qry);
     CheckMultipleGetAll(cursor, 1, "A1", 10, 2, "A2", 20);
+
+    cursor = cache.Query(qry);
+    CheckMultipleGetAllIter(cursor, 1, "A1", 10, 2, "A2", 20);
 }
 
 /**
@@ -831,6 +924,9 @@ BOOST_AUTO_TEST_CASE(TestTextQuery)
     cursor = cache.Query(qry);
     CheckEmptyGetAll(cursor);
 
+    cursor = cache.Query(qry);
+    CheckEmptyGetAllIter(cursor);
+
     // Test simple query.
     cache.Put(1, QueryPerson("A1", 10, MakeDateGmt(1990, 03, 18),
         MakeTimestampGmt(2016, 02, 10, 17, 39, 34, 579304685)));
@@ -844,6 +940,9 @@ BOOST_AUTO_TEST_CASE(TestTextQuery)
     cursor = cache.Query(qry);
     CheckSingleGetAll(cursor, 1, "A1", 10);
 
+    cursor = cache.Query(qry);
+    CheckSingleGetAllIter(cursor, 1, "A1", 10);
+
     // Test simple local query.
     qry.SetLocal(true);
 
@@ -853,6 +952,9 @@ BOOST_AUTO_TEST_CASE(TestTextQuery)
     cursor = cache.Query(qry);
     CheckSingleGetAll(cursor, 1, "A1", 10);
 
+    cursor = cache.Query(qry);
+    CheckSingleGetAllIter(cursor, 1, "A1", 10);
+
     // Test query returning multiple entries.
     qry = TextQuery("QueryPerson", "A*");
 
@@ -861,6 +963,9 @@ BOOST_AUTO_TEST_CASE(TestTextQuery)
 
     cursor = cache.Query(qry);
     CheckMultipleGetAll(cursor, 1, "A1", 10, 2, "A2", 20);
+
+    cursor = cache.Query(qry);
+    CheckMultipleGetAllIter(cursor, 1, "A1", 10, 2, "A2", 20);
 }
 
 /**
@@ -880,6 +985,9 @@ BOOST_AUTO_TEST_CASE(TestScanQuery)
     cursor = cache.Query(qry);
     CheckEmptyGetAll(cursor);
 
+    cursor = cache.Query(qry);
+    CheckEmptyGetAllIter(cursor);
+
     // Test simple query.
     cache.Put(1, QueryPerson("A1", 10, MakeDateGmt(1990, 03, 18),
         MakeTimestampGmt(2016, 02, 10, 17, 39, 34, 579304685)));
@@ -890,6 +998,9 @@ BOOST_AUTO_TEST_CASE(TestScanQuery)
     cursor = cache.Query(qry);
     CheckSingleGetAll(cursor, 1, "A1", 10);
 
+    cursor = cache.Query(qry);
+    CheckSingleGetAllIter(cursor, 1, "A1", 10);
+
     // Test query returning multiple entries.
     cache.Put(2, QueryPerson("A2", 20, MakeDateGmt(1989, 10, 26),
         MakeTimestampGmt(2016, 02, 10, 17, 39, 35, 678403201)));
@@ -899,6 +1010,9 @@ BOOST_AUTO_TEST_CASE(TestScanQuery)
 
     cursor = cache.Query(qry);
     CheckMultipleGetAll(cursor, 1, "A1", 10, 2, "A2", 20);
+
+    cursor = cache.Query(qry);
+    CheckMultipleGetAllIter(cursor, 1, "A1", 10, 2, "A2", 20);
 }
 
 /**
@@ -1692,16 +1806,7 @@ BOOST_AUTO_TEST_CASE(TestFieldsQueryPageSingle)
  */
 BOOST_AUTO_TEST_CASE(TestFieldsQueryPageZero)
 {
-    try
-    {
-        CheckFieldsQueryPages(0, 100, 0);
-
-        BOOST_FAIL("Exception expected.");
-    }
-    catch (IgniteError&)
-    {
-        // Expected.
-    }
+    BOOST_CHECK_THROW(CheckFieldsQueryPages(0, 100, 0), IgniteError);
 }
 
 BOOST_AUTO_TEST_SUITE_END()

http://git-wip-us.apache.org/repos/asf/ignite/blob/d34a4d06/modules/platforms/cpp/core-test/src/cache_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/cache_test.cpp b/modules/platforms/cpp/core-test/src/cache_test.cpp
index d57b757..22ad96c 100644
--- a/modules/platforms/cpp/core-test/src/cache_test.cpp
+++ b/modules/platforms/cpp/core-test/src/cache_test.cpp
@@ -146,6 +146,50 @@ BOOST_AUTO_TEST_CASE(TestRemoveAllKeys)
     BOOST_REQUIRE(1 == size);
 }
 
+BOOST_AUTO_TEST_CASE(TestRemoveAllKeysIterVector)
+{
+    cache::Cache<int, int> cache = Cache();
+
+    int size = cache.Size(cache::IGNITE_PEEK_MODE_ALL);
+
+    BOOST_REQUIRE(0 == size);
+
+    cache.Put(1, 1);
+    cache.Put(2, 2);
+    cache.Put(3, 3);
+
+    int keys[] = { 1, 2, 4, 5 };
+
+    std::vector<int> keySet(keys, keys + 4);
+
+    cache.RemoveAll(keySet.begin(), keySet.end());
+
+    size = cache.Size(cache::IGNITE_PEEK_MODE_PRIMARY);
+
+    BOOST_REQUIRE(1 == size);
+}
+
+BOOST_AUTO_TEST_CASE(TestRemoveAllKeysIterArray)
+{
+    cache::Cache<int, int> cache = Cache();
+
+    int size = cache.Size(cache::IGNITE_PEEK_MODE_ALL);
+
+    BOOST_REQUIRE(0 == size);
+
+    cache.Put(1, 1);
+    cache.Put(2, 2);
+    cache.Put(3, 3);
+
+    int keys[] = { 1, 2, 4, 5 };
+
+    cache.RemoveAll(keys, keys + 4);
+
+    size = cache.Size(cache::IGNITE_PEEK_MODE_PRIMARY);
+
+    BOOST_REQUIRE(1 == size);
+}
+
 BOOST_AUTO_TEST_CASE(TestPut)
 {
     cache::Cache<int, int> cache = Cache();
@@ -170,6 +214,36 @@ BOOST_AUTO_TEST_CASE(TestPutAll)
         BOOST_REQUIRE(i + 1 == cache.Get(i));
 }
 
+BOOST_AUTO_TEST_CASE(TestPutAllIterMap)
+{
+    std::map<int, int> map;
+
+    for (int i = 0; i < 100; i++)
+        map[i] = i + 1;
+    
+    cache::Cache<int, int> cache = Cache();
+
+    cache.PutAll(map.begin(), map.end());
+
+    for (int i = 0; i < 100; i++)
+        BOOST_REQUIRE(i + 1 == cache.Get(i));
+}
+
+BOOST_AUTO_TEST_CASE(TestPutAllIterVector)
+{
+    std::vector< cache::CacheEntry<int, int> > entries;
+
+    for (int i = 0; i < 100; i++)
+        entries.push_back(cache::CacheEntry<int, int>(i, i + 1));
+
+    cache::Cache<int, int> cache = Cache();
+
+    cache.PutAll(entries.begin(), entries.end());
+
+    for (int i = 0; i < 100; i++)
+        BOOST_REQUIRE(i + 1 == cache.Get(i));
+}
+
 BOOST_AUTO_TEST_CASE(TestPutIfAbsent)
 {
     cache::Cache<int, int> cache = Cache();
@@ -208,6 +282,40 @@ BOOST_AUTO_TEST_CASE(TestGetAll)
         BOOST_REQUIRE(i + 1 == map[i + 1]);
 }
 
+BOOST_AUTO_TEST_CASE(TestGetAllIterMap)
+{
+    cache::Cache<int, int> cache = Cache();
+
+    int keys[] = { 1, 2, 3, 4, 5 };
+
+    for (int i = 0; i < 5; ++i)
+        cache.Put(keys[i], i + 1);
+
+    std::map<int, int> map;
+
+    cache.GetAll(keys, keys + 5, std::inserter(map, map.begin()));
+
+    for (int i = 0; i < 5; ++i)
+        BOOST_REQUIRE(i + 1 == map[keys[i]]);
+}
+
+BOOST_AUTO_TEST_CASE(TestGetAllIterArray)
+{
+    cache::Cache<int, int> cache = Cache();
+
+    int keys[] = { 1, 2, 3, 4, 5 };
+
+    cache::CacheEntry<int, int> res[5];
+
+    for (int i = 0; i < 5; ++i)
+        cache.Put(keys[i], i + 1);
+
+    cache.GetAll(keys, keys + 5, res);
+
+    for (int i = 0; i < 5; ++i)
+        BOOST_REQUIRE(res[i].GetKey() == res[i].GetValue());
+}
+
 BOOST_AUTO_TEST_CASE(TestGetAndPut)
 {
     cache::Cache<int, int> cache = Cache();
@@ -284,6 +392,24 @@ BOOST_AUTO_TEST_CASE(TestContainsKeys)
     BOOST_REQUIRE(false == cache.ContainsKeys(keySet));
 }
 
+BOOST_AUTO_TEST_CASE(TestContainsKeysIter)
+{
+    cache::Cache<int, int> cache = Cache();
+
+    int keys[] = { 1, 2 };
+
+    BOOST_REQUIRE(false == cache.ContainsKeys(keys, keys + 2));
+
+    cache.Put(1, 1);
+    cache.Put(2, 2);
+
+    BOOST_REQUIRE(true == cache.ContainsKeys(keys, keys + 2));
+
+    cache.Remove(1);
+
+    BOOST_REQUIRE(false == cache.ContainsKeys(keys, keys + 2));
+}
+
 BOOST_AUTO_TEST_CASE(TestIsEmpty)
 {
     cache::Cache<int, int> cache = Cache();
@@ -358,6 +484,44 @@ BOOST_AUTO_TEST_CASE(TestLocalClearAll)
     BOOST_REQUIRE(0 == cache.LocalPeek(1, cache::IGNITE_PEEK_MODE_PRIMARY));
 }
 
+BOOST_AUTO_TEST_CASE(TestLocalClearAllIterList)
+{
+    cache::Cache<int, int> cache = Cache();
+
+    cache.Put(0, 3);
+    cache.Put(1, 3);
+
+    int keys[] = { 0, 1 };
+
+    std::list<int> keySet(keys, keys + 2);
+
+    BOOST_REQUIRE(3 == cache.LocalPeek(0, cache::IGNITE_PEEK_MODE_PRIMARY));
+    BOOST_REQUIRE(3 == cache.LocalPeek(1, cache::IGNITE_PEEK_MODE_PRIMARY));
+
+    cache.LocalClearAll(keySet.begin(), keySet.end());
+
+    BOOST_REQUIRE(0 == cache.LocalPeek(0, cache::IGNITE_PEEK_MODE_PRIMARY));
+    BOOST_REQUIRE(0 == cache.LocalPeek(1, cache::IGNITE_PEEK_MODE_PRIMARY));
+}
+
+BOOST_AUTO_TEST_CASE(TestLocalClearAllIterArray)
+{
+    cache::Cache<int, int> cache = Cache();
+
+    cache.Put(0, 3);
+    cache.Put(1, 3);
+
+    int keys[] = { 0, 1 };
+
+    BOOST_REQUIRE(3 == cache.LocalPeek(0, cache::IGNITE_PEEK_MODE_PRIMARY));
+    BOOST_REQUIRE(3 == cache.LocalPeek(1, cache::IGNITE_PEEK_MODE_PRIMARY));
+
+    cache.LocalClearAll(keys, keys + 2);
+
+    BOOST_REQUIRE(0 == cache.LocalPeek(0, cache::IGNITE_PEEK_MODE_PRIMARY));
+    BOOST_REQUIRE(0 == cache.LocalPeek(1, cache::IGNITE_PEEK_MODE_PRIMARY));
+}
+
 BOOST_AUTO_TEST_CASE(TestSizes)
 {
     cache::Cache<int, int> cache = Cache();
@@ -393,6 +557,46 @@ BOOST_AUTO_TEST_CASE(TestLocalEvict)
     BOOST_REQUIRE(5 == cache.LocalPeek(1, cache::IGNITE_PEEK_MODE_ONHEAP));
 }
 
+BOOST_AUTO_TEST_CASE(TestLocalEvictIterSet)
+{
+    cache::Cache<int, int> cache = Cache();
+
+    cache.Put(1, 5);
+
+    BOOST_REQUIRE(5 == cache.LocalPeek(1, cache::IGNITE_PEEK_MODE_ONHEAP));
+
+    int keys[] = { 0, 1 };
+
+    std::set<int> keySet(keys, keys + 2);
+
+    cache.LocalEvict(keySet.begin(), keySet.end());
+
+    BOOST_REQUIRE(0 == cache.LocalPeek(1, cache::IGNITE_PEEK_MODE_ONHEAP));
+
+    BOOST_REQUIRE(5 == cache.Get(1));
+
+    BOOST_REQUIRE(5 == cache.LocalPeek(1, cache::IGNITE_PEEK_MODE_ONHEAP));
+}
+
+BOOST_AUTO_TEST_CASE(TestLocalEvictIterArray)
+{
+    cache::Cache<int, int> cache = Cache();
+
+    cache.Put(1, 5);
+
+    BOOST_REQUIRE(5 == cache.LocalPeek(1, cache::IGNITE_PEEK_MODE_ONHEAP));
+
+    int keys[] = { 0, 1 };
+
+    cache.LocalEvict(keys, keys + 2);
+
+    BOOST_REQUIRE(0 == cache.LocalPeek(1, cache::IGNITE_PEEK_MODE_ONHEAP));
+
+    BOOST_REQUIRE(5 == cache.Get(1));
+
+    BOOST_REQUIRE(5 == cache.LocalPeek(1, cache::IGNITE_PEEK_MODE_ONHEAP));
+}
+
 BOOST_AUTO_TEST_CASE(TestBinary)
 {
     cache::Cache<int, Person> cache = grid0.GetCache<int, Person>("partitioned");

http://git-wip-us.apache.org/repos/asf/ignite/blob/d34a4d06/modules/platforms/cpp/core-test/src/cluster_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/cluster_test.cpp b/modules/platforms/cpp/core-test/src/cluster_test.cpp
index 7b206d2..c681ca2 100644
--- a/modules/platforms/cpp/core-test/src/cluster_test.cpp
+++ b/modules/platforms/cpp/core-test/src/cluster_test.cpp
@@ -34,7 +34,7 @@ using namespace boost::unit_test;
  */
 struct ClusterTestSuiteFixture
 {
-    Ignite grid;
+    Ignite node;
 
     /*
      * Constructor.
@@ -52,8 +52,6 @@ struct ClusterTestSuiteFixture
     {
         Ignition::StopAll(true);
     }
-
-    Ignite node;
 };
 
 BOOST_FIXTURE_TEST_SUITE(ClusterTestSuite, ClusterTestSuiteFixture)

http://git-wip-us.apache.org/repos/asf/ignite/blob/d34a4d06/modules/platforms/cpp/core/include/ignite/cache/cache.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/cache.h b/modules/platforms/cpp/core/include/ignite/cache/cache.h
index 00d1c81..33fffc8 100644
--- a/modules/platforms/cpp/core/include/ignite/cache/cache.h
+++ b/modules/platforms/cpp/core/include/ignite/cache/cache.h
@@ -185,6 +185,29 @@ namespace ignite
              *
              * This method should only be used on the valid instance.
              *
+             * @param begin Iterator pointing to the beggining of the key sequence.
+             * @param end Iterator pointing to the end of the key sequence.
+             * @return True if cache contains mapping for all these keys.
+             */
+            template<typename InputIter>
+            bool ContainsKeys(InputIter begin, InputIter end)
+            {
+                IgniteError err;
+
+                impl::InIterOperation<K, V, InputIter> op(begin, end);
+
+                bool res = impl.Get()->ContainsKeys(op, err);
+
+                IgniteError::ThrowIfNeeded(err);
+
+                return res;
+            }
+
+            /**
+             * Check if cache contains mapping for these keys.
+             *
+             * This method should only be used on the valid instance.
+             *
              * @param keys Keys.
              * @param err Error.
              * @return True if cache contains mapping for all these keys.
@@ -337,6 +360,32 @@ namespace ignite
             }
 
             /**
+             * Retrieves values mapped to the specified keys from cache.
+             * If some value is not present in cache, then it will be looked up from swap storage. If
+             * it's not present in swap, or if swap is disabled, and if read-through is allowed, value
+             * will be loaded from persistent store.
+             * This method is transactional and will enlist the entry into ongoing transaction if there is one.
+             *
+             * This method should only be used on the valid instance.
+             *
+             * @param begin Iterator pointing to the beggining of the key sequence.
+             * @param end Iterator pointing to the end of the key sequence.
+             * @param dst Output iterator. Should dereference to std::pair or CacheEntry.
+             */
+            template<typename InIter, typename OutIter>
+            void GetAll(InIter begin, InIter end, OutIter dst)
+            {
+                IgniteError err;
+
+                impl::InIterOperation<K, V, InIter> inOp(begin, end);
+                impl::OutMapIterOperation<K, V, OutIter> outOp(dst);
+
+                impl.Get()->GetAll(inOp, outOp, err);
+
+                IgniteError::ThrowIfNeeded(err);
+            }
+
+            /**
              * Associates the specified value with the specified key in the cache.
              * If the cache previously contained a mapping for the key,
              * the old value is replaced by the specified value.
@@ -409,6 +458,28 @@ namespace ignite
             }
 
             /**
+             * Stores given key-value pairs in cache.
+             * If write-through is enabled, the stored values will be persisted to store.
+             * This method is transactional and will enlist the entry into ongoing transaction if there is one.
+             *
+             * This method should only be used on the valid instance.
+             *
+             * @param begin Iterator pointing to the beggining of the key-value pair sequence.
+             * @param end Iterator pointing to the end of the key-value pair sequence.
+             */
+            template<typename Iter>
+            void PutAll(Iter begin, Iter end)
+            {
+                IgniteError err;
+
+                impl::InIterOperation<K, V, Iter> op(begin, end);
+
+                impl.Get()->PutAll(op, err);
+
+                IgniteError::ThrowIfNeeded(err);
+            }
+
+            /**
              * Associates the specified value with the specified key in this cache,
              * returning an existing value if one existed.
              *
@@ -761,6 +832,29 @@ namespace ignite
             }
 
             /**
+             * Attempts to evict all entries associated with keys.
+             *
+             * @note Entry will be evicted only if it's not used (not
+             * participating in any locks or transactions).
+             *
+             * This method should only be used on the valid instance.
+             *
+             * @param begin Iterator pointing to the beggining of the key sequence.
+             * @param end Iterator pointing to the end of the key sequence.
+             */
+            template<typename Iter>
+            void LocalEvict(Iter begin, Iter end)
+            {
+                IgniteError err;
+
+                impl::InIterOperation<K, V, Iter> op(begin, end);
+
+                impl.Get()->LocalEvict(op, err);
+
+                IgniteError::ThrowIfNeeded(err);
+            }
+
+            /**
              * Clear cache.
              *
              * This method should only be used on the valid instance.
@@ -853,6 +947,27 @@ namespace ignite
             }
 
             /**
+             * Clear entries from the cache and swap storage, without notifying listeners or CacheWriters.
+             * Entry is cleared only if it is not currently locked, and is not participating in a transaction.
+             *
+             * This method should only be used on the valid instance.
+             *
+             * @param begin Iterator pointing to the beggining of the key sequence.
+             * @param end Iterator pointing to the end of the key sequence.
+             */
+            template<typename Iter>
+            void ClearAll(Iter begin, Iter end)
+            {
+                IgniteError err;
+
+                impl::InIterOperation<K, V, Iter> op(begin, end);
+
+                impl.Get()->ClearAll(op, err);
+
+                IgniteError::ThrowIfNeeded(err);
+            }
+
+            /**
              * Clear entry from the cache and swap storage, without notifying listeners or CacheWriters.
              * Entry is cleared only if it is not currently locked, and is not participating in a transaction.
              *
@@ -931,6 +1046,30 @@ namespace ignite
             }
 
             /**
+             * Clear entries from the cache and swap storage, without notifying listeners or CacheWriters.
+             * Entry is cleared only if it is not currently locked, and is not participating in a transaction.
+             *
+             * @note This operation is local as it merely clears entries from local cache, it does not
+             * remove entries from remote caches.
+             *
+             * This method should only be used on the valid instance.
+             *
+             * @param begin Iterator pointing to the beggining of the key sequence.
+             * @param end Iterator pointing to the end of the key sequence.
+             */
+            template<typename Iter>
+            void LocalClearAll(Iter begin, Iter end)
+            {
+                IgniteError err;
+
+                impl::InIterOperation<K, V, Iter> op(begin, end);
+
+                impl.Get()->LocalClearAll(op, err);
+
+                IgniteError::ThrowIfNeeded(err);
+            }
+
+            /**
              * Removes given key mapping from cache. If cache previously contained value for the given key,
              * then this value is returned. In case of PARTITIONED or REPLICATED caches, the value will be
              * loaded from the primary node, which in its turn may load the value from the disk-based swap
@@ -1056,6 +1195,28 @@ namespace ignite
             }
 
             /**
+             * Removes given key mappings from cache.
+             * If write-through is enabled, the value will be removed from store.
+             * This method is transactional and will enlist the entry into ongoing transaction if there is one.
+             *
+             * This method should only be used on the valid instance.
+             *
+             * @param begin Iterator pointing to the beggining of the key sequence.
+             * @param end Iterator pointing to the end of the key sequence.
+             */
+            template<typename Iter>
+            void RemoveAll(Iter begin, Iter end)
+            {
+                IgniteError err;
+
+                impl::InIterOperation<K, V, Iter> op(begin, end);
+
+                impl.Get()->RemoveAll(op, err);
+
+                IgniteError::ThrowIfNeeded(err);
+            }
+
+            /**
              * Removes all mappings from cache.
              * If write-through is enabled, the value will be removed from store.
              * This method is transactional and will enlist the entry into ongoing transaction if there is one.

http://git-wip-us.apache.org/repos/asf/ignite/blob/d34a4d06/modules/platforms/cpp/core/include/ignite/cache/cache_entry.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/cache_entry.h b/modules/platforms/cpp/core/include/ignite/cache/cache_entry.h
index aea5182..c88f918 100644
--- a/modules/platforms/cpp/core/include/ignite/cache/cache_entry.h
+++ b/modules/platforms/cpp/core/include/ignite/cache/cache_entry.h
@@ -23,6 +23,7 @@
 #ifndef _IGNITE_CACHE_CACHE_ENTRY
 #define _IGNITE_CACHE_CACHE_ENTRY
 
+#include <utility>
 #include <ignite/common/common.h>
 
 namespace ignite
@@ -80,6 +81,20 @@ namespace ignite
             }
 
             /**
+             * Constructor.
+             *
+             * @param p Pair.
+             */
+            CacheEntry(const std::pair<K, V>& p) :
+                key(p.first),
+                val(p.second),
+                hasValue(true)
+            {
+                // No-op.
+            }
+
+
+            /**
              * Destructor.
              */
             virtual ~CacheEntry()

http://git-wip-us.apache.org/repos/asf/ignite/blob/d34a4d06/modules/platforms/cpp/core/include/ignite/cache/query/query_cursor.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/cache/query/query_cursor.h b/modules/platforms/cpp/core/include/ignite/cache/query/query_cursor.h
index 61fd7ec..3f7ccce 100644
--- a/modules/platforms/cpp/core/include/ignite/cache/query/query_cursor.h
+++ b/modules/platforms/cpp/core/include/ignite/cache/query/query_cursor.h
@@ -186,7 +186,7 @@ namespace ignite
                  *
                  * This method should only be used on the valid instance.
                  *
-                 * @param Vector where query entries will be stored.
+                 * @param res Vector where query entries will be stored.
                  *
                  * @throw IgniteError class instance in case of failure.
                  */
@@ -205,7 +205,7 @@ namespace ignite
                  *
                  * This method should only be used on the valid instance.
                  * 
-                 * @param Vector where query entries will be stored.
+                 * @param res Vector where query entries will be stored.
                  * @param err Used to set operation result.
                  */
                 void GetAll(std::vector<CacheEntry<K, V> >& res, IgniteError& err)
@@ -223,6 +223,30 @@ namespace ignite
                 }
 
                 /**
+                 * Get all entries.
+                 *
+                 * This method should only be used on the valid instance.
+                 * 
+                 * @param iter Output iterator.
+                 */
+                template<typename OutIter>
+                void GetAll(OutIter iter)
+                {
+                    impl::cache::query::QueryCursorImpl* impl0 = impl.Get();
+
+                    if (impl0) {
+                        impl::OutQueryGetAllOperationIter<K, V, OutIter> outOp(iter);
+
+                        impl0->GetAll(outOp);
+                    }
+                    else
+                    {
+                        throw IgniteError(IgniteError::IGNITE_ERR_GENERIC,
+                            "Instance is not usable (did you check for error?).");
+                    }
+                }
+
+                /**
                  * Check if the instance is valid.
                  *
                  * Invalid instance can be returned if some of the previous

http://git-wip-us.apache.org/repos/asf/ignite/blob/d34a4d06/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_impl.h b/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_impl.h
index 4083c7c..7306805 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_impl.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/cache/query/query_impl.h
@@ -85,6 +85,13 @@ namespace ignite
                      */
                     void GetAll(OutputOperation& op, IgniteError& err);
 
+                    /**
+                     * Get all cursor entries.
+                     *
+                     * @param op Operation.
+                     */
+                    void GetAll(OutputOperation& op);
+
                 private:
                     /** Environment. */
                     ignite::common::concurrent::SharedPointer<impl::IgniteEnvironment> env;

http://git-wip-us.apache.org/repos/asf/ignite/blob/d34a4d06/modules/platforms/cpp/core/include/ignite/impl/helpers.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/helpers.h b/modules/platforms/cpp/core/include/ignite/impl/helpers.h
new file mode 100644
index 0000000..bc9eb39
--- /dev/null
+++ b/modules/platforms/cpp/core/include/ignite/impl/helpers.h
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+#ifndef _IGNITE_IMPL_HELPERS
+#define _IGNITE_IMPL_HELPERS
+
+#include <map>
+
+#include <ignite/cache/cache_entry.h>
+#include <ignite/impl/binary/binary_writer_impl.h>
+
+namespace ignite
+{
+    namespace impl
+    {
+        /**
+         * Class-helper to properly write values of different type.
+         */
+        template<typename K, typename V>
+        struct ContainerEntryWriteHelper
+        {
+            template<typename E>
+            static void Write(binary::BinaryWriterImpl& writer, const E& val)
+            {
+                writer.WriteTopObject(val);
+            }
+
+            static void Write(binary::BinaryWriterImpl& writer, const typename std::map<K, V>::value_type& val)
+            {
+                writer.WriteTopObject(val.first);
+                writer.WriteTopObject(val.second);
+            }
+
+            static void Write(binary::BinaryWriterImpl& writer, const ignite::cache::CacheEntry<K, V>& val)
+            {
+                writer.WriteTopObject(val.GetKey());
+                writer.WriteTopObject(val.GetValue());
+            }
+        };
+    }
+}
+
+#endif //_IGNITE_IMPL_HELPERS

http://git-wip-us.apache.org/repos/asf/ignite/blob/d34a4d06/modules/platforms/cpp/core/include/ignite/impl/operations.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/operations.h b/modules/platforms/cpp/core/include/ignite/impl/operations.h
index fff8a86..1645fb56 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/operations.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/operations.h
@@ -28,6 +28,7 @@
 #include "ignite/impl/binary/binary_reader_impl.h"
 #include "ignite/impl/binary/binary_writer_impl.h"
 #include "ignite/impl/binary/binary_utils.h"
+#include "ignite/impl/helpers.h"
 #include "ignite/binary/binary.h"
 
 namespace ignite
@@ -253,6 +254,50 @@ namespace ignite
         };
 
         /**
+         * Input iterator operation.
+         */
+        template<typename K, typename V, typename Iter>
+        class InIterOperation : public InputOperation
+        {
+        public:
+            /**
+             * Constructor.
+             *
+             * @param begin Iterator pointing to the beggining of the sequence.
+             * @param end Iterator pointing to the end of the key sequence.
+             */
+            InIterOperation(Iter begin, Iter end) :
+                begin(begin),
+                end(end)
+            {
+                // No-op.
+            }
+
+            virtual void ProcessInput(ignite::impl::binary::BinaryWriterImpl& writer)
+            {
+                interop::InteropOutputStream& stream = *writer.GetStream();
+                int32_t sizePos = stream.Reserve(4);
+
+                int32_t size = 0;
+                for (Iter it = begin; it != end; ++it)
+                {
+                    ContainerEntryWriteHelper<K, V>::Write(writer, *it);
+                    ++size;
+                }
+
+                stream.WriteInt32(sizePos, size);
+            }
+        private:
+            /** Sequence begining. */
+            Iter begin;
+
+            /** Sequence end. */
+            Iter end;
+
+            IGNITE_NO_COPY_ASSIGNMENT(InIterOperation)
+        };
+
+        /**
          * Output operation.
          */
         class OutputOperation
@@ -496,7 +541,7 @@ namespace ignite
                         val0[t1] = t2;
                     }
 
-                    val = val0;
+                    std::swap(val, val0);
                 }
             }
 
@@ -508,7 +553,7 @@ namespace ignite
             /**
              * Get value.
              *
-             * @param Value.
+             * @return Value.
              */
             std::map<T1, T2> GetResult()
             {
@@ -540,6 +585,8 @@ namespace ignite
             {
                 int32_t cnt = reader.ReadInt32();
 
+                res.reserve(res.size() + cnt);
+
                 for (int i = 0; i < cnt; i++) 
                 {
                     K key = reader.ReadTopObject<K>();
@@ -560,6 +607,91 @@ namespace ignite
             
             IGNITE_NO_COPY_ASSIGNMENT(OutQueryGetAllOperation)
         };
+
+        /**
+         * Output query GET ALL operation.
+         */
+        template<typename K, typename V, typename Iter, typename Pair = ignite::cache::CacheEntry<K,V> >
+        class OutQueryGetAllOperationIter : public OutputOperation
+        {
+        public:
+            /**
+             * Constructor.
+             */
+            OutQueryGetAllOperationIter(Iter iter) : iter(iter)
+            {
+                // No-op.
+            }
+
+            virtual void ProcessOutput(binary::BinaryReaderImpl& reader)
+            {
+                int32_t cnt = reader.ReadInt32();
+
+                for (int32_t i = 0; i < cnt; i++)
+                {
+                    K key = reader.ReadTopObject<K>();
+                    V val = reader.ReadTopObject<V>();
+
+                    *iter = Pair(key, val);
+                    ++iter;
+                }
+            }
+
+            virtual void SetNull()
+            {
+                // No-op.
+            }
+
+        private:
+            /** Out iter. */
+            Iter iter;
+            
+            IGNITE_NO_COPY_ASSIGNMENT(OutQueryGetAllOperationIter)
+        };
+
+        /**
+         * Output iter operation.
+         */
+        template<typename K, typename V, typename Iter>
+        class OutMapIterOperation :public OutputOperation
+        {
+        public:
+            /**
+             * Constructor.
+             */
+            OutMapIterOperation(Iter iter) : iter(iter)
+            {
+                // No-op.
+            }
+
+            virtual void ProcessOutput(binary::BinaryReaderImpl& reader)
+            {
+                bool exists = reader.GetStream()->ReadBool();
+
+                if (exists)
+                {
+                    int32_t cnt = reader.GetStream()->ReadInt32();
+
+                    for (int32_t i = 0; i < cnt; i++) {
+                        K key = reader.ReadTopObject<K>();
+                        V val = reader.ReadTopObject<V>();
+
+                        *iter = std::pair<K, V>(key, val);
+                        ++iter;
+                    }
+                }
+            }
+
+            virtual void SetNull()
+            {
+                // No-op.
+            }
+        private:
+            /** Out iter. */
+            Iter iter;
+
+            IGNITE_NO_COPY_ASSIGNMENT(OutMapIterOperation)
+        };
     }
 }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/d34a4d06/modules/platforms/cpp/core/project/vs/core.vcxproj
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/project/vs/core.vcxproj b/modules/platforms/cpp/core/project/vs/core.vcxproj
index b5a95bd..5cd49f3 100644
--- a/modules/platforms/cpp/core/project/vs/core.vcxproj
+++ b/modules/platforms/cpp/core/project/vs/core.vcxproj
@@ -225,6 +225,7 @@
     <ClInclude Include="..\..\include\ignite\impl\cache\query\query_fields_row_impl.h" />
     <ClInclude Include="..\..\include\ignite\impl\cache\query\query_impl.h" />
     <ClInclude Include="..\..\include\ignite\impl\cluster\cluster_group_impl.h" />
+    <ClInclude Include="..\..\include\ignite\impl\helpers.h" />
     <ClInclude Include="..\..\include\ignite\impl\ignite_environment.h" />
     <ClInclude Include="..\..\include\ignite\impl\ignite_impl.h" />
     <ClInclude Include="..\..\include\ignite\impl\handle_registry.h" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/d34a4d06/modules/platforms/cpp/core/project/vs/core.vcxproj.filters
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/project/vs/core.vcxproj.filters b/modules/platforms/cpp/core/project/vs/core.vcxproj.filters
index 3b17d53..98099a9 100644
--- a/modules/platforms/cpp/core/project/vs/core.vcxproj.filters
+++ b/modules/platforms/cpp/core/project/vs/core.vcxproj.filters
@@ -207,6 +207,9 @@
     <ClInclude Include="..\..\include\ignite\impl\bindings.h">
       <Filter>Code\impl</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\include\ignite\impl\helpers.h">
+      <Filter>Code\impl</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <Filter Include="Code">

http://git-wip-us.apache.org/repos/asf/ignite/blob/d34a4d06/modules/platforms/cpp/core/src/impl/cache/query/query_impl.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/impl/cache/query/query_impl.cpp b/modules/platforms/cpp/core/src/impl/cache/query/query_impl.cpp
index 018bd99..a7bf0e4 100644
--- a/modules/platforms/cpp/core/src/impl/cache/query/query_impl.cpp
+++ b/modules/platforms/cpp/core/src/impl/cache/query/query_impl.cpp
@@ -186,12 +186,49 @@ namespace ignite
 
                         InteropInputStream in(inMem.Get());
 
-                        binary::BinaryReaderImpl reader(&in);
+                        BinaryReaderImpl reader(&in);
 
                         op.ProcessOutput(reader);
                     }
                 }
 
+                void QueryCursorImpl::GetAll(OutputOperation& op)
+                {
+                    // Check whether any of iterator methods were called.
+                    if (iterCalled)
+                    {
+                        throw IgniteError(IgniteError::IGNITE_ERR_GENERIC,
+                            "Cannot use GetAll() method because an iteration method was called.");
+                    }
+
+                    // Check whether GetAll was called before.
+                    if (getAllCalled)
+                    {
+                        throw IgniteError(IgniteError::IGNITE_ERR_GENERIC,
+                            "Cannot use GetNext() method because GetAll() was called.");
+                    }
+
+                    // Get data.
+                    JniErrorInfo jniErr;
+
+                    SharedPointer<InteropMemory> inMem = env.Get()->AllocateMemory();
+
+                    env.Get()->Context()->TargetOutStream(javaRef, OP_GET_ALL, inMem.Get()->PointerLong(), &jniErr);
+
+                    IgniteError err;
+                    IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
+
+                    IgniteError::ThrowIfNeeded(err);
+
+                    getAllCalled = true;
+
+                    InteropInputStream in(inMem.Get());
+
+                    BinaryReaderImpl reader(&in);
+
+                    op.ProcessOutput(reader);
+                }
+
                 bool QueryCursorImpl::CreateIteratorIfNeeded(IgniteError& err)
                 {
                     if (iterCalled)