ignite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From isap...@apache.org
Subject [1/2] ignite git commit: IGNITE-4617: CPP: Added Field-access methods for BinaryObject
Date Tue, 28 Mar 2017 15:09:45 GMT
Repository: ignite
Updated Branches:
  refs/heads/master 8ae3d5b20 -> d44de994e


http://git-wip-us.apache.org/repos/asf/ignite/blob/d44de994/modules/platforms/cpp/binary/src/impl/binary/binary_type_handler.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/src/impl/binary/binary_type_handler.cpp b/modules/platforms/cpp/binary/src/impl/binary/binary_type_handler.cpp
index 5e70707..3602608 100644
--- a/modules/platforms/cpp/binary/src/impl/binary/binary_type_handler.cpp
+++ b/modules/platforms/cpp/binary/src/impl/binary/binary_type_handler.cpp
@@ -25,54 +25,23 @@ namespace ignite
     {
         namespace binary
         {
-            BinaryTypeHandler::BinaryTypeHandler(SPSnap snap) : snap(snap), fieldIds(NULL), fields(NULL)
+            BinaryTypeHandler::BinaryTypeHandler(SPSnap snap) :
+                origin(snap),
+                updated()
             {
                 // No-op.
             }
-            
-            BinaryTypeHandler::~BinaryTypeHandler()
-            {
-                if (fieldIds)
-                    delete fieldIds;
-
-                if (fields)
-                    delete fields;
-            }
 
             void BinaryTypeHandler::OnFieldWritten(int32_t fieldId, std::string fieldName, int32_t fieldTypeId)
             {
-                if (!snap.Get() || !snap.Get()->ContainsFieldId(fieldId))
+                if (!origin.Get() || !origin.Get()->ContainsFieldId(fieldId))
                 {
-                    if (!HasDifference())
-                    {
-                        fieldIds = new std::set<int32_t>();
-                        fields = new std::map<std::string, int32_t>();
-                    }
+                    if (!updated.Get())
+                        updated = SPSnap(new Snap(*origin.Get()));
 
-                    fieldIds->insert(fieldId);
-                    (*fields)[fieldName] = fieldTypeId;
+                    updated.Get()->AddField(fieldId, fieldName, fieldTypeId);
                 }
             }
-
-            SPSnap BinaryTypeHandler::GetSnapshot()
-            {
-                return snap;
-            }
-
-            bool BinaryTypeHandler::HasDifference()
-            {
-                return fieldIds ? true : false;
-            }
-
-            std::set<int32_t>* BinaryTypeHandler::GetFieldIds()
-            {
-                return fieldIds;
-            }
-
-            std::map<std::string, int32_t>* BinaryTypeHandler::GetFields()
-            {
-                return fields;
-            }
         }
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/d44de994/modules/platforms/cpp/binary/src/impl/binary/binary_type_manager.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/src/impl/binary/binary_type_manager.cpp b/modules/platforms/cpp/binary/src/impl/binary/binary_type_manager.cpp
index 2a7b617..4a8c14c 100644
--- a/modules/platforms/cpp/binary/src/impl/binary/binary_type_manager.cpp
+++ b/modules/platforms/cpp/binary/src/impl/binary/binary_type_manager.cpp
@@ -18,20 +18,23 @@
 #include <ignite/common/concurrent.h>
 
 #include "ignite/impl/binary/binary_type_manager.h"
+#include <algorithm>
 
 using namespace ignite::common::concurrent;
 
 namespace ignite
-{    
+{
     namespace impl
     {
         namespace binary
         {
-            BinaryTypeManager::BinaryTypeManager() : 
-                snapshots(SharedPointer<std::map<int32_t, SPSnap> >(new std::map<int32_t, SPSnap>)),
-                pending(new std::vector<SPSnap>()), 
-                cs(new CriticalSection()), 
-                pendingVer(0), ver(0)
+            BinaryTypeManager::BinaryTypeManager() :
+                snapshots(new std::map<int32_t, SPSnap>),
+                pending(new std::vector<SPSnap>),
+                cs(),
+                updater(0),
+                pendingVer(0),
+                ver(0)
             {
                 // No-op.
             }
@@ -41,156 +44,134 @@ namespace ignite
                 pending->erase(pending->begin(), pending->end());
 
                 delete pending;
-                delete cs;
             }
 
-            SharedPointer<BinaryTypeHandler> BinaryTypeManager::GetHandler(int32_t typeId)
+            SharedPointer<BinaryTypeHandler> BinaryTypeManager::GetHandler(const std::string& typeName, int32_t typeId)
             {
-                SPSnap snapshot = (*snapshots.Get())[typeId];
+                std::map<int32_t, SPSnap>& snapshots0 = *snapshots.Get();
+
+                { // Locking scope.
+                    CsLockGuard guard(cs);
+
+                    std::map<int32_t, SPSnap>::iterator it = snapshots0.find(typeId);
+                    if (it != snapshots0.end())
+                        return SharedPointer<BinaryTypeHandler>(new BinaryTypeHandler(it->second));
+                }
+
+                SPSnap snapshot = SPSnap(new Snap(typeName ,typeId));
 
                 return SharedPointer<BinaryTypeHandler>(new BinaryTypeHandler(snapshot));
             }
 
-            void BinaryTypeManager::SubmitHandler(std::string typeName, int32_t typeId, 
-                BinaryTypeHandler* hnd)
+            void BinaryTypeManager::SubmitHandler(BinaryTypeHandler& hnd)
             {
-                Snap* snap = hnd->GetSnapshot().Get();
-
                 // If this is the very first write of a class or difference exists, 
                 // we need to enqueue it for write.
-                if (!snap || hnd->HasDifference())
+                if (hnd.HasUpdate())
                 {
-                    std::set<int32_t>* newFieldIds = new std::set<int32_t>();
-                    std::map<std::string, int32_t>* newFields = new std::map<std::string, int32_t>();
-                    
-                    CopyFields(snap, newFieldIds, newFields);
-
-                    if (hnd->HasDifference())
-                    {
-                        std::set<int32_t>* diffFieldIds = hnd->GetFieldIds();
-                        std::map<std::string, int32_t>* diffFields = hnd->GetFields();
-
-                        for (std::set<int32_t>::iterator it = diffFieldIds->begin(); it != diffFieldIds->end(); ++it)
-                            newFieldIds->insert(*it);
+                    CsLockGuard guard(cs);
 
-                        for (std::map<std::string, int32_t>::iterator it = diffFields->begin(); it != diffFields->end(); ++it)
-                            (*newFields)[it->first] = it->second;
-                    }
-
-                    Snap* diffSnap = new Snap(typeName, typeId, newFieldIds, newFields);
-
-                    cs->Enter();
-
-                    pending->push_back(SPSnap(diffSnap));
+                    pending->push_back(hnd.GetUpdated());
 
-                    pendingVer++;
-
-                    cs->Leave();
+                    ++pendingVer;
                 }
             }
 
-            int32_t BinaryTypeManager::GetVersion()
+            int32_t BinaryTypeManager::GetVersion() const
             {
                 Memory::Fence();
 
                 return ver;
             }
 
-            bool BinaryTypeManager::IsUpdatedSince(int32_t oldVer)
+            bool BinaryTypeManager::IsUpdatedSince(int32_t oldVer) const
             {
                 Memory::Fence();
 
                 return pendingVer > oldVer;
             }
 
-            bool BinaryTypeManager::ProcessPendingUpdates(BinaryTypeUpdater* updater, IgniteError* err)
+            bool BinaryTypeManager::ProcessPendingUpdates(IgniteError& err)
             {
-                bool success = true; // Optimistically assume that all will be fine.
+                if (!updater)
+                    return false;
 
-                CsLockGuard guard(*cs);
+                CsLockGuard guard(cs);
 
                 for (std::vector<SPSnap>::iterator it = pending->begin(); it != pending->end(); ++it)
                 {
                     Snap* pendingSnap = it->Get();
 
-                    if (updater->Update(pendingSnap, *err))
+                    if (!updater->Update(*pendingSnap, err))
+                        return false; // Stop as we cannot move further.
+
+                    // Perform copy-on-write update of snapshot collection.
+                    SharedPointer< std::map<int32_t, SPSnap> > newSnapshots(new std::map<int32_t, SPSnap>());
+                    std::map<int32_t, SPSnap>& newSnapshots0 = *newSnapshots.Get();
+
+                    bool snapshotFound = false;
+
+                    for (std::map<int32_t, SPSnap>::iterator snapIt = snapshots.Get()->begin();
+                        snapIt != snapshots.Get()->end(); ++snapIt)
                     {
-                        // Perform copy-on-write update of snapshot collection.
-                        std::map<int32_t, SPSnap>* newSnapshots = new std::map<int32_t, SPSnap>();
-                        
-                        bool snapshotFound = false;
+                        int32_t curTypeId = snapIt->first;
+                        Snap* curSnap = snapIt->second.Get();
 
-                        for (std::map<int32_t, SPSnap>::iterator snapIt = snapshots.Get()->begin();
-                            snapIt != snapshots.Get()->end(); ++snapIt)
+                        if (pendingSnap->GetTypeId() != curTypeId)
                         {
-                            int32_t curTypeId = snapIt->first;
-                            Snap* curSnap = snapIt->second.Get();
-
-                            if (pendingSnap->GetTypeId() == curTypeId)
-                            {
-                                // Have to create snapshot with updated fields.
-                                std::set<int32_t>* newFieldIds = new std::set<int32_t>();
-                                std::map<std::string, int32_t>* newFields = new std::map<std::string, int32_t>();
-
-                                // Add old fields.
-                                CopyFields(curSnap, newFieldIds, newFields);
-
-                                // Add new fields.
-                                CopyFields(pendingSnap, newFieldIds, newFields);
-                                
-                                // Create new snapshot.
-                                Snap* newSnap = new Snap(pendingSnap->GetTypeName(), pendingSnap->GetTypeId(), 
-                                    newFieldIds, newFields);
-
-                                (*newSnapshots)[curTypeId] = SPSnap(newSnap);
-
-                                snapshotFound = true;
-                            }
-                            else 
-                                (*newSnapshots)[curTypeId] = snapIt->second; // Just transfer exising snapshot.
+                            // Just transfer exising snapshot.
+                            newSnapshots0[curTypeId] = snapIt->second;
+
+                            continue;
                         }
 
-                        // Handle situation when completely new snapshot is found.
-                        if (!snapshotFound)
-                            (*newSnapshots)[pendingSnap->GetTypeId()] = *it;
+                        // Create new snapshot.
+                        SPSnap newSnap(new Snap(*pendingSnap));
 
-                        snapshots = SharedPointer<std::map<int32_t, SPSnap> >(newSnapshots);
-                    }
-                    else
-                    {
-                        // Stop as we cannot move further.
-                        success = false;
+                        // Add old fields.
+                        newSnap.Get()->CopyFieldsFrom(curSnap);
+
+                        newSnapshots0[curTypeId].Swap(newSnap);
 
-                        break;
+                        snapshotFound = true;
                     }
-                }
 
-                if (success) 
-                {
-                    pending->erase(pending->begin(), pending->end());
+                    // Handle situation when completely new snapshot is found.
+                    if (!snapshotFound)
+                        newSnapshots0[pendingSnap->GetTypeId()] = *it;
 
-                    ver = pendingVer;
+                    snapshots.Swap(newSnapshots);
                 }
 
-                return success;
+                pending->clear();
+
+                ver = pendingVer;
+
+                return true;
             }
 
-            void BinaryTypeManager::CopyFields(Snap* snap, std::set<int32_t>* fieldIds, 
-                std::map<std::string, int32_t>* fields)
+            SPSnap BinaryTypeManager::GetMeta(int32_t typeId)
             {
-                if (snap && snap->HasFields())
-                {
-                    std::set<int32_t>* snapFieldIds = snap->GetFieldIds();
-                    std::map<std::string, int32_t>* snapFields = snap->GetFields();
+                std::map<int32_t, SPSnap>::iterator it = snapshots.Get()->find(typeId);
+
+                if (it != snapshots.Get()->end() && it->second.Get())
+                    return it->second;
 
-                    for (std::set<int32_t>::iterator oldIt = snapFieldIds->begin();
-                        oldIt != snapFieldIds->end(); ++oldIt)
-                        fieldIds->insert(*oldIt);
+                for (int32_t i = 0; i < pending->size(); ++i)
+                {
+                    SPSnap& snap = (*pending)[i];
 
-                    for (std::map<std::string, int32_t>::iterator newFieldsIt = snapFields->begin();
-                        newFieldsIt != snapFields->end(); ++newFieldsIt)
-                        (*fields)[newFieldsIt->first] = newFieldsIt->second;
+                    if (snap.Get()->GetTypeId() == typeId)
+                        return snap;
                 }
+
+                IgniteError err;
+
+                SPSnap snap = updater->GetMeta(typeId, err);
+
+                IgniteError::ThrowIfNeeded(err);
+
+                return snap;
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/d44de994/modules/platforms/cpp/binary/src/impl/binary/binary_type_snapshot.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/src/impl/binary/binary_type_snapshot.cpp b/modules/platforms/cpp/binary/src/impl/binary/binary_type_snapshot.cpp
index f34732f..05962b1 100644
--- a/modules/platforms/cpp/binary/src/impl/binary/binary_type_snapshot.cpp
+++ b/modules/platforms/cpp/binary/src/impl/binary/binary_type_snapshot.cpp
@@ -23,47 +23,37 @@ namespace ignite
     {
         namespace binary
         {
-            BinaryTypeSnapshot::BinaryTypeSnapshot(std::string typeName, int32_t typeId, 
-                std::set<int32_t>* fieldIds, std::map<std::string, int32_t>* fields) : 
-                typeName(typeName), typeId(typeId), fieldIds(fieldIds), fields(fields)
+            BinaryTypeSnapshot::BinaryTypeSnapshot(std::string typeName, int32_t typeId) :
+                typeName(typeName),
+                typeId(typeId),
+                fieldIds(),
+                fields()
             {
                 // No-op.
             }
 
-            BinaryTypeSnapshot::~BinaryTypeSnapshot()
+            BinaryTypeSnapshot::BinaryTypeSnapshot(const BinaryTypeSnapshot& another) :
+                typeName(another.typeName),
+                typeId(another.typeId),
+                fieldIds(another.fieldIds),
+                fields(another.fields)
             {
-                delete fieldIds;
-                delete fields;
-            }
-
-            bool BinaryTypeSnapshot::ContainsFieldId(int32_t fieldId)
-            {
-                return fieldIds && fieldIds->count(fieldId) == 1;
-            }
-
-            std::string BinaryTypeSnapshot::GetTypeName()
-            {
-                return typeName;
-            }
-
-            int32_t BinaryTypeSnapshot::GetTypeId()
-            {
-                return typeId;
-            }
-
-            bool BinaryTypeSnapshot::HasFields()
-            {
-                return !fieldIds->empty();
+                // No-op.
             }
 
-            std::set<int32_t>* BinaryTypeSnapshot::GetFieldIds()
+            void BinaryTypeSnapshot::AddField(int32_t fieldId, const std::string& fieldName, int32_t fieldTypeId)
             {
-                return fieldIds;
+                fieldIds.insert(fieldId);
+                fields[fieldName] = BinaryFieldMeta(fieldTypeId, fieldId);
             }
 
-            std::map<std::string, int32_t>* BinaryTypeSnapshot::GetFields()
+            void BinaryTypeSnapshot::CopyFieldsFrom(const BinaryTypeSnapshot* another)
             {
-                return fields;
+                if (another && another->HasFields())
+                {
+                    fieldIds.insert(another->fieldIds.begin(), another->fieldIds.end());
+                    fields.insert(another->fields.begin(), another->fields.end());
+                }
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/d44de994/modules/platforms/cpp/binary/src/impl/binary/binary_type_updater.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/binary/src/impl/binary/binary_type_updater.cpp b/modules/platforms/cpp/binary/src/impl/binary/binary_type_updater.cpp
deleted file mode 100644
index b3436e9..0000000
--- a/modules/platforms/cpp/binary/src/impl/binary/binary_type_updater.cpp
+++ /dev/null
@@ -1,32 +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.
- */
-
-#include "ignite/impl/binary/binary_type_updater.h"
-
-namespace ignite
-{    
-    namespace impl
-    {
-        namespace binary
-        {
-            BinaryTypeUpdater::~BinaryTypeUpdater()
-            {
-                // No-op.
-            }
-        }
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/d44de994/modules/platforms/cpp/core-test/config/cache-identity.xml
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/config/cache-identity.xml b/modules/platforms/cpp/core-test/config/cache-identity.xml
index ace9f6a..c4e0b1b 100644
--- a/modules/platforms/cpp/core-test/config/cache-identity.xml
+++ b/modules/platforms/cpp/core-test/config/cache-identity.xml
@@ -99,6 +99,39 @@
                         </list>
                     </property>
                 </bean>
+
+                <bean class="org.apache.ignite.configuration.CacheConfiguration">
+                    <property name="name" value="cache3"/>
+                    <property name="cacheMode" value="PARTITIONED"/>
+                    <property name="atomicityMode" value="TRANSACTIONAL"/>
+                    <property name="writeSynchronizationMode" value="FULL_SYNC"/>
+
+                    <!-- Configure type metadata to enable queries. -->
+                    <property name="queryEntities">
+                        <list>
+                            <bean class="org.apache.ignite.cache.QueryEntity">
+                                <property name="keyType" value="ComplexType2"/>
+                                <property name="valueType" value="java.lang.Integer"/>
+
+                                <property name="fields">
+                                    <map>
+                                        <entry key="i32Field" value="java.lang.Integer"/>
+                                        <entry key="objField" value="InnerObject"/>
+                                        <entry key="strField" value="java.lang.String"/>
+                                    </map>
+                                </property>
+
+                                <property name="keyFields">
+                                    <list>
+                                        <value>i32Field</value>
+                                        <value>objField</value>
+                                        <value>strField</value>
+                                    </list>
+                                </property>
+                            </bean>
+                        </list>
+                    </property>
+                </bean>
             </list>
         </property>
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/d44de994/modules/platforms/cpp/core-test/include/ignite/binary_test_defs.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/include/ignite/binary_test_defs.h b/modules/platforms/cpp/core-test/include/ignite/binary_test_defs.h
index 2965797..196c6d3 100644
--- a/modules/platforms/cpp/core-test/include/ignite/binary_test_defs.h
+++ b/modules/platforms/cpp/core-test/include/ignite/binary_test_defs.h
@@ -122,6 +122,11 @@ namespace ignite_test
                 {
                     return 0;
                 }
+
+                virtual BinaryIdResolver* Clone() const
+                {
+                    return new DummyIdResolver();
+                }
             };
         }
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/d44de994/modules/platforms/cpp/core-test/src/binary_identity_resolver_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/binary_identity_resolver_test.cpp b/modules/platforms/cpp/core-test/src/binary_identity_resolver_test.cpp
index 9a06c3c..55b77bd 100644
--- a/modules/platforms/cpp/core-test/src/binary_identity_resolver_test.cpp
+++ b/modules/platforms/cpp/core-test/src/binary_identity_resolver_test.cpp
@@ -33,6 +33,7 @@
 #include "ignite/binary/binary_array_identity_resolver.h"
 
 #include "ignite/test_utils.h"
+#include "ignite/complex_type.h"
 
 
 using namespace boost::unit_test;
@@ -137,6 +138,8 @@ struct GetHashDefined : TestUserClassBase {};
 struct ResolverDefined : TestUserClassBase {};
 struct BothDefined : TestUserClassBase {};
 
+struct ComplexType2 : ComplexType { };
+
 struct CustomIdResolver : binary::BinaryIdentityResolver
 {
     int32_t GetHashCode(const BinaryObject& obj)
@@ -159,6 +162,29 @@ struct CustomIdResolver : binary::BinaryIdentityResolver
     }
 };
 
+struct CustomFieldIdResolver : binary::BinaryIdentityResolver
+{
+    static int32_t lastHash;
+
+    int32_t GetHashCode(const BinaryObject& obj)
+    {
+        int32_t hash = 0;
+
+        if (obj.HasField("objField"))
+        {
+            BinaryObject inner = obj.GetField<BinaryObject>("objField");
+
+            hash = inner.GetField<int32_t>("f1");
+        }
+
+        lastHash = hash;
+
+        return hash;
+    }
+};
+
+int32_t CustomFieldIdResolver::lastHash = 0;
+
 namespace ignite
 {
     namespace binary
@@ -312,7 +338,7 @@ namespace ignite
         };
 
         /**
-         * Binary type definition for CompositeKey.
+         * Binary type definition for CompositeKeySimple.
          */
         template<>
         struct BinaryType<CompositeKeySimple>
@@ -341,6 +367,42 @@ namespace ignite
                 return val;
             }
         };
+
+        /**
+         * Binary type definition for ComplexType2.
+         */
+        template<>
+        struct BinaryType<ComplexType2>
+        {
+            IGNITE_BINARY_GET_TYPE_ID_AS_HASH(ComplexType2)
+            IGNITE_BINARY_GET_TYPE_NAME_AS_IS(ComplexType2)
+            IGNITE_BINARY_GET_FIELD_ID_AS_HASH
+            IGNITE_BINARY_IS_NULL_FALSE(ComplexType2)
+            IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(ComplexType2)
+
+            ignite::Reference<ignite::binary::BinaryIdentityResolver> GetIdentityResolver()
+            {
+                return ignite::MakeReferenceFromCopy(CustomFieldIdResolver());
+            }
+
+            void Write(BinaryWriter& writer, ComplexType2 obj)
+            {
+                writer.WriteInt32("i32Field", obj.i32Field);
+                writer.WriteObject("objField", obj.objField);
+                writer.WriteString("strField", obj.strField);
+            }
+
+            ComplexType2 Read(BinaryReader& reader)
+            {
+                ComplexType2 obj;
+
+                obj.i32Field = reader.ReadInt32("i32Field");
+                obj.objField = reader.ReadObject<InnerObject>("objField");
+                obj.strField = reader.ReadString("strField");
+
+                return obj;
+            }
+        };
     }
 }
 
@@ -384,7 +446,7 @@ int32_t CalculateHashCode(const T& value)
 
     FillMem<T>(mem, value);
 
-    BinaryObject obj(mem, 0);
+    BinaryObject obj(mem, 0, 0, 0);
 
     R resolver;
 
@@ -398,7 +460,7 @@ int32_t RetrieveHashCode(const T& value)
 
     FillMem<T>(mem, value);
 
-    BinaryObjectImpl obj(mem, 0);
+    BinaryObjectImpl obj(mem, 0, 0, 0);
 
     return obj.GetHashCode();
 }
@@ -519,4 +581,27 @@ BOOST_AUTO_TEST_CASE(TestBothDefined)
     BOOST_CHECK_EQUAL(RetrieveHashCode(val), val.field * 42);
 }
 
+BOOST_AUTO_TEST_CASE(ComplexTypeWithFieldsIdentityResolver)
+{
+    BOOST_CHECKPOINT("Node startup");
+    Ignite node = ignite_test::StartNode("cache-identity.xml");
+
+    ComplexType2 key;
+
+    key.strField = "ComplexType2";
+    key.i32Field = 58943095;
+    key.objField.f1 = 812;
+    key.objField.f2 = "InnerType";
+
+    int32_t value = -12345890;
+
+    BOOST_CHECKPOINT("Cache creation");
+    Cache<ComplexType2, int32_t> cache = node.GetOrCreateCache<ComplexType2, int32_t>("cache3");
+
+    BOOST_CHECKPOINT("Value Put");
+    cache.Put(key, value);
+
+    BOOST_CHECK_EQUAL(key.objField.f1, CustomFieldIdResolver::lastHash);
+}
+
 BOOST_AUTO_TEST_SUITE_END()

http://git-wip-us.apache.org/repos/asf/ignite/blob/d44de994/modules/platforms/cpp/core-test/src/binary_object_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/binary_object_test.cpp b/modules/platforms/cpp/core-test/src/binary_object_test.cpp
index 6378266..bc30428 100644
--- a/modules/platforms/cpp/core-test/src/binary_object_test.cpp
+++ b/modules/platforms/cpp/core-test/src/binary_object_test.cpp
@@ -21,6 +21,7 @@
 
 #include <boost/test/unit_test.hpp>
 
+#include <ignite/common/utils.h>
 #include <ignite/common/fixed_size_array.h>
 #include <ignite/binary/binary_object.h>
 #include <ignite/binary/binary_writer.h>
@@ -28,6 +29,7 @@
 #include "ignite/binary_test_defs.h"
 #include "ignite/test_type.h"
 #include "ignite/complex_type.h"
+#include "ignite/test_utils.h"
 
 using namespace ignite;
 using namespace ignite::binary;
@@ -53,7 +55,7 @@ void CheckSimple(const T& value)
 
     FillMem<T>(mem, value);
 
-    BinaryObject obj(BinaryObjectImpl::FromMemory(mem, 0));
+    BinaryObject obj(BinaryObjectImpl::FromMemory(mem, 0, 0));
 
     T actual = obj.Deserialize<T>();
 
@@ -67,7 +69,7 @@ void CheckSimpleNP(const T& value)
 
     FillMem<T>(mem, value);
 
-    BinaryObject obj(BinaryObjectImpl::FromMemory(mem, 0));
+    BinaryObject obj(BinaryObjectImpl::FromMemory(mem, 0, 0));
 
     T actual = obj.Deserialize<T>();
 
@@ -100,7 +102,7 @@ void CheckData(const T& obj)
     InteropUnpooledMemory mem(1024);
     FillMem<T>(mem, obj);
 
-    BinaryObjectImpl binObj(BinaryObjectImpl::FromMemory(mem, 0));
+    BinaryObjectImpl binObj(BinaryObjectImpl::FromMemory(mem, 0, 0));
 
     BOOST_REQUIRE_EQUAL(binObj.GetLength(), objData.GetSize());
 
@@ -110,6 +112,50 @@ void CheckData(const T& obj)
         BOOST_CHECK_EQUAL(objData[i], binObjData[i]);
 }
 
+template<typename F, typename T>
+void CheckField(const T& obj, const char* field, const F& expected)
+{
+    InteropUnpooledMemory mem(1024);
+    FillMem<T>(mem, obj);
+
+    TemplatedBinaryIdResolver<T> resolver;
+    BinaryObject binObj(mem, 0, &resolver, 0);
+
+    BOOST_REQUIRE(binObj.HasField(field));
+
+    F actual = binObj.GetField<F>(field);
+
+    BOOST_CHECK_EQUAL(actual, expected);
+}
+
+template<typename F, typename T>
+void CheckFieldNP(const T& obj, const char* field, const F& expected)
+{
+    InteropUnpooledMemory mem(1024);
+    FillMem<T>(mem, obj);
+
+    TemplatedBinaryIdResolver<T> resolver;
+    BinaryObject binObj(mem, 0, &resolver, 0);
+
+    BOOST_REQUIRE(binObj.HasField(field));
+
+    F actual = binObj.GetField<F>(field);
+
+    BOOST_CHECK(actual == expected);
+}
+
+template<typename T>
+void CheckNoField(const T& obj, const char* field)
+{
+    InteropUnpooledMemory mem(1024);
+    FillMem<T>(mem, obj);
+
+    TemplatedBinaryIdResolver<T> resolver;
+    BinaryObject binObj(mem, 0, &resolver, 0);
+
+    BOOST_REQUIRE(!binObj.HasField(field));
+}
+
 BOOST_AUTO_TEST_SUITE(BinaryObjectTestSuite)
 
 BOOST_AUTO_TEST_CASE(UserTestType)
@@ -173,4 +219,172 @@ BOOST_AUTO_TEST_CASE(UserBinaryFieldsGetData)
     CheckData(BinaryFields(423425, 961851, 18946, 180269165));
 }
 
