You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2015/09/03 11:28:34 UTC

[06/14] ignite git commit: IGNITE-1364: WIP.

http://git-wip-us.apache.org/repos/asf/ignite/blob/1e18fa32/modules/platform/src/main/cpp/core/include/gridgain/impl/operations.h
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/cpp/core/include/gridgain/impl/operations.h b/modules/platform/src/main/cpp/core/include/gridgain/impl/operations.h
new file mode 100644
index 0000000..63bc7d6
--- /dev/null
+++ b/modules/platform/src/main/cpp/core/include/gridgain/impl/operations.h
@@ -0,0 +1,444 @@
+/*
+ *  Copyright (C) GridGain Systems. All Rights Reserved.
+ *  _________        _____ __________________        _____
+ *  __  ____/___________(_)______  /__  ____/______ ____(_)_______
+ *  _  / __  __  ___/__  / _  __  / _  / __  _  __ `/__  / __  __ \
+ *  / /_/ /  _  /    _  /  / /_/ /  / /_/ /  / /_/ / _  /  _  / / /
+ *  \____/   /_/     /_/   \_,__/   \____/   \__,_/  /_/   /_/ /_/
+ */
+
+#ifndef _GRIDGAIN_IMPL_OPERATION
+#define _GRIDGAIN_IMPL_OPERATION
+
+#include <map>
+#include <set>
+#include <vector>
+
+#include <ignite/common/common.h>
+
+#include "gridgain/cache/cache_entry.h"
+#include "gridgain/impl/portable/portable_reader_impl.h"
+#include "gridgain/impl/portable/portable_writer_impl.h"
+#include "gridgain/portable/portable.h"
+
+namespace gridgain
+{
+    namespace impl
+    {
+        /**
+         * Input operation.
+         */
+        class InputOperation
+        {
+        public:
+            /**
+             * Destructor.
+             */
+            virtual ~InputOperation()
+            {
+                // No-op.
+            }
+
+            /**
+             * Process input.
+             *
+             * @param writer Writer.
+             */
+            virtual void ProcessInput(gridgain::impl::portable::PortableWriterImpl& writer) = 0;
+        };
+
+        /**
+         * Input operation accepting a single argument.
+         */
+        template<typename T>
+        class In1Operation : public InputOperation
+        {
+        public:
+            /**
+             * Constructor.
+             * 
+             * @param val Value.
+             */
+            In1Operation(const T* val) : val(val)
+            {
+                // No-op.
+            }
+
+            virtual void ProcessInput(gridgain::impl::portable::PortableWriterImpl& writer)
+            {
+                writer.WriteTopObject<T>(*val);
+            }
+        private:
+            /** Value. */
+            const T* val; 
+
+            IGNITE_NO_COPY_ASSIGNMENT(In1Operation)
+        };
+
+        /**
+         * Input operation accepting two single objects.
+         */
+        template<typename T1, typename T2>
+        class In2Operation : public InputOperation
+        {
+        public:
+            /**
+             * Constructor.
+             *
+             * @param val1 First value.
+             * @param val2 Second value.
+             */
+            In2Operation(const T1* val1, const T2* val2) : val1(val1), val2(val2)
+            {
+                // No-op.
+            }
+
+            virtual void ProcessInput(gridgain::impl::portable::PortableWriterImpl& writer)
+            {
+                writer.WriteTopObject<T1>(*val1);
+                writer.WriteTopObject<T2>(*val2);
+            }
+        private:
+            /** First value. */
+            const T1* val1; 
+
+            /** Second value. */
+            const T2* val2; 
+
+            IGNITE_NO_COPY_ASSIGNMENT(In2Operation)
+        };
+
+        /**
+         * Input operation accepting three single objects.
+         */
+        template<typename T1, typename T2, typename T3>
+        class In3Operation : public InputOperation
+        {
+        public:
+            /**
+             * Constructor.
+             *
+             * @param val1 First value.
+             * @param val2 Second value.
+             * @param val3 Third value.
+             */
+            In3Operation(const T1* val1, const T2* val2, const T3* val3) : val1(val1), val2(val2), val3(val3)
+            {
+                // No-op.
+            }
+
+            virtual void ProcessInput(gridgain::impl::portable::PortableWriterImpl& writer)
+            {
+                writer.WriteTopObject<T1>(*val1);
+                writer.WriteTopObject<T2>(*val2);
+                writer.WriteTopObject<T3>(*val3);
+            }
+        private:
+            /** First value. */
+            const T1* val1;
+
+            /** Second value. */
+            const T2* val2;
+
+            /** Third value. */
+            const T3* val3;
+
+            IGNITE_NO_COPY_ASSIGNMENT(In3Operation)
+        };
+
+        /*
+         * Input set operation.
+         */
+        template<typename T>
+        class InSetOperation : public InputOperation
+        {
+        public:
+            /**
+             * Constructor.
+             *
+             * @param val Value.
+             */
+            InSetOperation(const std::set<T>* val) : val(val)
+            {
+                // No-op.
+            }
+
+            virtual void ProcessInput(gridgain::impl::portable::PortableWriterImpl& writer)
+            {
+                writer.GetStream()->WriteInt32(static_cast<int32_t>(val->size()));
+
+                for (typename std::set<T>::const_iterator it = val->begin(); it != val->end(); ++it)
+                    writer.WriteTopObject<T>(*it);
+            }
+        private:
+            /** Value. */
+            const std::set<T>* val; 
+
+            IGNITE_NO_COPY_ASSIGNMENT(InSetOperation)
+        };
+
+        /**
+         * Input map operation.
+         */
+        template<typename K, typename V>
+        class InMapOperation : public InputOperation
+        {
+        public:
+            /*
+             * Constructor.
+             *
+             * @param val Value.
+             */
+            InMapOperation(const std::map<K, V>* val) : val(val)
+            {
+                // No-op.
+            }
+
+            virtual void ProcessInput(gridgain::impl::portable::PortableWriterImpl& writer)
+            {
+                writer.GetStream()->WriteInt32(static_cast<int32_t>(val->size()));
+
+                for (typename std::map<K, V>::const_iterator it = val->begin(); it != val->end(); ++it) {
+                    writer.WriteTopObject<K>(it->first);
+                    writer.WriteTopObject<V>(it->second);
+                }
+            }
+        private:
+            /** Value. */
+            const std::map<K, V>* val; 
+
+            IGNITE_NO_COPY_ASSIGNMENT(InMapOperation)
+        };
+
+        /**
+         * Cache LocalPeek input operation.
+         */
+        template<typename T>
+        class InCacheLocalPeekOperation : public InputOperation
+        {
+        public:
+            /**
+             * Constructor.
+             *
+             * @param key Key.
+             * @param peekModes Peek modes.
+             */
+            InCacheLocalPeekOperation(const T* key, int32_t peekModes) : key(key), peekModes(peekModes)
+            {
+                // No-op.
+            }
+
+            virtual void ProcessInput(gridgain::impl::portable::PortableWriterImpl& writer)
+            {
+                writer.WriteTopObject<T>(*key);
+                writer.GetStream()->WriteInt32(peekModes);
+            }
+        private:
+            /** Key. */
+            const T* key;   
+
+            /** Peek modes. */
+            int32_t peekModes; 
+
+            IGNITE_NO_COPY_ASSIGNMENT(InCacheLocalPeekOperation)
+        };
+
+        /**
+         * Output operation.
+         */
+        class OutputOperation
+        {
+        public:
+            /**
+             * Destructor.
+             */
+            virtual ~OutputOperation()
+            {
+                // No-op.
+            }
+
+            /**
+             * Process output.
+             *
+             * @param reader Reader.
+             */
+            virtual void ProcessOutput(gridgain::impl::portable::PortableReaderImpl& reader) = 0;
+        };
+
+        /**
+         * Output operation returning single object.
+         */
+        template<typename T>
+        class Out1Operation : public OutputOperation
+        {
+        public:
+            /**
+             * Constructor.
+             */
+            Out1Operation()
+            {
+                // No-op.
+            }
+
+            virtual void ProcessOutput(gridgain::impl::portable::PortableReaderImpl& reader)
+            {
+                val = reader.ReadTopObject<T>();
+            }
+
+            /**
+             * Get value.
+             *
+             * @param Value.
+             */
+            T GetResult()
+            {
+                return val;
+            }
+        private:
+            /** Value. */
+            T val; 
+
+            IGNITE_NO_COPY_ASSIGNMENT(Out1Operation)
+        };
+
+        /**
+         * Output operation returning single object.
+         */
+        template<typename T1, typename T2>
+        class Out2Operation : public OutputOperation
+        {
+        public:
+            /**
+             * Constructor.
+             */
+            Out2Operation()
+            {
+                // No-op.
+            }
+
+            virtual void ProcessOutput(gridgain::impl::portable::PortableReaderImpl& reader)
+            {
+                val1 = reader.ReadTopObject<T1>();
+                val2 = reader.ReadTopObject<T2>();
+            }
+
+            /**
+             * Get value 1.
+             *
+             * @param Value 1.
+             */
+            T1& Get1()
+            {
+                return val1;
+            }
+
+            /**
+             * Get value 2.
+             *
+             * @param Value 2.
+             */
+            T2& Get2()
+            {
+                return val2;
+            }
+
+        private:
+            /** Value 1. */
+            T1 val1; 
+            
+            /** Value 2. */
+            T2 val2; 
+
+            IGNITE_NO_COPY_ASSIGNMENT(Out2Operation)
+        };
+        
+        /*
+         * Output map operation.
+         */
+        template<typename T1, typename T2>
+        class OutMapOperation :public OutputOperation
+        {
+        public:
+            /**
+             * Constructor.
+             */
+            OutMapOperation()
+            {
+                // No-op.
+            }
+
+            virtual void ProcessOutput(gridgain::impl::portable::PortableReaderImpl& reader)
+            {
+                bool exists = reader.GetStream()->ReadBool();
+
+                if (exists)
+                {
+                    int32_t cnt = reader.GetStream()->ReadInt32();
+
+                    std::map<T1, T2> val0;
+
+                    for (int i = 0; i < cnt; i++) {
+                        T1 t1 = reader.ReadTopObject<T1>();
+                        T2 t2 = reader.ReadTopObject<T2>();
+
+                        val0[t1] = t2;
+                    }
+
+                    val = val0;
+                }
+            }
+
+            /**
+             * Get value.
+             *
+             * @param Value.
+             */
+            std::map<T1, T2> GetResult()
+            {
+                return val;
+            }
+        private:
+            /** Value. */
+            std::map<T1, T2> val;
+
+            IGNITE_NO_COPY_ASSIGNMENT(OutMapOperation)
+        };
+
+        /*
+         * Output query GET ALL operation.
+         */
+        template<typename K, typename V>
+        class OutQueryGetAllOperation : public OutputOperation
+        {
+        public:
+            /**
+             * Constructor.
+             */
+            OutQueryGetAllOperation(std::vector<gridgain::cache::CacheEntry<K, V>>* res) : res(res)
+            {
+                // No-op.
+            }
+
+            virtual void ProcessOutput(gridgain::impl::portable::PortableReaderImpl& reader)
+            {
+                int32_t cnt = reader.ReadInt32();
+
+                for (int i = 0; i < cnt; i++) 
+                {
+                    K key = reader.ReadTopObject<K>();
+                    V val = reader.ReadTopObject<V>();
+
+                    res->push_back(gridgain::cache::CacheEntry<K, V>(key, val));
+                }
+            }
+
+        private:
+            /** Entries. */
+            std::vector<gridgain::cache::CacheEntry<K, V>>* res;
+            
+            IGNITE_NO_COPY_ASSIGNMENT(OutQueryGetAllOperation)
+        };
+    }
+}
+
+#endif
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/1e18fa32/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_common.h
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_common.h b/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_common.h
new file mode 100644
index 0000000..306f443
--- /dev/null
+++ b/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_common.h
@@ -0,0 +1,138 @@
+/*
+ *  Copyright (C) GridGain Systems. All Rights Reserved.
+ *  _________        _____ __________________        _____
+ *  __  ____/___________(_)______  /__  ____/______ ____(_)_______
+ *  _  / __  __  ___/__  / _  __  / _  / __  _  __ `/__  / __  __ \
+ *  / /_/ /  _  /    _  /  / /_/ /  / /_/ /  / /_/ / _  /  _  / / /
+ *  \____/   /_/     /_/   \_,__/   \____/   \__,_/  /_/   /_/ /_/
+ */
+
+#ifndef _GRIDGAIN_IMPL_PORTABLE_COMMON
+#define _GRIDGAIN_IMPL_PORTABLE_COMMON
+
+#include <stdint.h>
+
+namespace gridgain
+{    
+    namespace impl
+    {
+        namespace portable
+        {
+            /** Header: null. */
+            const int8_t GG_HDR_NULL = 101;
+
+            /** Header: handle. */
+            const int8_t GG_HDR_HND = 102;
+
+            /** Header: fulle form. */
+            const int8_t GG_HDR_FULL = 103;
+
+            /** Full header length. */
+            const int32_t GG_FULL_HDR_LEN = 18;
+
+            /** Type: object. */
+            const int8_t GG_TYPE_OBJECT = GG_HDR_FULL;
+
+            /** Type: unsigned byte. */
+            const int8_t GG_TYPE_BYTE = 1;
+
+            /** Type: short. */
+            const int8_t GG_TYPE_SHORT = 2;
+
+            /** Type: int. */
+            const int8_t GG_TYPE_INT = 3;
+
+            /** Type: long. */
+            const int8_t GG_TYPE_LONG = 4;
+
+            /** Type: float. */
+            const int8_t GG_TYPE_FLOAT = 5;
+
+            /** Type: double. */
+            const int8_t GG_TYPE_DOUBLE = 6;
+
+            /** Type: char. */
+            const int8_t GG_TYPE_CHAR = 7;
+
+            /** Type: boolean. */
+            const int8_t GG_TYPE_BOOL = 8;
+
+            /** Type: decimal. */
+            const int8_t GG_TYPE_DECIMAL = 30;
+
+            /** Type: string. */
+            const int8_t GG_TYPE_STRING = 9;
+
+            /** Type: UUID. */
+            const int8_t GG_TYPE_UUID = 10;
+
+            /** Type: date. */
+            const int8_t GG_TYPE_DATE = 11;
+
+            /** Type: unsigned byte array. */
+            const int8_t GG_TYPE_ARRAY_BYTE = 12;
+
+            /** Type: short array. */
+            const int8_t GG_TYPE_ARRAY_SHORT = 13;
+
+            /** Type: int array. */
+            const int8_t GG_TYPE_ARRAY_INT = 14;
+
+            /** Type: long array. */
+            const int8_t GG_TYPE_ARRAY_LONG = 15;
+
+            /** Type: float array. */
+            const int8_t GG_TYPE_ARRAY_FLOAT = 16;
+
+            /** Type: double array. */
+            const int8_t GG_TYPE_ARRAY_DOUBLE = 17;
+
+            /** Type: char array. */
+            const int8_t GG_TYPE_ARRAY_CHAR = 18;
+
+            /** Type: boolean array. */
+            const int8_t GG_TYPE_ARRAY_BOOL = 19;
+
+            /** Type: decimal array. */
+            const int8_t GG_TYPE_ARRAY_DECIMAL = 31;
+
+            /** Type: string array. */
+            const int8_t GG_TYPE_ARRAY_STRING = 20;
+
+            /** Type: UUID array. */
+            const int8_t GG_TYPE_ARRAY_UUID = 21;
+
+            /** Type: date array. */
+            const int8_t GG_TYPE_ARRAY_DATE = 22;
+
+            /** Type: object array. */
+            const int8_t GG_TYPE_ARRAY = 23;
+
+            /** Type: collection. */
+            const int8_t GG_TYPE_COLLECTION = 24;
+
+            /** Type: map. */
+            const int8_t GG_TYPE_MAP = 25;
+
+            /** Type: map entry. */
+            const int8_t GG_TYPE_MAP_ENTRY = 26;
+
+            /** Type: portable object. */
+            const int8_t GG_TYPE_PORTABLE = 27;
+
+            /** Read/write single object. */
+            const int32_t GG_PORTABLE_MODE_SINGLE = 0;
+
+            /** Read/write array. */
+            const int32_t GG_PORTABLE_MODE_ARRAY = 1;
+
+            /** Read/write collection. */
+            const int32_t GG_PORTABLE_MODE_COL = 2;
+
+            /** Read/write map. */
+            const int32_t GG_PORTABLE_MODE_MAP = 3;
+        }
+    }    
+}
+
+#endif
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/1e18fa32/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_id_resolver.h
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_id_resolver.h b/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_id_resolver.h
new file mode 100644
index 0000000..699e911
--- /dev/null
+++ b/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_id_resolver.h
@@ -0,0 +1,98 @@
+/*
+ *  Copyright (C) GridGain Systems. All Rights Reserved.
+ *  _________        _____ __________________        _____
+ *  __  ____/___________(_)______  /__  ____/______ ____(_)_______
+ *  _  / __  __  ___/__  / _  __  / _  / __  _  __ `/__  / __  __ \
+ *  / /_/ /  _  /    _  /  / /_/ /  / /_/ /  / /_/ / _  /  _  / / /
+ *  \____/   /_/     /_/   \_,__/   \____/   \__,_/  /_/   /_/ /_/
+ */
+
+#ifndef _GRIDGAIN_IMPL_PORTABLE_ID_RESOLVER
+#define _GRIDGAIN_IMPL_PORTABLE_ID_RESOLVER
+
+#include "gridgain/portable/portable_type.h"
+
+namespace gridgain
+{
+    namespace impl
+    {
+        namespace portable
+        {
+            /**
+             * Portable type id resolver.
+             */
+            class PortableIdResolver
+            {
+            public:
+                /**
+                 * Destructor.
+                 */
+                virtual ~PortableIdResolver()
+                {
+                    // No-op.
+                }
+
+                /**
+                 * Get portable object type ID.
+                 *
+                 * @return Type ID.
+                 */
+                virtual int32_t GetTypeId() = 0;
+
+                /**
+                 * Get portable object field ID.
+                 *
+                 * @param typeId Type ID.
+                 * @param name Field name.
+                 * @return Field ID.
+                 */
+                virtual int32_t GetFieldId(const int32_t typeId, const char* name) = 0;
+            };
+
+            /**
+             * Templated portable type descriptor.
+             */
+            template<typename T>
+            class TemplatedPortableIdResolver : public PortableIdResolver
+            {
+            public:
+                /**
+                 * Constructor.
+                 */
+                TemplatedPortableIdResolver()
+                {
+                    type = gridgain::portable::PortableType<T>();
+                }
+
+                /**
+                 * Constructor.
+                 *
+                 * @param type Portable type.
+                 */
+                TemplatedPortableIdResolver(gridgain::portable::PortableType<T> type) : type(type)
+                {
+                    // No-op.
+                }
+
+                virtual int32_t GetTypeId()
+                {
+                    return type.GetTypeId();
+                }
+
+                virtual int32_t GetFieldId(const int32_t typeId, const char* name) {
+                    if (!name)
+                    {
+                        GG_ERROR_1(GridError::GG_ERR_PORTABLE, "Field name cannot be NULL.");
+                    }
+
+                    return type.GetFieldId(name);
+                }
+            private:
+                /** Actual type.  */
+                gridgain::portable::PortableType<T> type; 
+            };
+        }
+    }
+}
+
+#endif
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/1e18fa32/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_metadata_handler.h
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_metadata_handler.h b/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_metadata_handler.h
new file mode 100644
index 0000000..5b203ac
--- /dev/null
+++ b/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_metadata_handler.h
@@ -0,0 +1,94 @@
+/*
+ *  Copyright (C) GridGain Systems. All Rights Reserved.
+ *  _________        _____ __________________        _____
+ *  __  ____/___________(_)______  /__  ____/______ ____(_)_______
+ *  _  / __  __  ___/__  / _  __  / _  / __  _  __ `/__  / __  __ \
+ *  / /_/ /  _  /    _  /  / /_/ /  / /_/ /  / /_/ / _  /  _  / / /
+ *  \____/   /_/     /_/   \_,__/   \____/   \__,_/  /_/   /_/ /_/
+ */
+
+#ifndef _GRIDGAIN_IMPL_PORTABLE_METADATA_HANDLER
+#define _GRIDGAIN_IMPL_PORTABLE_METADATA_HANDLER
+
+#include <ignite/common/concurrent.h>
+
+#include "gridgain/impl/portable/portable_metadata_snapshot.h"
+
+namespace gridgain
+{    
+    namespace impl
+    {
+        namespace portable
+        {
+            /**
+             * Metadata handler. Tracks all metadata updates during write session.
+             */
+            class PortableMetadataHandler 
+            {
+            public:
+                /**
+                 * Constructor.
+                 *
+                 * @param snap Snapshot.
+                 */
+                PortableMetadataHandler(SPSnap snap);
+                
+                /**
+                 * Destructor.
+                 */
+                ~PortableMetadataHandler();
+
+                /**
+                 * Callback invoked when field is being written.
+                 *
+                 * @param fieldId Field ID.
+                 * @param fieldName Field name.
+                 * @param fieldTypeId Field type ID.
+                 */
+                void OnFieldWritten(int32_t fieldId, std::string fieldName, int32_t fieldTypeId);
+
+                /**
+                 * Get initial snapshot.
+                 *
+                 * @param Snapshot.
+                 */
+                SPSnap GetSnapshot();
+
+                /**
+                 * Whether any difference exists.
+                 *
+                 * @param True if difference exists.
+                 */
+                bool HasDifference();
+
+                /**
+                 * Get recorded field IDs difference.
+                 *
+                 * @param Recorded field IDs difference.
+                 */
+                std::set<int32_t>* GetFieldIds();
+
+                /**
+                 * Get recorded fields difference.
+                 *
+                 * @param Recorded fields difference.
+                 */
+                std::map<std::string, int32_t>* GetFields();
+
+            private:
+                /** Snapshot. */
+                SPSnap snap;                          
+
+                /** Recorded field IDs difference. */
+                std::set<int32_t>* fieldIds;           
+                
+                /** Recorded fields difference. */
+                std::map<std::string, int32_t>* fields; 
+
+                IGNITE_NO_COPY_ASSIGNMENT(PortableMetadataHandler)
+            };
+        }
+    }    
+}
+
+#endif
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/1e18fa32/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_metadata_manager.h
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_metadata_manager.h b/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_metadata_manager.h
new file mode 100644
index 0000000..9cab44f
--- /dev/null
+++ b/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_metadata_manager.h
@@ -0,0 +1,113 @@
+/*
+ *  Copyright (C) GridGain Systems. All Rights Reserved.
+ *  _________        _____ __________________        _____
+ *  __  ____/___________(_)______  /__  ____/______ ____(_)_______
+ *  _  / __  __  ___/__  / _  __  / _  / __  _  __ `/__  / __  __ \
+ *  / /_/ /  _  /    _  /  / /_/ /  / /_/ /  / /_/ / _  /  _  / / /
+ *  \____/   /_/     /_/   \_,__/   \____/   \__,_/  /_/   /_/ /_/
+ */
+
+#ifndef _GRIDGAIN_IMPL_PORTABLE_METADATA_MANAGER
+#define _GRIDGAIN_IMPL_PORTABLE_METADATA_MANAGER
+
+#include <vector>
+
+#include "gridgain/grid_error.h"
+
+#include "gridgain/impl/portable/portable_metadata_handler.h"
+#include "gridgain/impl/portable/portable_metadata_updater.h"
+
+namespace gridgain
+{    
+    namespace impl
+    {
+        namespace portable
+        {
+            /**
+             * Metadata manager.
+             */
+            class IGNITE_IMPORT_EXPORT PortableMetadataManager
+            {
+            public:
+                /**
+                 * Constructor.
+                 */
+                PortableMetadataManager();
+
+                /**
+                 * Destructor.
+                 */
+                ~PortableMetadataManager();
+
+                /**
+                 * Get handler.
+                 *
+                 * @param typeId Type ID.
+                 */
+                ignite::common::concurrent::SharedPointer<PortableMetadataHandler> GetHandler(int32_t typeId);
+
+                /**
+                 * Submit handler for processing.
+                 * 
+                 * @param typeName Type name.
+                 * @param typeId Type ID.
+                 * @param hnd Handler.
+                 */
+                void SubmitHandler(std::string typeName, int32_t typeId, PortableMetadataHandler* hnd);
+
+                /**
+                 * Get current metadata manager version.
+                 *
+                 * @param Version.
+                 */
+                int32_t GetVersion();
+
+                /**
+                 * Check whether something is updated since the given version.
+                 *
+                 * @param oldVer Old version.
+                 * @return True if updated and it is very likely that pending metadata exists.
+                 */
+                bool IsUpdatedSince(int32_t oldVer);
+
+                /**
+                 * Process pending updates.
+                 *
+                 * @param updated Updater.
+                 * @param err Error.
+                 * @return In case of success.
+                 */
+                bool ProcessPendingUpdates(PortableMetadataUpdater* updater, GridError* err);
+
+            private:
+                /** Current snapshots. */
+                ignite::common::concurrent::SharedPointer<std::map<int32_t, SPSnap>> snapshots;
+                
+                /** Pending snapshots. */
+                std::vector<SPSnap>* pending;                                          
+
+                /** Critical section. */
+                ignite::common::concurrent::CriticalSection* cs;
+
+                /** Version of pending changes. */
+                int32_t pendingVer;                                                    
+                
+                /** Latest version. */
+                int32_t ver;          
+
+                IGNITE_NO_COPY_ASSIGNMENT(PortableMetadataManager);
+
+                /**
+                 * Copy fields from a snapshot into relevant collections.
+                 *
+                 * @param snap Target snapshot.
+                 * @param fieldIds Field IDs.
+                 * @param fields Fields.
+                 */
+                void CopyFields(Snap* snap, std::set<int32_t>* fieldIds, std::map<std::string, int32_t>* fields);
+            };
+        }
+    }    
+}
+
+#endif
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/1e18fa32/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_metadata_snapshot.h
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_metadata_snapshot.h b/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_metadata_snapshot.h
new file mode 100644
index 0000000..df427aa
--- /dev/null
+++ b/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_metadata_snapshot.h
@@ -0,0 +1,114 @@
+/*
+ *  Copyright (C) GridGain Systems. All Rights Reserved.
+ *  _________        _____ __________________        _____
+ *  __  ____/___________(_)______  /__  ____/______ ____(_)_______
+ *  _  / __  __  ___/__  / _  __  / _  / __  _  __ `/__  / __  __ \
+ *  / /_/ /  _  /    _  /  / /_/ /  / /_/ /  / /_/ / _  /  _  / / /
+ *  \____/   /_/     /_/   \_,__/   \____/   \__,_/  /_/   /_/ /_/
+ */
+
+#ifndef _GRIDGAIN_IMPL_PORTABLE_METADATA_SNAPSHOT
+#define _GRIDGAIN_IMPL_PORTABLE_METADATA_SNAPSHOT
+
+#include <map>
+#include <set>
+#include <stdint.h>
+#include <string>
+
+#include <ignite/common/common.h>
+#include <ignite/common/concurrent.h>
+
+namespace gridgain
+{    
+    namespace impl
+    {
+        namespace portable
+        {
+            /**
+             * Metadata snapshot. 
+             */
+            class PortableMetadataSnapshot
+            {
+            public:
+                /**
+                 * Constructor.
+                 *
+                 * @param typeName Type name.
+                 * @param typeId Type ID.
+                 * @param fieldIds Field IDs.
+                 * @param fields Fields.
+                 */
+                PortableMetadataSnapshot(std::string typeName, int32_t typeId, std::set<int32_t>* fieldIds, 
+                    std::map<std::string, int32_t>* fields);
+                
+                /**
+                 * Destructor.
+                 */
+                ~PortableMetadataSnapshot();
+
+                /**
+                 * Check whether snapshot contains a field with the given ID.
+                 *
+                 * @param fieldId Field ID.
+                 * @return True if contains, false otherwise.
+                 */
+                bool ContainsFieldId(int32_t fieldId);
+
+                /**
+                 * Get type name.
+                 *
+                 * @param Type name.
+                 */
+                std::string GetTypeName();
+
+                /**
+                 * Get type ID.
+                 *
+                 * @return Type ID.
+                 */
+                int32_t GetTypeId();
+
+                /**
+                 * Whether snapshot contains any fields.
+                 *
+                 * @param True if fields exist.
+                 */
+                bool HasFields();
+
+                /** 
+                 * Get field IDs.
+                 *
+                 * @param Field IDs.
+                 */
+                std::set<int32_t>* GetFieldIds();
+
+                /**
+                 * Get fields.
+                 *
+                 * @return Fields.
+                 */
+                std::map<std::string, int32_t>* GetFields();
+
+            private:
+                /** Type name. */
+                std::string typeName;                   
+                
+                /** Type ID. */
+                int32_t typeId;
+
+                /** Known field IDs. */
+                std::set<int32_t>* fieldIds;
+
+                /** Field name-type mappings. */
+                std::map<std::string, int32_t>* fields; 
+
+                IGNITE_NO_COPY_ASSIGNMENT(PortableMetadataSnapshot)
+            };
+
+            typedef PortableMetadataSnapshot Snap;
+            typedef ignite::common::concurrent::SharedPointer<Snap> SPSnap;
+        }
+    }    
+}
+
+#endif
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/1e18fa32/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_metadata_updater.h
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_metadata_updater.h b/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_metadata_updater.h
new file mode 100644
index 0000000..ba1aefa
--- /dev/null
+++ b/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_metadata_updater.h
@@ -0,0 +1,45 @@
+/*
+ *  Copyright (C) GridGain Systems. All Rights Reserved.
+ *  _________        _____ __________________        _____
+ *  __  ____/___________(_)______  /__  ____/______ ____(_)_______
+ *  _  / __  __  ___/__  / _  __  / _  / __  _  __ `/__  / __  __ \
+ *  / /_/ /  _  /    _  /  / /_/ /  / /_/ /  / /_/ / _  /  _  / / /
+ *  \____/   /_/     /_/   \_,__/   \____/   \__,_/  /_/   /_/ /_/
+ */
+
+#ifndef _GRIDGAIN_IMPL_PORTABLE_METADATA_UPDATER
+#define _GRIDGAIN_IMPL_PORTABLE_METADATA_UPDATER
+
+#include "gridgain/grid_error.h"
+#include "gridgain/impl/portable/portable_metadata_snapshot.h"
+
+namespace gridgain
+{    
+    namespace impl
+    {
+        namespace portable
+        {
+            /**
+             * Metadata updater interface.
+             */
+            class IGNITE_IMPORT_EXPORT PortableMetadataUpdater
+            {
+            public:
+                /**
+                 * Destructor.
+                 */
+                virtual ~PortableMetadataUpdater();
+
+                /**
+                 * Update metadata using provided snapshot.
+                 *
+                 * @param snapshot Snapshot.
+                 * @param err Error.
+                 */
+                virtual bool Update(Snap* snapshot, GridError* err) = 0;
+            };
+        }
+    }    
+}
+
+#endif
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/1e18fa32/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_metadata_updater_impl.h
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_metadata_updater_impl.h b/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_metadata_updater_impl.h
new file mode 100644
index 0000000..518be96
--- /dev/null
+++ b/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_metadata_updater_impl.h
@@ -0,0 +1,57 @@
+/*
+ *  Copyright (C) GridGain Systems. All Rights Reserved.
+ *  _________        _____ __________________        _____
+ *  __  ____/___________(_)______  /__  ____/______ ____(_)_______
+ *  _  / __  __  ___/__  / _  __  / _  / __  _  __ `/__  / __  __ \
+ *  / /_/ /  _  /    _  /  / /_/ /  / /_/ /  / /_/ / _  /  _  / / /
+ *  \____/   /_/     /_/   \_,__/   \____/   \__,_/  /_/   /_/ /_/
+ */
+
+#ifndef _GRIDGAIN_IMPL_PORTABLE_METADATA_UPDATER_IMPL
+#define _GRIDGAIN_IMPL_PORTABLE_METADATA_UPDATER_IMPL
+
+#include <ignite/common/exports.h>
+
+#include "gridgain/impl/grid_environment.h"
+#include "gridgain/impl/portable/portable_metadata_updater.h"
+
+namespace gridgain
+{    
+    namespace impl
+    {
+        namespace portable
+        {
+            /**
+             * Metadata updater implementation.
+             */
+            class IGNITE_IMPORT_EXPORT PortableMetadataUpdaterImpl : public PortableMetadataUpdater
+            {
+            public:
+                /**
+                 * Constructor.
+                 *
+                 * @param env Environment.
+                 * @param javaRef Reference to Java object which is able to process metadata request.
+                 */
+                PortableMetadataUpdaterImpl(ignite::common::concurrent::SharedPointer<GridEnvironment> env, jobject javaRef);
+
+                /**
+                 * Destructor.
+                 */
+                ~PortableMetadataUpdaterImpl();
+
+                bool Update(Snap* snapshot, GridError* err);
+            private:
+                /** Environment. */
+                ignite::common::concurrent::SharedPointer<GridEnvironment> env;
+                
+                /** Handle to Java object. */
+                jobject javaRef;                 
+
+                IGNITE_NO_COPY_ASSIGNMENT(PortableMetadataUpdaterImpl)
+            };
+        }
+    }    
+}
+
+#endif
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/1e18fa32/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_reader_impl.h
----------------------------------------------------------------------
diff --git a/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_reader_impl.h b/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_reader_impl.h
new file mode 100644
index 0000000..40ab9ae
--- /dev/null
+++ b/modules/platform/src/main/cpp/core/include/gridgain/impl/portable/portable_reader_impl.h
@@ -0,0 +1,1122 @@
+/*
+ *  Copyright (C) GridGain Systems. All Rights Reserved.
+ *  _________        _____ __________________        _____
+ *  __  ____/___________(_)______  /__  ____/______ ____(_)_______
+ *  _  / __  __  ___/__  / _  __  / _  / __  _  __ `/__  / __  __ \
+ *  / /_/ /  _  /    _  /  / /_/ /  / /_/ /  / /_/ / _  /  _  / / /
+ *  \____/   /_/     /_/   \_,__/   \____/   \__,_/  /_/   /_/ /_/
+ */
+
+#ifndef _GRIDGAIN_IMPL_PORTABLE_READER
+#define _GRIDGAIN_IMPL_PORTABLE_READER
+
+#include <stdint.h>
+
+#include <ignite/common/common.h>
+
+#include "gridgain/impl/interop/interop_input_stream.h"
+#include "gridgain/impl/portable/portable_common.h"
+#include "gridgain/impl/portable/portable_id_resolver.h"
+#include "gridgain/impl/portable/portable_utils.h"
+#include "gridgain/impl/utils.h"
+#include "gridgain/portable/portable_consts.h"
+#include "gridgain/portable/portable_type.h"
+#include "gridgain/guid.h"
+
+namespace gridgain
+{
+    namespace impl
+    {
+        namespace portable
+        {
+            /**
+             * Internal implementation of portable reader.
+             */
+            class IGNITE_IMPORT_EXPORT PortableReaderImpl
+            {
+            public:
+                /**
+                 * Constructor.
+                 *
+                 * @param stream Interop stream.
+                 * @param idRslvr Portable ID resolver.
+                 * @param pos Object position in the stream.
+                 * @param usrType user type flag.
+                 * @param typeId Type ID.
+                 * @param hashcode Hash code.
+                 * @param len Length in bytes.
+                 * @param rawOff Raw data offset.
+                 */
+                PortableReaderImpl(interop::InteropInputStream* stream, PortableIdResolver* idRslvr,                     
+                    int32_t pos, bool usrType, int32_t typeId, int32_t hashCode, int32_t len, int32_t rawOff);
+
+                /**
+                 * Constructor used to construct light-weight reader allowing only raw operations 
+                 * and read of primitives.
+                 *
+                 * @param stream Interop stream.
+                 */
+                PortableReaderImpl(interop::InteropInputStream* stream);
+
+                /**
+                 * Read 8-byte signed integer. Maps to "byte" type in Java.
+                 *
+                 * @return Result.
+                 */
+                int8_t ReadInt8();
+
+                /**
+                 * Read array of 8-byte signed integers. Maps to "byte[]" type in Java.
+                 *
+                 * @param res Array to store data to.
+                 * @param len Expected length of array.
+                 * @return Actual amount of elements read. If "len" argument is less than actual
+                 *     array size or resulting array is set to null, nothing will be written
+                 *     to resulting array and returned value will contain required array length.
+                 *     -1 will be returned in case array in stream was null.
+                 */
+                int32_t ReadInt8Array(int8_t* res, const int32_t len);
+
+                /**
+                 * Read 8-byte signed integer. Maps to "byte" type in Java.
+                 *
+                 * @param fieldName Field name.
+                 * @return Result.
+                 */
+                int8_t ReadInt8(const char* fieldName);
+
+                /**
+                 * Read array of 8-byte signed integers. Maps to "byte[]" type in Java.
+                 *
+                 * @param fieldName Field name.
+                 * @param res Array to store data to.
+                 * @param len Expected length of array.                 
+                 * @return Actual amount of elements read. If "len" argument is less than actual
+                 *     array size or resulting array is set to null, nothing will be written
+                 *     to resulting array and returned value will contain required array length.
+                 *     -1 will be returned in case array in stream was null.
+                 */
+                int32_t ReadInt8Array(const char* fieldName, int8_t* res, const int32_t len);
+
+                /**
+                 * Read bool. Maps to "boolean" type in Java.
+                 *
+                 * @return Result.
+                 */
+                bool ReadBool();
+
+                /**
+                 * Read bool array. Maps to "boolean[]" type in Java.
+                 *
+                 * @param res Array to store data to.
+                 * @param len Expected length of array.                 
+                 * @return Actual amount of elements read. If "len" argument is less than actual
+                 *     array size or resulting array is set to null, nothing will be written
+                 *     to resulting array and returned value will contain required array length.
+                 *     -1 will be returned in case array in stream was null.
+                 */
+                int32_t ReadBoolArray(bool* res, const int32_t len);
+
+                /**
+                 * Read bool. Maps to "short" type in Java.
+                 *
+                 * @param fieldName Field name.
+                 * @return Result.
+                 */
+                bool ReadBool(const char* fieldName);
+
+                /**
+                 * Read bool array. Maps to "bool[]" type in Java.
+                 *
+                 * @param fieldName Field name.
+                 * @param res Array to store data to.
+                 * @param len Expected length of array.                 
+                 * @return Actual amount of elements read. If "len" argument is less than actual
+                 *     array size or resulting array is set to null, nothing will be written
+                 *     to resulting array and returned value will contain required array length.
+                 *     -1 will be returned in case array in stream was null.
+                 */
+                int32_t ReadBoolArray(const char* fieldName, bool* res, const int32_t len);
+
+                /**
+                 * Read 16-byte signed integer. Maps to "short" type in Java.
+                 *
+                 * @return Result.
+                 */
+                int16_t ReadInt16();
+
+                /**
+                 * Read array of 16-byte signed integers. Maps to "short[]" type in Java.
+                 *
+                 * @param res Array to store data to.
+                 * @param len Expected length of array.                 
+                 * @return Actual amount of elements read. If "len" argument is less than actual
+                 *     array size or resulting array is set to null, nothing will be written
+                 *     to resulting array and returned value will contain required array length.
+                 *     -1 will be returned in case array in stream was null.
+                 */
+                int32_t ReadInt16Array(int16_t* res, const int32_t len);
+
+                /**
+                 * Read 16-byte signed integer. Maps to "short" type in Java.
+                 *
+                 * @param fieldName Field name.
+                 * @return Result.
+                 */
+                int16_t ReadInt16(const char* fieldName);
+
+                /**
+                 * Read array of 16-byte signed integers. Maps to "short[]" type in Java.
+                 *
+                 * @param fieldName Field name.
+                 * @param res Array to store data to.
+                 * @param len Expected length of array.                 
+                 * @return Actual amount of elements read. If "len" argument is less than actual
+                 *     array size or resulting array is set to null, nothing will be written
+                 *     to resulting array and returned value will contain required array length.
+                 *      -1 will be returned in case array in stream was null.
+                 */
+                int32_t ReadInt16Array(const char* fieldName, int16_t* res, const int32_t len);
+
+                /**
+                 * Read 16-byte unsigned integer. Maps to "char" type in Java.
+                 *
+                 * @return Result.
+                 */
+                uint16_t ReadUInt16();
+
+                /**
+                 * Read array of 16-byte unsigned integers. Maps to "char[]" type in Java.
+                 *
+                 * @param res Array to store data to.
+                 * @param len Expected length of array.                 
+                 * @return Actual amount of elements read. If "len" argument is less than actual
+                 *     array size or resulting array is set to null, nothing will be written
+                 *     to resulting array and returned value will contain required array length.
+                 *     -1 will be returned in case array in stream was null.
+                 */
+                int32_t ReadUInt16Array(uint16_t* res, const int32_t len);
+
+                /**
+                 * Read 16-byte unsigned integer. Maps to "char" type in Java.
+                 *
+                 * @param fieldName Field name.
+                 * @return Result.
+                 */
+                uint16_t ReadUInt16(const char* fieldName);
+
+                /**
+                 * Read array of 16-byte unsigned integers. Maps to "char[]" type in Java.
+                 *
+                 * @param fieldName Field name.
+                 * @param res Array to store data to.
+                 * @param len Expected length of array.                 
+                 * @return Actual amount of elements read. If "len" argument is less than actual
+                 *     array size or resulting array is set to null, nothing will be written
+                 *     to resulting array and returned value will contain required array length.
+                 *     -1 will be returned in case array in stream was null.
+                 */
+                int32_t ReadUInt16Array(const char* fieldName, uint16_t* res, const int32_t len);
+
+                /**
+                 * Read 32-byte signed integer. Maps to "int" type in Java.
+                 *
+                 * @return Result.
+                 */
+                int32_t ReadInt32();
+
+                /**
+                 * Read array of 32-byte signed integers. Maps to "int[]" type in Java.
+                 *
+                 * @param res Array to store data to.
+                 * @param len Expected length of array.                 
+                 * @return Actual amount of elements read. If "len" argument is less than actual
+                 *     array size or resulting array is set to null, nothing will be written
+                 *     to resulting array and returned value will contain required array length.
+                 *     -1 will be returned in case array in stream was null.
+                 */
+                int32_t ReadInt32Array(int32_t* res, const int32_t len);
+
+                /**
+                 * Read 32-byte signed integer. Maps to "int" type in Java.
+                 *
+                 * @param fieldName Field name.
+                 * @return Result.
+                 */
+                int32_t ReadInt32(const char* fieldName);
+
+                /**
+                 * Read array of 32-byte signed integers. Maps to "int[]" type in Java.
+                 *
+                 * @param fieldName Field name.
+                 * @param res Array to store data to.
+                 * @param len Expected length of array.                 
+                 * @return Actual amount of elements read. If "len" argument is less than actual
+                 *     array size or resulting array is set to null, nothing will be written
+                 *     to resulting array and returned value will contain required array length.
+                 *     -1 will be returned in case array in stream was null.
+                 */
+                int32_t ReadInt32Array(const char* fieldName, int32_t* res, const int32_t len);
+
+                /**
+                 * Read 64-byte signed integer. Maps to "long" type in Java.
+                 *
+                 * @return Result.
+                 */
+                int64_t ReadInt64();
+
+                /**
+                 * Read array of 64-byte signed integers. Maps to "long[]" type in Java.
+                 *
+                 * @param res Array to store data to.
+                 * @param len Expected length of array.                 
+                 * @return Actual amount of elements read. If "len" argument is less than actual
+                 *     array size or resulting array is set to null, nothing will be written
+                 *     to resulting array and returned value will contain required array length.
+                 *     -1 will be returned in case array in stream was null.
+                 */
+                int32_t ReadInt64Array(int64_t* res, const int32_t len);
+
+                /**
+                 * Read 64-byte signed integer. Maps to "long" type in Java.
+                 *
+                 * @param fieldName Field name.
+                 * @return Result.
+                 */
+                int64_t ReadInt64(const char* fieldName);
+
+                /**
+                 * Read array of 64-byte signed integers. Maps to "long[]" type in Java.
+                 *
+                 * @param fieldName Field name.
+                 * @param res Array to store data to.
+                 * @param len Expected length of array.                 
+                 * @return Actual amount of elements read. If "len" argument is less than actual
+                 *     array size or resulting array is set to null, nothing will be written
+                 *     to resulting array and returned value will contain required array length.
+                 *     -1 will be returned in case array in stream was null.
+                 */
+                int32_t ReadInt64Array(const char* fieldName, int64_t* res, const int32_t len);
+
+                /**
+                 * Read float. Maps to "float" type in Java.
+                 *
+                 * @return Result.
+                 */
+                float ReadFloat();
+
+                /**
+                 * Read float array. Maps to "float[]" type in Java.
+                 *
+                 * @param res Array to store data to.
+                 * @param len Expected length of array.                 
+                 * @return Actual amount of elements read. If "len" argument is less than actual
+                 *     array size or resulting array is set to null, nothing will be written
+                 *     to resulting array and returned value will contain required array length.
+                 *     -1 will be returned in case array in stream was null.
+                 */
+                int32_t ReadFloatArray(float* res, const int32_t len);
+
+                /**
+                 * Read float. Maps to "float" type in Java.
+                 *
+                 * @param fieldName Field name.
+                 * @return Result.
+                 */
+                float ReadFloat(const char* fieldName);
+
+                /**
+                 * Read float array. Maps to "float[]" type in Java.
+                 *
+                 * @param fieldName Field name.
+                 * @param res Array to store data to.
+                 * @param len Expected length of array.                 
+                 * @return Actual amount of elements read. If "len" argument is less than actual
+                 *     array size or resulting array is set to null, nothing will be written
+                 *     to resulting array and returned value will contain required array length.
+                 *     -1 will be returned in case array in stream was null.
+                 */
+                int32_t ReadFloatArray(const char* fieldName, float* res, const int32_t len);
+
+                /**
+                 * Read double. Maps to "double" type in Java.
+                 *
+                 * @return Result.
+                 */
+                double ReadDouble();
+                
+                /**
+                 * Read double array. Maps to "double[]" type in Java.
+                 *
+                 * @param res Array to store data to.
+                 * @param len Expected length of array.                 
+                 * @return Actual amount of elements read. If "len" argument is less than actual
+                 *     array size or resulting array is set to null, nothing will be written
+                 *     to resulting array and returned value will contain required array length.
+                 *     -1 will be returned in case array in stream was null.
+                 */
+                int32_t ReadDoubleArray(double* res, const int32_t len);
+
+                /**
+                 * Read double. Maps to "double" type in Java.
+                 *
+                 * @param fieldName Field name.
+                 * @return Result.
+                 */
+                double ReadDouble(const char* fieldName);
+
+                /**
+                 * Read double array. Maps to "double[]" type in Java.
+                 *
+                 * @param fieldName Field name.
+                 * @param res Array to store data to.
+                 * @param len Expected length of array.                 
+                 * @return Actual amount of elements read. If "len" argument is less than actual
+                 *     array size or resulting array is set to null, nothing will be written
+                 *     to resulting array and returned value will contain required array length.
+                 *     -1 will be returned in case array in stream was null.
+                 */
+                int32_t ReadDoubleArray(const char* fieldName, double* res, const int32_t len);
+
+                /**
+                 * Read Guid. Maps to "UUID" type in Java.
+                 *
+                 * @return Result.
+                 */
+                Guid ReadGuid();
+
+                /**
+                 * Read array of Guids. Maps to "UUID[]" type in Java.
+                 *
+                 * @param res Array to store data to.
+                 * @param len Expected length of array.                 
+                 * @return Actual amount of elements read. If "len" argument is less than actual
+                 *     array size or resulting array is set to null, nothing will be written
+                 *     to resulting array and returned value will contain required array length.
+                 *     -1 will be returned in case array in stream was null.
+                 */
+                int32_t ReadGuidArray(Guid* res, const int32_t len);
+
+                /**
+                 * Read Guid. Maps to "UUID" type in Java.
+                 *
+                 * @param fieldName Field name.
+                 * @return Result.
+                 */
+                Guid ReadGuid(const char* fieldName);
+
+                /**
+                 * Read array of Guids. Maps to "UUID[]" type in Java.
+                 *
+                 * @param fieldName Field name.
+                 * @param res Array to store data to.
+                 * @param len Expected length of array.                 
+                 * @return Actual amount of elements read. If "len" argument is less than actual
+                 *     array size or resulting array is set to null, nothing will be written
+                 *     to resulting array and returned value will contain required array length.
+                 *     -1 will be returned in case array in stream was null.
+                 */
+                int32_t ReadGuidArray(const char* fieldName, Guid* res, const int32_t len);
+
+                /**
+                 * Read string.
+                 *
+                 * @param len Expected length of string.
+                 * @param res Array to store data to (should be able to acocmodate null-terminator).
+                 * @return Actual amount of elements read. If "len" argument is less than actual
+                 *     array size or resulting array is set to null, nothing will be written
+                 *     to resulting array and returned value will contain required array length.
+                 *     -1 will be returned in case array in stream was null.
+                 */
+                int32_t ReadString(char* res, const int32_t len);
+
+                /**
+                 * Read string.
+                 *
+                 * @param fieldName Field name.                 
+                 * @param res Array to store data to (should be able to acocmodate null-terminator).
+                 * @param len Expected length of string.
+                 * @return Actual amount of elements read. If "len" argument is less than actual
+                 *     array size or resulting array is set to null, nothing will be written
+                 *     to resulting array and returned value will contain required array length.
+                 *     -1 will be returned in case array in stream was null.
+                 */
+                int32_t ReadString(const char* fieldName, char* res, const int32_t len);
+                
+                /**
+                 * Start string array read.
+                 *
+                 * @param size Array size.
+                 * @return Read session ID.
+                 */
+                int32_t ReadStringArray(int32_t* size);
+
+                /**
+                 * Start string array read.
+                 *
+                 * @param fieldName Field name.
+                 * @param size Array size.
+                 * @return Read session ID.
+                 */
+                int32_t ReadStringArray(const char* fieldName, int32_t* size);
+
+                /**
+                 * Read string element.
+                 *
+                 * @param id Session ID.
+                 * @param len Expected length of string.
+                 * @param res Array to store data to (should be able to acocmodate null-terminator).
+                 * @return Actual amount of elements read. If "len" argument is less than actual
+                 *     array size or resulting array is set to null, nothing will be written
+                 *     to resulting array and returned value will contain required array length.
+                 *     -1 will be returned in case array in stream was null.
+                 */
+                int32_t ReadStringElement(int32_t id, char* res, const int32_t len);
+
+                /**
+                 * Start array read.
+                 *
+                 * @param size Array size.
+                 * @return Read session ID.
+                 */
+                int32_t ReadArray(int32_t* size);
+
+                /**
+                 * Start array read.
+                 *
+                 * @param fieldName Field name.
+                 * @param size Array size.
+                 * @return Read session ID.
+                 */
+                int32_t ReadArray(const char* fieldName, int32_t* size);
+
+                /**
+                 * Start collection read.
+                 *
+                 * @param typ Collection type.
+                 * @param size Collection size.
+                 * @return Read session ID.
+                 */
+                int32_t ReadCollection(gridgain::portable::CollectionType* typ, int32_t* size);
+
+                /**
+                 * Start collection read.
+                 *
+                 * @param fieldName Field name.
+                 * @param typ Collection type.
+                 * @param size Collection size.
+                 * @return Read session ID.
+                 */
+                int32_t ReadCollection(const char* fieldName, gridgain::portable::CollectionType* typ, int32_t* size);
+
+                /**
+                 * Start map read.
+                 *
+                 * @param typ Map type.
+                 * @param size Map size.
+                 * @return Read session ID.
+                 */
+                int32_t ReadMap(gridgain::portable::MapType* typ, int32_t* size);
+
+                /**
+                 * Start map read.
+                 *
+                 * @param fieldName Field name.
+                 * @param typ Map type.
+                 * @param size Map size.
+                 * @return Read session ID.
+                 */
+                int32_t ReadMap(const char* fieldName, gridgain::portable::MapType* typ, int32_t* size);
+
+                /**
+                 * Check whether next value exists.
+                 *
+                 * @param id Session ID.
+                 * @return True if next element exists for the given session.
+                 */
+                bool HasNextElement(int32_t id);
+
+                /**
+                 * Read element.
+                 *
+                 * @param id Session ID.
+                 * @return Value.
+                 */
+                template<typename T>
+                T ReadElement(const int32_t id)
+                {
+                    CheckSession(id);
+
+                    if (++elemRead == elemCnt) {
+                        elemId = 0;
+                        elemCnt = -1;
+                        elemRead = 0;
+                    }
+
+                    return ReadTopObject<T>();
+                }
+
+                /**
+                 * Read element.
+                 *
+                 * @param id Session ID.
+                 * @param key Key.
+                 * @param val Value.
+                 */
+                template<typename K, typename V>
+                void ReadElement(const int32_t id, K* key, V* val)
+                {
+                    CheckSession(id);
+
+                    if (++elemRead == elemCnt) {
+                        elemId = 0;
+                        elemCnt = -1;
+                        elemRead = 0;
+                    }
+
+                    *key = ReadTopObject<K>();
+                    *val = ReadTopObject<V>();
+                }
+                
+                /**
+                 * Read object.
+                 *
+                 * @return Object.
+                 */
+                template<typename T>
+                T ReadObject()
+                {
+                    CheckRawMode(true);
+
+                    return ReadTopObject<T>();
+                }
+
+                /**
+                 * Read object.
+                 *
+                 * @param fieldName Field name.
+                 * @return Object.
+                 */
+                template<typename T>
+                T ReadObject(const char* fieldName)
+                {
+                    CheckRawMode(false);
+
+                    int32_t fieldId = idRslvr->GetFieldId(typeId, fieldName); 
+                        
+                    int32_t fieldLen = SeekField(fieldId); 
+                        
+                    if (fieldLen > 0) 
+                        return ReadTopObject<T>();
+                    
+                    return GetNull<T>();
+                }
+
+                /**
+                 * Set raw mode.
+                 */
+                void SetRawMode();
+
+                /**
+                 * Read object.
+                 *
+                 * @param obj Object to write.
+                 */
+                template<typename T>
+                T ReadTopObject()
+                {
+                    int32_t pos = stream->Position();
+                    int8_t hdr = stream->ReadInt8();
+
+                    if (hdr == GG_HDR_NULL)
+                        return GetNull<T>();
+                    else if (hdr == GG_HDR_HND) {
+                        GG_ERROR_1(gridgain::GridError::GG_ERR_PORTABLE, "Circular references are not supported.");
+                    }
+                    else if (hdr == GG_TYPE_PORTABLE)
+                    {
+                        int32_t portLen = stream->ReadInt32(); // Total length of portable object.
+                        int32_t curPos = stream->Position();
+                        int32_t portOff = stream->ReadInt32(curPos + portLen);
+
+                        stream->Position(curPos + portOff); // Position stream right on the object.
+
+                        T val = ReadTopObject<T>();
+
+                        stream->Position(curPos + portLen + 4); // Position stream after portable.
+
+                        return val;
+                    }
+                    else
+                    {
+                        bool usrType = stream->ReadBool();
+                        int32_t typeId = stream->ReadInt32();
+                        int32_t hashCode = stream->ReadInt32();
+                        int32_t len = stream->ReadInt32();
+                        int32_t rawOff = stream->ReadInt32();
+
+                        gridgain::portable::PortableType<T> type;
+                        TemplatedPortableIdResolver<T> idRslvr(type);
+                        PortableReaderImpl readerImpl(stream, &idRslvr, pos, usrType, typeId, hashCode, len, rawOff);
+                        gridgain::portable::PortableReader reader(&readerImpl);
+
+                        T val = type.Read(reader);
+
+                        stream->Position(pos + len);
+
+                        return val;
+                    }
+                }
+
+                /**
+                 * Get NULL value for the given type.
+                 */
+                template<typename T>
+                T GetNull()
+                {
+                    gridgain::portable::PortableType<T> type;
+
+                    return type.GetNull();
+                }
+
+                /**
+                 * Get underlying stream.
+                 *
+                 * @return Stream.
+                 */
+                impl::interop::InteropInputStream* GetStream();
+            private:
+                /** Underlying stream. */
+                interop::InteropInputStream* stream;   
+                
+                /** ID resolver. */
+                PortableIdResolver* idRslvr;           
+
+                /** Position in the stream where this object starts. */
+                int32_t pos;       
+                
+                /** Whether this is user type or system type. */
+                bool usrType;      
+                
+                /** Type ID as defined in the stream. */
+                int32_t typeId;    
+                
+                /** Hash code. */
+                int32_t hashCode;  
+                
+                /** Total object length in the stream. */
+                int32_t len;       
+                
+                /** Raw data offset. */
+                int32_t rawOff;    
+
+                /** Raw mode flag. */
+                bool rawMode;      
+
+                /** Elements read session ID generator. */
+                int32_t elemIdGen; 
+                
+                /** Elements read session ID. */
+                int32_t elemId;    
+                
+                /** Total amount of elements in collection. */
+                int32_t elemCnt;   
+                
+                /** Amount of elements read. */
+                int32_t elemRead;  
+
+                IGNITE_NO_COPY_ASSIGNMENT(PortableReaderImpl)
+
+                /**
+                 * Internal routine to read Guid array.
+                 *
+                 * @param stream Stream.
+                 * @param res Resulting array.
+                 * @param len Length.
+                 */
+                static void ReadGuidArrayInternal(
+                    interop::InteropInputStream* stream, 
+                    Guid* res,
+                    const int32_t len
+                );
+
+                /**
+                 * Read single value in raw mode.
+                 * 
+                 * @param stream Stream.
+                 * @param func Function to be invoked on stream.
+                 * @return Result.
+                 */
+                template<typename T>
+                T ReadRaw(
+                    T(*func) (interop::InteropInputStream*)
+                )
+                {
+                    {
+                        CheckRawMode(true);
+                        CheckSingleMode(true);
+
+                        return func(stream);
+                    }
+                }
+
+                /**
+                 * Read single value.
+                 *
+                 * @param fieldName Field name.
+                 * @param func Function to be invoked on stream.
+                 * @param epxHdr Expected header.
+                 * @param dflt Default value returned if field is not found.
+                 * @return Result.
+                 */
+                template<typename T>
+                T Read(
+                    const char* fieldName, 
+                    T(*func) (interop::InteropInputStream*), 
+                    const int8_t expHdr, 
+                    T dflt
+                )
+                {
+                    {
+                        CheckRawMode(false);
+                        CheckSingleMode(true);
+
+                        int32_t fieldId = idRslvr->GetFieldId(typeId, fieldName);
+                        int32_t fieldLen = SeekField(fieldId);
+
+                        if (fieldLen > 0)
+                        {
+                            int8_t typeId = stream->ReadInt8();
+
+                            if (typeId == expHdr)
+                                return func(stream);
+                            else if (typeId != GG_HDR_NULL)
+                            {
+                                int32_t pos = stream->Position();
+
+                                GG_ERROR_FORMATTED_3(GridError::GG_ERR_PORTABLE, "Invalid type ID", 
+                                    "position", pos, "expected", expHdr, "actual", typeId)
+                            }
+                        }
+
+                        return dflt;
+                    }
+                }
+
+                /**
+                 * Read array in raw mode.
+                 *
+                 * @param res Resulting array.
+                 * @param len Length.                 
+                 * @param func Function to be invoked on stream.
+                 * @param expHdr Expected header.
+                 * @return Length.
+                 */
+                template<typename T>
+                int32_t ReadRawArray(
+                    T* res,
+                    const int32_t len,
+                    void(*func)(interop::InteropInputStream*, T* const, const int32_t),
+                    const int8_t expHdr
+                )
+                {
+                    {
+                        CheckRawMode(true);
+                        CheckSingleMode(true);
+
+                        return ReadArrayInternal(res, len, stream, func, expHdr);
+                    }
+                }
+
+                /**
+                 * Read array.
+                 *
+                 * @param fieldName Field name.
+                 * @param res Resulting array.
+                 * @param len Length.
+                 * @param func Function to be invoked on stream.
+                 * @param expHdr Expected header.
+                 * @return Length.
+                 */
+                template<typename T>
+                int32_t ReadArray(
+                    const char* fieldName,
+                    T* res,
+                    const int32_t len,                    
+                    void(*func)(interop::InteropInputStream*, T* const, const int32_t),
+                    const int8_t expHdr
+                )
+                {
+                    {
+                        CheckRawMode(false);
+                        CheckSingleMode(true);
+
+                        int32_t pos = stream->Position();
+
+                        int32_t fieldId = idRslvr->GetFieldId(typeId, fieldName);
+                        int32_t fieldLen = SeekField(fieldId);
+
+                        if (fieldLen > 0) {
+                            int32_t realLen = ReadArrayInternal(res, len, stream, func, expHdr);
+
+                            // If actual read didn't occur return to initial position so that we do not perform 
+                            // N jumps to find the field again, where N is total amount of fields.
+                            if (realLen != -1 && (!res || realLen > len))
+                                stream->Position(pos);
+
+                            return realLen;
+                        }
+
+                        return -1;
+                    }
+                }
+
+                /**
+                 * Internal read array routine.
+                 *
+                 * @param res Resulting array.
+                 * @param len Length.                 
+                 * @param stream Stream.
+                 * @param func Function to be invoked on stream.
+                 * @param expHdr Expected header.
+                 * @return Length.
+                 */
+                template<typename T>
+                static int32_t ReadArrayInternal(
+                    T* res,
+                    const int32_t len,
+                    interop::InteropInputStream* stream,
+                    void(*func)(interop::InteropInputStream*, T* const, const int32_t),
+                    const int8_t expHdr
+                )
+                {
+                    {
+                        int8_t hdr = stream->ReadInt8();
+
+                        if (hdr == expHdr)
+                        {
+                            int32_t realLen = stream->ReadInt32();
+
+                            if (realLen == 0 || (res && len >= realLen))
+                                func(stream, res, realLen);
+                            else
+                                stream->Position(stream->Position() - 5);
+
+                            return realLen;
+                        }
+                        else if (hdr != GG_HDR_NULL)
+                            ThrowOnInvalidHeader(stream->Position() - 1, expHdr, hdr);
+
+                        return -1;
+                    }
+                }
+
+                /**
+                 * Read nullable value.
+                 *
+                 * @param stream Stream.
+                 * @param func Function to be invoked on stream.
+                 * @param expHdr Expected header.
+                 */
+                template<typename T>
+                static T ReadNullable(
+                    interop::InteropInputStream* stream,
+                    T(*func)(interop::InteropInputStream*), 
+                    const int8_t expHdr
+                )
+                {
+                    {
+                        int8_t hdr = stream->ReadInt8();
+
+                        if (hdr == expHdr)
+                            return func(stream);
+                        else if (hdr == GG_HDR_NULL)
+                            return Guid();
+                        else {
+                            ThrowOnInvalidHeader(stream->Position() - 1, expHdr, hdr);
+
+                            return Guid();
+                        }
+                    }
+                }
+
+                /**
+                 * Seek field with the given ID.
+                 *
+                 * @param fieldId Field ID.
+                 * @return Field length or -1 if field is not found.
+                 */
+                int32_t SeekField(const int32_t fieldId);
+
+                /**
+                 * Check raw mode.
+                 * 
+                 * @param expected Expected raw mode of the reader.
+                 */
+                void CheckRawMode(bool expected);
+
+                /**
+                 * Check whether reader is currently operating in single mode.
+                 *
+                 * @param expected Expected value.
+                 */
+                void CheckSingleMode(bool expected);
+
+                /**
+                 * Start new container reader session.
+                 *
+                 * @param expRawMode Expected raw mode.
+                 * @param expHdr Expected header.
+                 * @param size Container size.
+                 * @return Session ID.
+                 */
+                int32_t StartContainerSession(const bool expRawMode, const int8_t expHdr, int32_t* size);
+
+                /**
+                 * Check whether session ID matches.
+                 *
+                 * @param ses Expected session ID.
+                 */
+                void CheckSession(int32_t expSes);
+
+                /**
+                 * Throw an error due to invalid header.
+                 *
+                 * @param pos Position in the stream.
+                 * @param expHdr Expected header.
+                 * @param hdr Actual header.
+                 */
+                static void ThrowOnInvalidHeader(int32_t pos, int8_t expHdr, int8_t hdr);
+
+                /**
+                 * Throw an error due to invalid header.
+                 *
+                 * @param expHdr Expected header.
+                 * @param hdr Actual header.
+                 */
+                void ThrowOnInvalidHeader(int8_t expHdr, int8_t hdr);
+
+                /**
+                 * Internal string read routine.
+                 *
+                 * @param res Resulting array.
+                 * @param len Length of array.
+                 * @return Real array length.
+                 */
+                int32_t ReadStringInternal(char* res, const int32_t len);
+
+                /**
+                 * Read value.
+                 *
+                 * @param expHdr Expected header.
+                 * @param func Function to be applied to the stream.
+                 */
+                template<typename T>
+                T ReadTopObject0(const int8_t expHdr, T(*func) (gridgain::impl::interop::InteropInputStream*))
+                {
+                    int8_t typeId = stream->ReadInt8();
+
+                    if (typeId == expHdr)
+                        return func(stream);
+                    else if (typeId == GG_HDR_NULL)
+                        return GetNull<T>();
+                    else {
+                        int32_t pos = stream->Position() - 1;
+
+                        GG_ERROR_FORMATTED_3(GridError::GG_ERR_PORTABLE, "Invalid header", "position", pos, "expected", expHdr, "actual", typeId)
+                    }
+                }
+
+                /**
+                 * Read value.
+                 *
+                 * @param expHdr Expected header.
+                 * @param func Function to be applied to the stream.
+                 * @param dflt Default value.
+                 */
+                template<typename T>
+                T ReadTopObject0(const int8_t expHdr, T(*func) (gridgain::impl::interop::InteropInputStream*), T dflt)
+                {
+                    int8_t typeId = stream->ReadInt8();
+
+                    if (typeId == expHdr)
+                        return func(stream);
+                    else if (typeId == GG_HDR_NULL)
+                        return dflt;
+                    else {
+                        int32_t pos = stream->Position() - 1;
+
+                        GG_ERROR_FORMATTED_3(GridError::GG_ERR_PORTABLE, "Invalid header", "position", pos, "expected", expHdr, "actual", typeId)
+                    }
+                }
+            };
+
+            template<>
+            int8_t IGNITE_IMPORT_EXPORT PortableReaderImpl::ReadTopObject<int8_t>();
+
+            template<>
+            bool IGNITE_IMPORT_EXPORT PortableReaderImpl::ReadTopObject<bool>();
+
+            template<>
+            int16_t IGNITE_IMPORT_EXPORT PortableReaderImpl::ReadTopObject<int16_t>();
+
+            template<>
+            uint16_t IGNITE_IMPORT_EXPORT PortableReaderImpl::ReadTopObject<uint16_t>();
+
+            template<>
+            int32_t IGNITE_IMPORT_EXPORT PortableReaderImpl::ReadTopObject<int32_t>();
+
+            template<>
+            int64_t IGNITE_IMPORT_EXPORT PortableReaderImpl::ReadTopObject<int64_t>();
+
+            template<>
+            float IGNITE_IMPORT_EXPORT PortableReaderImpl::ReadTopObject<float>();
+
+            template<>
+            double IGNITE_IMPORT_EXPORT PortableReaderImpl::ReadTopObject<double>();
+
+            
+            template<>
+            Guid IGNITE_IMPORT_EXPORT PortableReaderImpl::ReadTopObject<Guid>();
+
+            template<>
+            inline std::string IGNITE_IMPORT_EXPORT PortableReaderImpl::ReadTopObject<std::string>()
+            {
+                int8_t typeId = stream->ReadInt8();
+
+                if (typeId == GG_TYPE_STRING)
+                {
+                    bool utf8Mode = stream->ReadBool();
+                    int32_t realLen = stream->ReadInt32();
+
+                    gridgain::impl::utils::SafeArray<char> arr(realLen + 1);
+
+                    if (utf8Mode)
+                    {
+                        for (int i = 0; i < realLen; i++)
+                            *(arr.target + i) = static_cast<char>(stream->ReadInt8());
+                    }
+                    else
+                    {
+                        for (int i = 0; i < realLen; i++)
+                            *(arr.target + i) = static_cast<char>(stream->ReadUInt16());
+                    }
+
+                    *(arr.target + realLen) = 0;
+
+                    return std::string(arr.target);
+                }
+
+                else if (typeId == GG_HDR_NULL)
+                    return std::string();
+                else {
+                    int32_t pos = stream->Position() - 1;
+
+                    GG_ERROR_FORMATTED_3(GridError::GG_ERR_PORTABLE, "Invalid header", "position", pos, "expected", GG_TYPE_STRING, "actual", typeId)
+                }
+            }
+        }
+    }
+}
+
+#endif
\ No newline at end of file