+BOOST_AUTO_TEST_CASE(UserBinaryFieldsGetField)
+{
+    BinaryFields dflt;
+
+    CheckField<int32_t>(dflt, "val1", dflt.val1);
+    CheckField<int32_t>(dflt, "val2", dflt.val2);
+
+    CheckNoField(dflt, "rawVal1");
+    CheckNoField(dflt, "rawVal2");
+    CheckNoField(dflt, "some");
+    CheckNoField(dflt, "unknown");
+    CheckNoField(dflt, "");
+
+    BinaryFields some(423425, 961851, 18946, 180269165);
+
+    CheckField<int32_t>(some, "val1", some.val1);
+    CheckField<int32_t>(some, "val2", some.val2);
+
+    CheckNoField(some, "rawVal1");
+    CheckNoField(some, "rawVal2");
+    CheckNoField(some, "some");
+    CheckNoField(some, "unknown");
+    CheckNoField(some, "");
+}
+
+BOOST_AUTO_TEST_CASE(UserTestTypeGetField)
+{
+    TestType dflt;
+
+    CheckField<int8_t>(dflt, "i8Field", dflt.i8Field);
+    CheckField<int16_t>(dflt, "i16Field", dflt.i16Field);
+    CheckField<int32_t>(dflt, "i32Field", dflt.i32Field);
+    CheckField<int64_t>(dflt, "i64Field", dflt.i64Field);
+    CheckField<std::string>(dflt, "strField", dflt.strField);
+    CheckField<float>(dflt, "floatField", dflt.floatField);
+    CheckField<double>(dflt, "doubleField", dflt.doubleField);
+    CheckField<bool>(dflt, "boolField", dflt.boolField);
+    CheckField<Guid>(dflt, "guidField", dflt.guidField);
+    CheckFieldNP<Date>(dflt, "dateField", dflt.dateField);
+    CheckFieldNP<Time>(dflt, "timeField", dflt.timeField);
+    CheckFieldNP<Timestamp>(dflt, "timestampField", dflt.timestampField);
+
+    CheckNoField(dflt, "some");
+    CheckNoField(dflt, "unknown");
+    CheckNoField(dflt, "");
+
+    TestType some(31, 2314, 54363467, -534180269165, "Lorem ipsum", 45364.46462f, 0.0750732, true,
+        Guid(8934658962, 56784598325), common::MakeDateGmt(1997, 3, 21), common::MakeTimeGmt(23, 50, 11),
+        common::MakeTimestampGmt(2002, 4, 12, 14, 36, 29, 438576348));
+
+    CheckField<int8_t>(some, "i8Field", some.i8Field);
+    CheckField<int16_t>(some, "i16Field", some.i16Field);
+    CheckField<int32_t>(some, "i32Field", some.i32Field);
+    CheckField<int64_t>(some, "i64Field", some.i64Field);
+    CheckField<std::string>(some, "strField", some.strField);
+    CheckField<float>(some, "floatField", some.floatField);
+    CheckField<double>(some, "doubleField", some.doubleField);
+    CheckField<bool>(some, "boolField", some.boolField);
+    CheckField<Guid>(some, "guidField", some.guidField);
+    CheckFieldNP<Date>(some, "dateField", some.dateField);
+    CheckFieldNP<Time>(some, "timeField", some.timeField);
+    CheckFieldNP<Timestamp>(some, "timestampField", some.timestampField);
+
+    CheckNoField(some, "some");
+    CheckNoField(some, "unknown");
+    CheckNoField(some, "");
+}
+
+BOOST_AUTO_TEST_CASE(UserBinaryOuterGetField)
+{
+    BinaryOuter some(1895298, 592856);
+
+    InteropUnpooledMemory mem(1024);
+    FillMem(mem, some);
+
+    TemplatedBinaryIdResolver<BinaryOuter> resolver;
+    BinaryObject binObj(mem, 0, &resolver, 0);
+
+    BOOST_REQUIRE(binObj.HasField("val"));
+    BOOST_REQUIRE(binObj.HasField("inner"));
+
+    int32_t outer = binObj.GetField<int32_t>("val");
+    BinaryObject inner = binObj.GetField<BinaryObject>("inner");
+
+    BOOST_CHECK_EQUAL(outer, some.GetValue());
+}
+
+BOOST_AUTO_TEST_CASE(ExceptionSafety)
+{
+    BinaryFields some(43956293, 567894632, 253945, 107576622);
+
+    InteropUnpooledMemory mem(1024);
+    FillMem(mem, some);
+
+    TemplatedBinaryIdResolver<BinaryOuter> resolver;
+    BinaryObject binObj(mem, 0, &resolver, 0);
+
+    BOOST_CHECK_THROW(binObj.Deserialize<TestType>(), IgniteError);
+
+    BinaryFields restored = binObj.Deserialize<BinaryFields>();
+
+    BOOST_CHECK(restored == some);
+}
+
+BOOST_AUTO_TEST_CASE(RemoteSchemaRetrieval)
+{
+    try
+    {
+        BOOST_CHECKPOINT("Node1 startup");
+        Ignite node1 = ignite_test::StartNode("cache-test.xml", "node1");
+
+        BOOST_CHECKPOINT("Creating cache");
+        cache::Cache<int32_t, BinaryFields> cache = node1.GetOrCreateCache<int32_t, BinaryFields>("cache");
+
+        BinaryFields some(25675472, 67461, 457542, 87073456);
+
+        BOOST_CHECKPOINT("Putting value");
+        cache.Put(42, some);
+
+        BOOST_CHECKPOINT("Node2 startup");
+        Ignite node2 = ignite_test::StartNode("cache-test.xml", "node2");
+
+        impl::IgniteImpl* nodeImpl = impl::IgniteImpl::GetFromProxy(node2);
+        impl::IgniteEnvironment* env = nodeImpl->GetEnvironment();
+
+        InteropUnpooledMemory mem(1024);
+        FillMem<BinaryFields>(mem, some);
+
+        BOOST_CHECKPOINT("Creating BinaryObject");
+        BinaryObject binObj(mem, 0, 0, env->GetTypeManager());
+
+        BOOST_CHECK(binObj.HasField("val1"));
+        BOOST_CHECK(binObj.HasField("val2"));
+
+        int32_t val1 = binObj.GetField<int32_t>("val1");
+        int32_t val2 = binObj.GetField<int32_t>("val2");
+
+        BOOST_CHECK_EQUAL(val1, some.val1);
+        BOOST_CHECK_EQUAL(val2, some.val2);
+
+        BOOST_CHECK(!binObj.HasField("rawVal1"));
+        BOOST_CHECK(!binObj.HasField("rawVal2"));
+        BOOST_CHECK(!binObj.HasField("some"));
+        BOOST_CHECK(!binObj.HasField("unknown"));
+        BOOST_CHECK(!binObj.HasField("some_really_long_and_FancyName32047_20567934065286584067325693462"));
+    }
+    catch (...)
+    {
+        Ignition::StopAll(true);
+        throw;
+    }
+
+    Ignition::StopAll(true);
+}
+
+BOOST_AUTO_TEST_CASE(GetEnumValueInvalid)
+{
+    BinaryFields some(43956293, 567894632, 253945, 107576622);
+
+    InteropUnpooledMemory mem(1024);
+    FillMem(mem, some);
+
+    TemplatedBinaryIdResolver<BinaryOuter> resolver;
+    BinaryObjectImpl binObj(mem, 0, &resolver, 0);
+
+    BOOST_CHECK_THROW(binObj.GetEnumValue(), IgniteError);
+}
+
 BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/d44de994/modules/platforms/cpp/core-test/src/cache_invoke_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/cache_invoke_test.cpp b/modules/platforms/cpp/core-test/src/cache_invoke_test.cpp
index 1b548a6..db304e2 100644
--- a/modules/platforms/cpp/core-test/src/cache_invoke_test.cpp
+++ b/modules/platforms/cpp/core-test/src/cache_invoke_test.cpp
@@ -33,6 +33,8 @@
 #include "ignite/ignite_binding_context.h"
 #include "ignite/cache/cache_entry_processor.h"
 
+#include "ignite/test_utils.h"
+
 using namespace boost::unit_test;
 
 using namespace ignite;

http://git-wip-us.apache.org/repos/asf/ignite/blob/d44de994/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 8dfd39d..7b206d2 100644
--- a/modules/platforms/cpp/core-test/src/cluster_test.cpp
+++ b/modules/platforms/cpp/core-test/src/cluster_test.cpp
@@ -32,7 +32,10 @@ using namespace boost::unit_test;
 /*
  * Test setup fixture.
  */
-struct ClusterTestSuiteFixture {
+struct ClusterTestSuiteFixture
+{
+    Ignite grid;
+
     /*
      * Constructor.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/d44de994/modules/platforms/cpp/core/include/ignite/impl/binary/binary_type_updater_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/binary/binary_type_updater_impl.h b/modules/platforms/cpp/core/include/ignite/impl/binary/binary_type_updater_impl.h
index 02ecd06..11d0aba 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/binary/binary_type_updater_impl.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/binary/binary_type_updater_impl.h
@@ -18,8 +18,6 @@
 #ifndef _IGNITE_IMPL_BINARY_BINARY_TYPE_UPDATER_IMPL
 #define _IGNITE_IMPL_BINARY_BINARY_TYPE_UPDATER_IMPL
 
-#include <ignite/jni/exports.h>
-
 #include "ignite/impl/ignite_environment.h"
 #include "ignite/impl/binary/binary_type_updater.h"
 
@@ -48,7 +46,9 @@ namespace ignite
                  */
                 ~BinaryTypeUpdaterImpl();
 
-                bool Update(Snap* snapshot, IgniteError& err);
+                virtual bool Update(const Snap& snap, IgniteError& err);
+
+                virtual SPSnap GetMeta(int32_t typeId, IgniteError& err);
             private:
                 /** Environment. */
                 IgniteEnvironment& env;

http://git-wip-us.apache.org/repos/asf/ignite/blob/d44de994/modules/platforms/cpp/core/include/ignite/impl/ignite_impl.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/ignite_impl.h b/modules/platforms/cpp/core/include/ignite/impl/ignite_impl.h
index 776678d..24fc989 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/ignite_impl.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/ignite_impl.h
@@ -170,6 +170,17 @@ namespace ignite
             }
 
             /**
+             * Get environment.
+             * Internal method. Should not be used by user.
+             *
+             * @return Environment pointer.
+             */
+            IgniteEnvironment* GetEnvironment()
+            {
+                return env.Get();
+            }
+
+            /**
              * Get transactions.
              *
              * @return TransactionsImpl instance.

http://git-wip-us.apache.org/repos/asf/ignite/blob/d44de994/modules/platforms/cpp/core/include/ignite/impl/interop/interop_target.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/include/ignite/impl/interop/interop_target.h b/modules/platforms/cpp/core/include/ignite/impl/interop/interop_target.h
index 5ce8cfa..0d32561 100644
--- a/modules/platforms/cpp/core/include/ignite/impl/interop/interop_target.h
+++ b/modules/platforms/cpp/core/include/ignite/impl/interop/interop_target.h
@@ -65,7 +65,7 @@ namespace ignite
                  * Internal out operation.
                  *
                  * @param opType Operation type.
-                 * @param inOp Input.
+                 * @param outOp Input.
                  * @param err Error.
                  * @return Result.
                  */

http://git-wip-us.apache.org/repos/asf/ignite/blob/d44de994/modules/platforms/cpp/core/src/impl/binary/binary_type_updater_impl.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/impl/binary/binary_type_updater_impl.cpp b/modules/platforms/cpp/core/src/impl/binary/binary_type_updater_impl.cpp
index 42d6fd0..73c96fd 100644
--- a/modules/platforms/cpp/core/src/impl/binary/binary_type_updater_impl.cpp
+++ b/modules/platforms/cpp/core/src/impl/binary/binary_type_updater_impl.cpp
@@ -15,10 +15,13 @@
  * limitations under the License.
  */
 
+#include <iterator>
+
 #include "ignite/impl/binary/binary_type_updater_impl.h"
 #include "ignite/impl/interop/interop_output_stream.h"
 #include "ignite/impl/binary/binary_writer_impl.h"
-#include "ignite/binary/binary_raw_writer.h"
+#include "ignite/binary/binary_writer.h"
+#include "ignite/binary/binary_reader.h"
 
 using namespace ignite::common::concurrent;
 using namespace ignite::jni::java;
@@ -33,8 +36,14 @@ namespace ignite
     {
         namespace binary
         {
-            /** Operation: metadata update. */
-            const int32_t OP_PUT_META = 3;
+            enum Operation
+            {
+                /** Operation: metadata get. */
+                OP_GET_META = 1,
+
+                /** Operation: metadata update. */
+                OP_PUT_META = 3
+            };
 
             BinaryTypeUpdaterImpl::BinaryTypeUpdaterImpl(IgniteEnvironment& env, jobject javaRef) :
                 env(env),
@@ -48,33 +57,35 @@ namespace ignite
                 JniContext::Release(javaRef);
             }
 
-            bool BinaryTypeUpdaterImpl::Update(Snap* snap, IgniteError& err)
+            bool BinaryTypeUpdaterImpl::Update(const Snap& snap, IgniteError& err)
             {
                 JniErrorInfo jniErr;
 
                 SharedPointer<InteropMemory> mem = env.AllocateMemory();
 
                 InteropOutputStream out(mem.Get());
-                BinaryWriterImpl writer(&out, NULL);
+                BinaryWriterImpl writer(&out, 0);
                 BinaryRawWriter rawWriter(&writer);
 
                 // We always pass only one meta at a time in current implementation for simplicity.
                 rawWriter.WriteInt32(1);
 
-                rawWriter.WriteInt32(snap->GetTypeId());
-                rawWriter.WriteString(snap->GetTypeName());
-                rawWriter.WriteString(NULL); // Affinity key is not supported for now.
+                rawWriter.WriteInt32(snap.GetTypeId());
+                rawWriter.WriteString(snap.GetTypeName());
+                rawWriter.WriteString(0); // Affinity key is not supported for now.
                 
-                if (snap->HasFields())
+                if (snap.HasFields())
                 {
-                    std::map<std::string, int32_t>* fields = snap->GetFields();
+                    const Snap::FieldMap& fields = snap.GetFieldMap();
 
-                    rawWriter.WriteInt32(static_cast<int32_t>(fields->size()));
+                    rawWriter.WriteInt32(static_cast<int32_t>(fields.size()));
 
-                    for (std::map<std::string, int32_t>::iterator it = fields->begin(); it != fields->end(); ++it)
+                    for (Snap::FieldMap::const_iterator it = fields.begin(); it != fields.end(); ++it)
                     {
+                        const BinaryFieldMeta& fieldMeta = it->second;
+
                         rawWriter.WriteString(it->first);
-                        rawWriter.WriteInt32(it->second);
+                        fieldMeta.Write(rawWriter);
                     }
                 }
                 else
@@ -90,10 +101,66 @@ namespace ignite
 
                 IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
 
-                if (jniErr.code == IGNITE_JNI_ERR_SUCCESS)
-                    return res == 1;
-                else
-                    return false;
+                return jniErr.code == IGNITE_JNI_ERR_SUCCESS && res == 1;
+            }
+
+            SPSnap BinaryTypeUpdaterImpl::GetMeta(int32_t typeId, IgniteError& err)
+            {
+                JniErrorInfo jniErr;
+
+                SharedPointer<InteropMemory> outMem = env.AllocateMemory();
+                SharedPointer<InteropMemory> inMem = env.AllocateMemory();
+
+                InteropOutputStream out(outMem.Get());
+                BinaryWriterImpl writer(&out, 0);
+
+                writer.WriteInt32(typeId);
+
+                out.Synchronize();
+
+                env.Context()->TargetInStreamOutStream(javaRef, OP_GET_META,
+                    outMem.Get()->PointerLong(), inMem.Get()->PointerLong(), &jniErr);
+
+                IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err);
+
+                if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
+                    return SPSnap();
+
+                InteropInputStream in(inMem.Get());
+                BinaryReaderImpl reader(&in);
+                BinaryRawReader rawReader(&reader);
+
+                bool found = rawReader.ReadBool();
+
+                if (!found)
+                    return SPSnap();
+
+                int32_t readTypeId = rawReader.ReadInt32();
+
+                assert(typeId == readTypeId);
+
+                std::string typeName = rawReader.ReadString();
+
+                SPSnap res(new Snap(typeName, readTypeId));
+
+                // Skipping affinity key field name.
+                rawReader.ReadString();
+                
+                int32_t fieldsNum = rawReader.ReadInt32();
+
+                for (int32_t i = 0; i < fieldsNum; ++i)
+                {
+                    std::string fieldName = rawReader.ReadString();
+                    BinaryFieldMeta fieldMeta;
+                    fieldMeta.Read(rawReader);
+
+                    res.Get()->AddField(fieldMeta.GetFieldId(), fieldName, fieldMeta.GetTypeId());
+                }
+
+                // Skipping isEnum info.
+                rawReader.ReadBool();
+
+                return res;
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/d44de994/modules/platforms/cpp/core/src/impl/ignite_environment.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/impl/ignite_environment.cpp b/modules/platforms/cpp/core/src/impl/ignite_environment.cpp
index 1a1c80f..b37fa8f 100644
--- a/modules/platforms/cpp/core/src/impl/ignite_environment.cpp
+++ b/modules/platforms/cpp/core/src/impl/ignite_environment.cpp
@@ -198,6 +198,8 @@ namespace ignite
             jobject binaryProc = Context()->ProcessorBinaryProcessor(proc.Get());
             metaUpdater = new BinaryTypeUpdaterImpl(*this, binaryProc);
 
+            metaMgr->SetUpdater(metaUpdater);
+
             common::dynamic::Module currentModule = common::dynamic::GetCurrent();
             moduleMgr.Get()->RegisterModule(currentModule);
         }
@@ -335,7 +337,7 @@ namespace ignite
             if (local)
                 throw IgniteError(IgniteError::IGNITE_ERR_UNSUPPORTED_OPERATION, "Local invokation is not supported.");
 
-            BinaryObjectImpl binProcHolder = BinaryObjectImpl::FromMemory(*mem.Get(), inStream.Position());
+            BinaryObjectImpl binProcHolder = BinaryObjectImpl::FromMemory(*mem.Get(), inStream.Position(), 0);
             BinaryObjectImpl binProc = binProcHolder.GetField(0);
 
             int64_t procId = binProc.GetTypeId();

http://git-wip-us.apache.org/repos/asf/ignite/blob/d44de994/modules/platforms/cpp/core/src/impl/interop/interop_target.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core/src/impl/interop/interop_target.cpp b/modules/platforms/cpp/core/src/impl/interop/interop_target.cpp
index 1c7bb82..3904dfa 100644
--- a/modules/platforms/cpp/core/src/impl/interop/interop_target.cpp
+++ b/modules/platforms/cpp/core/src/impl/interop/interop_target.cpp
@@ -57,7 +57,7 @@ namespace ignite
 
                 if (metaMgr->IsUpdatedSince(metaVer))
                 {
-                    if (!metaMgr->ProcessPendingUpdates(env.Get()->GetTypeUpdater(), &err))
+                    if (!metaMgr->ProcessPendingUpdates(err))
                         return 0;
                 }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/d44de994/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
index f3757b4..333b9bc 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj
@@ -188,6 +188,7 @@
     <Compile Include="Common\Package-Info.cs" />
     <Compile Include="Impl\Binary\DateTimeSerializer.cs" />
     <Compile Include="Impl\Binary\IO\IBinaryStreamProcessor.cs" />
+    <Compile Include="Impl\Binary\Metadata\BinaryField.cs" />
     <Compile Include="Impl\Binary\SerializableSerializer.cs" />
     <Compile Include="Impl\Binary\BinaryWriterExtensions.cs" />
     <Compile Include="Cache\Affinity\AffinityFunctionBase.cs" />

http://git-wip-us.apache.org/repos/asf/ignite/blob/d44de994/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectBuilder.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectBuilder.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectBuilder.cs
index 6e8df0b..e77cbae 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectBuilder.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryObjectBuilder.cs
@@ -537,7 +537,7 @@ namespace Apache.Ignite.Core.Impl.Binary
                 // 3. Handle metadata.
                 if (metaHnd != null)
                 {
-                    IDictionary<string, int> meta = metaHnd.OnObjectWriteFinished();
+                    IDictionary<string, BinaryField> meta = metaHnd.OnObjectWriteFinished();
 
                     if (meta != null)
                         _parent._ctx.Writer.SaveMetadata(desc, meta);

http://git-wip-us.apache.org/repos/asf/ignite/blob/d44de994/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs
index 6935fa2..f5bc370 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryProcessor.cs
@@ -120,7 +120,8 @@ namespace Apache.Ignite.Core.Impl.Binary
                     foreach (var field in fields)
                     {
                         w.WriteString(field.Key);
-                        w.WriteInt(field.Value);
+                        w.WriteInt(field.Value.TypeId);
+                        w.WriteInt(field.Value.FieldId);
                     }
 
                     w.WriteBoolean(meta.IsEnum);

http://git-wip-us.apache.org/repos/asf/ignite/blob/d44de994/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs
index 5ec649a..0490ec8 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/BinaryWriter.cs
@@ -1468,7 +1468,7 @@ namespace Apache.Ignite.Core.Impl.Binary
         /// </summary>
         /// <param name="desc">The descriptor.</param>
         /// <param name="fields">Fields metadata.</param>
-        internal void SaveMetadata(IBinaryTypeDescriptor desc, IDictionary<string, int> fields)
+        internal void SaveMetadata(IBinaryTypeDescriptor desc, IDictionary<string, BinaryField> fields)
         {
             Debug.Assert(desc != null);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/d44de994/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
index 9ec4216..b929f3a 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Marshaller.cs
@@ -346,13 +346,13 @@ namespace Apache.Ignite.Core.Impl.Binary
         {
             foreach (var meta in newMetas)
             {
-                var mergeInfo = new Dictionary<int, Tuple<string, int>>(meta.GetFieldsMap().Count);
+                var mergeInfo = new Dictionary<int, Tuple<string, BinaryField>>(meta.GetFieldsMap().Count);
 
-                foreach (KeyValuePair<string, int> fieldMeta in meta.GetFieldsMap())
+                foreach (var fieldMeta in meta.GetFieldsMap())
                 {
                     int fieldId = BinaryUtils.FieldId(meta.TypeId, fieldMeta.Key, null, null);
 
-                    mergeInfo[fieldId] = new Tuple<string, int>(fieldMeta.Key, fieldMeta.Value);
+                    mergeInfo[fieldId] = new Tuple<string, BinaryField>(fieldMeta.Key, fieldMeta.Value);
                 }
 
                 _metas[meta.TypeId].Merge(mergeInfo);

http://git-wip-us.apache.org/repos/asf/ignite/blob/d44de994/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryField.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryField.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryField.cs
new file mode 100644
index 0000000..483b3eb
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryField.cs
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+ 
+namespace Apache.Ignite.Core.Impl.Binary.Metadata
+{
+    using Apache.Ignite.Core.Binary;
+
+    /// <summary>
+    /// Binary field metadata.
+    /// </summary>
+    internal struct BinaryField
+    {
+        /** Type ID. */
+        private readonly int _typeId;
+
+        /** Field ID. */
+        private readonly int _fieldId;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="BinaryField" /> class.
+        /// </summary>
+        /// <param name="typeId">Type ID.</param>
+        /// <param name="fieldId">Field ID.</param>
+        public BinaryField(int typeId, int fieldId)
+        {
+            _typeId = typeId;
+            _fieldId = fieldId;
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="BinaryField" /> class.
+        /// </summary>
+        /// <param name="reader">Reader.</param>
+        public BinaryField(IBinaryRawReader reader)
+        {
+            _typeId = reader.ReadInt();
+            _fieldId = reader.ReadInt();
+        }
+
+        /// <summary>
+        /// Type ID.
+        /// </summary>
+        /// <returns>Type ID</returns>
+        public int TypeId
+        {
+            get { return _typeId; }
+        }
+
+        /// <summary>
+        /// Field ID.
+        /// </summary>
+        /// <returns>Field ID</returns>
+        public int FieldId
+        {
+            get { return _fieldId; }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/d44de994/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryType.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryType.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryType.cs
index cb0d3cd..837c28a 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryType.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryType.cs
@@ -21,6 +21,7 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
     using System.Diagnostics;
     using System.Diagnostics.CodeAnalysis;
     using Apache.Ignite.Core.Binary;
+    using Apache.Ignite.Core.Impl.Common;
 
     /// <summary>
     /// Binary metadata implementation.
@@ -32,7 +33,7 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
             new BinaryType(BinaryUtils.TypeObject, BinaryTypeNames.TypeNameObject, null, null, false);
 
         /** Empty dictionary. */
-        private static readonly IDictionary<string, int> EmptyDict = new Dictionary<string, int>();
+        private static readonly IDictionary<string, BinaryField> EmptyDict = new Dictionary<string, BinaryField>();
 
         /** Empty list. */
         private static readonly ICollection<string> EmptyList = new List<string>().AsReadOnly();
@@ -41,7 +42,7 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
         private static readonly string[] TypeNames = new string[byte.MaxValue];
 
         /** Fields. */
-        private readonly IDictionary<string, int> _fields;
+        private readonly IDictionary<string, BinaryField> _fields;
 
         /** Enum flag. */
         private readonly bool _isEnum;
@@ -121,7 +122,19 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
             _typeId = reader.ReadInt();
             _typeName = reader.ReadString();
             _affinityKeyFieldName = reader.ReadString();
-            _fields = reader.ReadDictionaryAsGeneric<string, int>();
+
+            int fieldsNum = reader.ReadInt();
+
+            _fields = new Dictionary<string, BinaryField>(fieldsNum);
+
+            for (int i = 0; i < fieldsNum; ++i)
+            {
+                string name = reader.ReadString();
+                BinaryField field = new BinaryField(reader);
+
+                _fields[name] = field;
+            }
+            
             _isEnum = reader.ReadBoolean();
         }
 
@@ -130,7 +143,7 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
         /// </summary>
         /// <param name="desc">Descriptor.</param>
         /// <param name="fields">Fields.</param>
-        public BinaryType(IBinaryTypeDescriptor desc, IDictionary<string, int> fields = null) 
+        public BinaryType(IBinaryTypeDescriptor desc, IDictionary<string, BinaryField> fields = null) 
             : this (desc.TypeId, desc.TypeName, fields, desc.AffinityKeyFieldName, desc.IsEnum)
         {
             _descriptor = desc;
@@ -144,7 +157,7 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
         /// <param name="fields">Fields.</param>
         /// <param name="affKeyFieldName">Affinity key field name.</param>
         /// <param name="isEnum">Enum flag.</param>
-        public BinaryType(int typeId, string typeName, IDictionary<string, int> fields,
+        public BinaryType(int typeId, string typeName, IDictionary<string, BinaryField> fields,
             string affKeyFieldName, bool isEnum)
         {
             _typeId = typeId;
@@ -188,13 +201,18 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
         /// </returns>
         public string GetFieldTypeName(string fieldName)
         {
+            IgniteArgumentCheck.NotNullOrEmpty(fieldName, "fieldName");
+
             if (_fields != null)
             {
-                int typeId;
+                BinaryField fieldMeta;
 
-                _fields.TryGetValue(fieldName, out typeId);
+                if (!_fields.TryGetValue(fieldName, out fieldMeta))
+                {
+                    throw new BinaryObjectException("BinaryObject field does not exist: " + fieldName);
+                }
 
-                return GetTypeName(typeId);
+                return GetTypeName(fieldMeta.TypeId);
             }
             
             return null;
@@ -226,7 +244,7 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
         /// Gets fields map.
         /// </summary>
         /// <returns>Fields map.</returns>
-        public IDictionary<string, int> GetFieldsMap()
+        public IDictionary<string, BinaryField> GetFieldsMap()
         {
             return _fields ?? EmptyDict;
         }
@@ -234,7 +252,7 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
         /// <summary>
         /// Updates the fields.
         /// </summary>
-        public void UpdateFields(IDictionary<string, int> fields)
+        public void UpdateFields(IDictionary<string, BinaryField> fields)
         {
             if (fields == null || fields.Count == 0)
                 return;

http://git-wip-us.apache.org/repos/asf/ignite/blob/d44de994/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryTypeHashsetHandler.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryTypeHashsetHandler.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryTypeHashsetHandler.cs
index af5902f..a8d26d3 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryTypeHashsetHandler.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryTypeHashsetHandler.cs
@@ -25,13 +25,13 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
     internal class BinaryTypeHashsetHandler : IBinaryTypeHandler
     {
         /** Empty fields collection. */
-        private static readonly IDictionary<string, int> EmptyFields = new Dictionary<string, int>();
+        private static readonly IDictionary<string, BinaryField> EmptyFields = new Dictionary<string, BinaryField>();
 
         /** IDs known when serialization starts. */
         private readonly ICollection<int> _ids;
 
         /** New fields. */
-        private IDictionary<string, int> _fieldMap;
+        private IDictionary<string, BinaryField> _fieldMap;
 
         /** */
         private readonly bool _newType;
@@ -53,15 +53,15 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
             if (!_ids.Contains(fieldId))
             {
                 if (_fieldMap == null)
-                    _fieldMap = new Dictionary<string, int>();
+                    _fieldMap = new Dictionary<string, BinaryField>();
 
                 if (!_fieldMap.ContainsKey(fieldName))
-                    _fieldMap[fieldName] = typeId;
+                    _fieldMap[fieldName] = new BinaryField(typeId, fieldId);
             }
         }
 
         /** <inheritdoc /> */
-        public IDictionary<string, int> OnObjectWriteFinished()
+        public IDictionary<string, BinaryField> OnObjectWriteFinished()
         {
             return _fieldMap ?? (_newType ? EmptyFields : null);
         }

http://git-wip-us.apache.org/repos/asf/ignite/blob/d44de994/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryTypeHolder.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryTypeHolder.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryTypeHolder.cs
index 1f290d8..cdbc687 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryTypeHolder.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/BinaryTypeHolder.cs
@@ -101,7 +101,7 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
         /// Merge newly sent field metadatas into existing ones.
         /// </summary>
         /// <param name="newMap">New field metadatas map.</param>
-        public void Merge(IDictionary<int, Tuple<string, int>> newMap)
+        public void Merge(IDictionary<int, Tuple<string, BinaryField>> newMap)
         {
             _saved = true;
 
@@ -116,11 +116,12 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
 
                 var newIds = ids0 != null ? new HashSet<int>(ids0) : new HashSet<int>();
 
-                IDictionary<string, int> newFields = meta0 != null ?
-                    new Dictionary<string, int>(meta0.GetFieldsMap()) : new Dictionary<string, int>(newMap.Count);
+                IDictionary<string, BinaryField> newFields = meta0 != null 
+                    ? new Dictionary<string, BinaryField>(meta0.GetFieldsMap()) 
+                    : new Dictionary<string, BinaryField>(newMap.Count);
 
                 // 2. Add new fields.
-                foreach (KeyValuePair<int, Tuple<string, int>> newEntry in newMap)
+                foreach (var newEntry in newMap)
                 {
                     if (!newIds.Contains(newEntry.Key))
                         newIds.Add(newEntry.Key);

http://git-wip-us.apache.org/repos/asf/ignite/blob/d44de994/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/IBinaryTypeHandler.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/IBinaryTypeHandler.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/IBinaryTypeHandler.cs
index a02764e..a98ab58 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/IBinaryTypeHandler.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Binary/Metadata/IBinaryTypeHandler.cs
@@ -36,6 +36,6 @@ namespace Apache.Ignite.Core.Impl.Binary.Metadata
         /// Callback invoked when object write is finished and it is time to collect missing metadata.
         /// </summary>
         /// <returns>Collected metadata.</returns>
-        IDictionary<string, int> OnObjectWriteFinished();
+        IDictionary<string, BinaryField> OnObjectWriteFinished();
     }
 }


Mime
View raw message