http://git-wip-us.apache.org/repos/asf/geode-native/blob/6cbd424f/clicache/src/impl/ManagedCacheLoader.hpp ---------------------------------------------------------------------- diff --git a/clicache/src/impl/ManagedCacheLoader.hpp b/clicache/src/impl/ManagedCacheLoader.hpp new file mode 100644 index 0000000..4d09d49 --- /dev/null +++ b/clicache/src/impl/ManagedCacheLoader.hpp @@ -0,0 +1,160 @@ +/* + * 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. + */ + +#pragma once + +#include "../geode_defs.hpp" +#include <vcclr.h> +#include "begin_native.hpp" +#include <geode/CacheLoader.hpp> +#include "end_native.hpp" + + +#include "../ICacheLoader.hpp" +#include "CacheLoader.hpp" + +namespace apache +{ + namespace geode + { + namespace client + { + + /// <summary> + /// Wraps the managed <see cref="Apache.Geode.Client.ICacheLoader" /> + /// object and implements the native <c>apache::geode::client::CacheLoader</c> interface. + /// </summary> + class ManagedCacheLoaderGeneric + : public apache::geode::client::CacheLoader + { + public: + + /// <summary> + /// Constructor to initialize with the provided managed object. + /// </summary> + /// <param name="userptr"> + /// The managed object. + /// </param> + inline ManagedCacheLoaderGeneric( + /*Generic::ICacheLoader<Object^, Object^>^ managedptr,*/ Object^ userptr) + : /*m_managedptr( managedptr ),*/ m_userptr(userptr) { } + + /// <summary> + /// Static function to create a <c>ManagedCacheLoader</c> using given + /// managed assembly path and given factory function. + /// </summary> + /// <param name="assemblyPath"> + /// The path of the managed assembly that contains the <c>ICacheLoader</c> + /// factory function. + /// </param> + /// <param name="factoryFunctionName"> + /// The name of the factory function of the managed class for creating + /// an object that implements <c>ICacheLoader</c>. + /// This should be a static function of the format + /// {Namespace}.{Class Name}.{Method Name}. + /// </param> + /// <exception cref="IllegalArgumentException"> + /// If the managed library cannot be loaded or the factory function fails. + /// </exception> + static apache::geode::client::CacheLoader* create(const char* assemblyPath, + const char* factoryFunctionName); + + virtual ~ManagedCacheLoaderGeneric() { } + + /// <summary> + /// Loads a value. Application writers should implement this + /// method to customize the loading of a value. + /// </summary> + /// <remarks> + /// This method is called by the caching service when the requested + /// value is not in the cache. Any exception thrown by this method + /// is propagated back to and thrown by the invocation of + /// <see cref="Apache.Geode.Client.Region.Get" /> that triggered this load. + /// </remarks> + /// <param name="region">a Region Pointer for which this is called.</param> + /// <param name="key">the key for the cacheable</param> + /// <param name="aCallbackArgument">any related user data, or null</param> + /// <returns> + /// the value supplied for this key, or null if no value can be + /// supplied. + /// If every available loader returns + /// a null value, <see cref="Apache.Geode.Client.Region.Get" /> + /// will return null. + /// </returns> + /// <seealso cref="Apache.Geode.Client.Region.Get" /> + virtual CacheablePtr load(const RegionPtr& region, + const CacheableKeyPtr& key, const UserDataPtr& aCallbackArgument); + + /// <summary> + /// Called when the region containing this callback is destroyed, when + /// the cache is closed. + /// </summary> + /// <remarks> + /// Implementations should clean up any external + /// resources, such as database connections. Any runtime exceptions this method + /// throws will be logged. + /// <para> + /// It is possible for this method to be called multiple times on a single + /// callback instance, so implementations must be tolerant of this. + /// </para> + /// </remarks> + /// <param name="region">the region pointer</param> + /// <seealso cref="Apache.Geode.Client.Cache.Close" /> + /// <seealso cref="Apache.Geode.Client.Region.DestroyRegion" /> + virtual void close(const RegionPtr& region); + + /* + /// <summary> + /// Returns the wrapped managed object reference. + /// </summary> + inline Apache::Geode::Client::ICacheLoader^ ptr( ) const + { + return m_managedptr; + } + */ + + inline void setptr(Apache::Geode::Client::ICacheLoaderProxy^ managedptr) + { + m_managedptr = managedptr; + } + + inline Object^ userptr() const + { + return m_userptr; + } + + + private: + + /// <summary> + /// Using gcroot to hold the managed delegate pointer (since it cannot be stored directly). + /// Note: not using auto_gcroot since it will result in 'Dispose' of the ICacheLoader + /// to be called which is not what is desired when this object is destroyed. Normally this + /// managed object may be created by the user and will be handled automatically by the GC. + /// </summary> + gcroot<Apache::Geode::Client::ICacheLoaderProxy^> m_managedptr; + + gcroot<Object^> m_userptr; + + // Disable the copy and assignment constructors + ManagedCacheLoaderGeneric(const ManagedCacheLoaderGeneric&); + ManagedCacheLoaderGeneric& operator = (const ManagedCacheLoaderGeneric&); + }; + + } // namespace client + } // namespace geode +} // namespace apache
http://git-wip-us.apache.org/repos/asf/geode-native/blob/6cbd424f/clicache/src/impl/ManagedCacheWriter.cpp ---------------------------------------------------------------------- diff --git a/clicache/src/impl/ManagedCacheWriter.cpp b/clicache/src/impl/ManagedCacheWriter.cpp new file mode 100644 index 0000000..646cf7e --- /dev/null +++ b/clicache/src/impl/ManagedCacheWriter.cpp @@ -0,0 +1,316 @@ +/* + * 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 "../geode_includes.hpp" +#include "ManagedCacheWriter.hpp" +#include "../ICacheWriter.hpp" +#include "../Region.hpp" +#include "../RegionEvent.hpp" +#include "../EntryEvent.hpp" +#include "../Log.hpp" +#include "ManagedString.hpp" +#include "../ExceptionTypes.hpp" +#include "SafeConvert.hpp" +#include "CacheWriter.hpp" + +using namespace System; +using namespace System::Text; +using namespace System::Reflection; + +namespace apache +{ + namespace geode + { + namespace client + { + + CacheWriter* ManagedCacheWriterGeneric::create(const char* assemblyPath, + const char* factoryFunctionName) + { + try + { + String^ mg_assemblyPath = + Apache::Geode::Client::ManagedString::Get(assemblyPath); + String^ mg_factoryFunctionName = + Apache::Geode::Client::ManagedString::Get(factoryFunctionName); + String^ mg_typeName = nullptr; + + String^ mg_genericKey = nullptr; + String^ mg_genericVal = nullptr; + + System::Int32 dotIndx = -1; + System::Int32 genericsOpenIndx = -1; + System::Int32 genericsCloseIndx = -1; + System::Int32 commaIndx = -1; + + if (mg_factoryFunctionName == nullptr || + (dotIndx = mg_factoryFunctionName->LastIndexOf('.')) < 0) + { + std::string ex_str = "ManagedCacheWriterGeneric: Factory function name '"; + ex_str += factoryFunctionName; + ex_str += "' does not contain type name"; + throw IllegalArgumentException(ex_str.c_str()); + } + + if ((genericsCloseIndx = mg_factoryFunctionName->LastIndexOf('>')) < 0) + { + std::string ex_str = "ManagedCacheWriterGeneric: Factory function name '"; + ex_str += factoryFunctionName; + ex_str += "' does not contain any generic type parameters"; + throw apache::geode::client::IllegalArgumentException(ex_str.c_str()); + } + + if ((genericsOpenIndx = mg_factoryFunctionName->LastIndexOf('<')) < 0 || + genericsOpenIndx > genericsCloseIndx) + { + std::string ex_str = "ManagedCacheWriterGeneric: Factory function name '"; + ex_str += factoryFunctionName; + ex_str += "' does not contain expected generic type parameters"; + throw apache::geode::client::IllegalArgumentException(ex_str.c_str()); + } + + if ((commaIndx = mg_factoryFunctionName->LastIndexOf(',')) < 0 || + (commaIndx < genericsOpenIndx || commaIndx > genericsCloseIndx)) + { + std::string ex_str = "ManagedCacheWriterGeneric: Factory function name '"; + ex_str += factoryFunctionName; + ex_str += "' does not contain expected generic type parameter comma separator"; + throw apache::geode::client::IllegalArgumentException(ex_str.c_str()); + } + + StringBuilder^ typeBuilder = gcnew StringBuilder(mg_factoryFunctionName->Substring(0, genericsOpenIndx)); + mg_typeName = typeBuilder->ToString(); + mg_genericKey = mg_factoryFunctionName->Substring(genericsOpenIndx + 1, commaIndx - genericsOpenIndx - 1); + mg_genericKey = mg_genericKey->Trim(); + mg_genericVal = mg_factoryFunctionName->Substring(commaIndx + 1, genericsCloseIndx - commaIndx - 1); + mg_genericVal = mg_genericVal->Trim(); + mg_factoryFunctionName = mg_factoryFunctionName->Substring(dotIndx + 1); + + Apache::Geode::Client::Log::Fine( + "Attempting to instantiate a [{0}<{1}, {2}>] via the [{3}] factory method.", + mg_typeName, mg_genericKey, mg_genericVal, mg_factoryFunctionName); + + typeBuilder->Append("`2"); + mg_typeName = typeBuilder->ToString(); + + Assembly^ assmb = nullptr; + try + { + assmb = Assembly::Load(mg_assemblyPath); + } + catch (System::Exception^) + { + assmb = nullptr; + } + if (assmb == nullptr) + { + std::string ex_str = "ManagedCacheWriterGeneric: Could not load assembly: "; + ex_str += assemblyPath; + throw IllegalArgumentException(ex_str.c_str()); + } + + Apache::Geode::Client::Log::Debug("Loading type: [{0}]", mg_typeName); + + Type^ typeInst = assmb->GetType(mg_typeName, false, true); + + if (typeInst != nullptr) + { + array<Type^>^ types = gcnew array<Type^>(2); + types[0] = Type::GetType(mg_genericKey, false, true); + types[1] = Type::GetType(mg_genericVal, false, true); + + if (types[0] == nullptr || types[1] == nullptr) + { + std::string ex_str = "ManagedCacheWriterGeneric: Could not get both generic type argument instances"; + throw apache::geode::client::IllegalArgumentException(ex_str.c_str()); + } + + typeInst = typeInst->MakeGenericType(types); + Apache::Geode::Client::Log::Info("Loading function: [{0}]", mg_factoryFunctionName); + + MethodInfo^ mInfo = typeInst->GetMethod(mg_factoryFunctionName, + BindingFlags::Public | BindingFlags::Static | BindingFlags::IgnoreCase); + if (mInfo != nullptr) + { + Object^ managedptr = nullptr; + try + { + managedptr = mInfo->Invoke(typeInst, nullptr); + } + catch (System::Exception^ ex) + { + Apache::Geode::Client::Log::Debug("{0}: {1}", ex->GetType()->Name, ex->Message); + managedptr = nullptr; + } + if (managedptr == nullptr) + { + std::string ex_str = "ManagedCacheWriterGeneric: Could not create " + "object on invoking factory function ["; + ex_str += factoryFunctionName; + ex_str += "] in assembly: "; + ex_str += assemblyPath; + throw IllegalArgumentException(ex_str.c_str()); + } + ManagedCacheWriterGeneric* mgcw = new ManagedCacheWriterGeneric(managedptr); + + Type^ cwgType = Type::GetType("Apache.Geode.Client.CacheWriterGeneric`2"); + cwgType = cwgType->MakeGenericType(types); + Object^ cwg = Activator::CreateInstance(cwgType); + + mInfo = cwgType->GetMethod("SetCacheWriter"); + array<Object^>^ params = gcnew array<Object^>(1); + params[0] = managedptr; + mInfo->Invoke(cwg, params); + + mgcw->setptr((Apache::Geode::Client::ICacheWriter<Object^, Object^>^)cwg); + + return mgcw; + } + else + { + std::string ex_str = "ManagedCacheWriterGeneric: Could not load " + "function with name ["; + ex_str += factoryFunctionName; + ex_str += "] in assembly: "; + ex_str += assemblyPath; + throw IllegalArgumentException(ex_str.c_str()); + } + } + else + { + Apache::Geode::Client::ManagedString typeName(mg_typeName); + std::string ex_str = "ManagedCacheWriterGeneric: Could not load type ["; + ex_str += typeName.CharPtr; + ex_str += "] in assembly: "; + ex_str += assemblyPath; + throw IllegalArgumentException(ex_str.c_str()); + } + } + catch (const apache::geode::client::Exception&) + { + throw; + } + catch (System::Exception^ ex) + { + Apache::Geode::Client::ManagedString mg_exStr(ex->ToString()); + std::string ex_str = "ManagedCacheWriterGeneric: Got an exception while " + "loading managed library: "; + ex_str += mg_exStr.CharPtr; + throw IllegalArgumentException(ex_str.c_str()); + } + return NULL; + } + + bool ManagedCacheWriterGeneric::beforeUpdate(const EntryEvent& ev) + { + try { + Apache::Geode::Client::EntryEvent<Object^, Object^> mevent(&ev); + + return m_managedptr->BeforeUpdate(%mevent); + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + return false; + } + + bool ManagedCacheWriterGeneric::beforeCreate(const EntryEvent& ev) + { + try { + Apache::Geode::Client::EntryEvent<Object^, Object^> mevent(&ev); + + return m_managedptr->BeforeCreate(%mevent); + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + return false; + } + + bool ManagedCacheWriterGeneric::beforeDestroy(const EntryEvent& ev) + { + try { + Apache::Geode::Client::EntryEvent<Object^, Object^> mevent(&ev); + + return m_managedptr->BeforeDestroy(%mevent); + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + return false; + } + bool ManagedCacheWriterGeneric::beforeRegionClear(const RegionEvent& ev) + { + try { + Apache::Geode::Client::RegionEvent<Object^, Object^> mevent(&ev); + + return m_managedptr->BeforeRegionClear(%mevent); + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + return false; + } + + bool ManagedCacheWriterGeneric::beforeRegionDestroy(const RegionEvent& ev) + { + try { + Apache::Geode::Client::RegionEvent<Object^, Object^> mevent(&ev); + + return m_managedptr->BeforeRegionDestroy(%mevent); + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + return false; + } + + void ManagedCacheWriterGeneric::close(const RegionPtr& rp) + { + try { + Apache::Geode::Client::IRegion<Object^, Object^>^ mregion = + Apache::Geode::Client::Region<Object^, Object^>::Create(rp); + + m_managedptr->Close(reinterpret_cast<Apache::Geode::Client::Region<Object^, Object^>^>(mregion)); + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + } + + } // namespace client + } // namespace geode +} // namespace apache + http://git-wip-us.apache.org/repos/asf/geode-native/blob/6cbd424f/clicache/src/impl/ManagedCacheWriter.hpp ---------------------------------------------------------------------- diff --git a/clicache/src/impl/ManagedCacheWriter.hpp b/clicache/src/impl/ManagedCacheWriter.hpp new file mode 100644 index 0000000..0b6eba1 --- /dev/null +++ b/clicache/src/impl/ManagedCacheWriter.hpp @@ -0,0 +1,191 @@ +/* + * 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. + */ + +#pragma once + +#include "../geode_defs.hpp" +#include <vcclr.h> +#include "begin_native.hpp" +#include <geode/CacheWriter.hpp> +#include "end_native.hpp" + +#include "../ICacheWriter.hpp" + +using namespace System; + +namespace apache +{ + namespace geode + { + namespace client + { + + /// <summary> + /// Wraps the managed <see cref="Apache.Geode.Client.ICacheWriter" /> + /// object and implements the native <c>apache::geode::client::CacheWriter</c> interface. + /// </summary> + class ManagedCacheWriterGeneric + : public CacheWriter + { + public: + + /// <summary> + /// Constructor to initialize with the provided managed object. + /// </summary> + /// <param name="userptr"> + /// The managed object. + /// </param> + inline ManagedCacheWriterGeneric(Object^ userptr) : m_userptr(userptr) { } + + /// <summary> + /// Static function to create a <c>ManagedCacheWriter</c> using given + /// managed assembly path and given factory function. + /// </summary> + /// <param name="assemblyPath"> + /// The path of the managed assembly that contains the <c>ICacheWriter</c> + /// factory function. + /// </param> + /// <param name="factoryFunctionName"> + /// The name of the factory function of the managed class for creating + /// an object that implements <c>ICacheWriter</c>. + /// This should be a static function of the format + /// {Namespace}.{Class Name}.{Method Name}. + /// </param> + /// <exception cref="IllegalArgumentException"> + /// If the managed library cannot be loaded or the factory function fails. + /// </exception> + static CacheWriter* create(const char* assemblyPath, + const char* factoryFunctionName); + + virtual ~ManagedCacheWriterGeneric() { } + + /// <summary> + /// Called before an entry is updated. The entry update is initiated by a + /// <c>put</c> or a <c>get</c> that causes the loader to update an existing entry. + /// </summary> + /// <remarks> + /// The entry previously existed in the cache where the operation was + /// initiated, although the old value may have been null. The entry being + /// updated may or may not exist in the local cache where the CacheWriter is + /// installed. + /// </remarks> + /// <param name="ev"> + /// EntryEvent denotes the event object associated with updating the entry + /// </param> + /// <seealso cref="Apache.Geode.Client.Region.Put" /> + /// <seealso cref="Apache.Geode.Client.Region.Get" /> + bool beforeUpdate(const EntryEvent& ev); + + /// <summary> + /// Called before an entry is created. Entry creation is initiated by a + /// <c>create</c>, a <c>put</c>, or a <c>get</c>. + /// </summary> + /// <remarks> + /// The <c>CacheWriter</c> can determine whether this value comes from a + /// <c>get</c> or not from <c>load</c>. The entry being created may already + /// exist in the local cache where this <c>CacheWriter</c> is installed, + /// but it does not yet exist in the cache where the operation was initiated. + /// </remarks> + /// <param name="ev"> + /// EntryEvent denotes the event object associated with creating the entry + /// </param> + /// <seealso cref="Apache.Geode.Client.Region.Create" /> + /// <seealso cref="Apache.Geode.Client.Region.Put" /> + /// <seealso cref="Apache.Geode.Client.Region.Get" /> + bool beforeCreate(const EntryEvent& ev); + + /// <summary> + /// Called before an entry is destroyed. + /// </summary> + /// <remarks> + /// The entry being destroyed may or may + /// not exist in the local cache where the CacheWriter is installed. This method + /// is <em>not</em> called as a result of expiration or + /// <see cref="Apache.Geode.Client.Region.LocalDestroyRegion" />. + /// </remarks> + /// <param name="ev"> + /// EntryEvent denotes the event object associated with destroying the entry + /// </param> + /// <seealso cref="Apache.Geode.Client.Region.Destroy" /> + bool beforeDestroy(const EntryEvent& ev); + + /// <summary> + /// called before this region is cleared + /// </summary> + bool beforeRegionClear(const RegionEvent& ev); + + /// <summary> + /// called before this region is destroyed + /// </summary> + /// <param name="ev"> + /// RegionEvent denotes the event object associated with destroying the region + /// </param> + /// <seealso cref="Apache.Geode.Client.Region.DestroyRegion" /> + bool beforeRegionDestroy(const RegionEvent& ev); + + /// <summary> + /// Called when the region containing this callback is destroyed, when + /// the cache is closed. + /// </summary> + /// <remarks> + /// Implementations should clean up any external + /// resources, such as database connections. Any runtime exceptions this method + /// throws will be logged. + /// <para> + /// It is possible for this method to be called multiple times on a single + /// callback instance, so implementations must be tolerant of this. + /// </para> + /// </remarks> + /// <seealso cref="Apache.Geode.Client.Cache.Close" /> + /// <seealso cref="Apache.Geode.Client.Region.DestroyRegion" /> + void close(const RegionPtr& rp); + + /// <summary> + /// Returns the wrapped managed object reference. + /// </summary> + inline Apache::Geode::Client::ICacheWriter<Object^, Object^>^ ptr() const + { + return m_managedptr; + } + + inline void setptr(Apache::Geode::Client::ICacheWriter<Object^, Object^>^ managedptr) + { + m_managedptr = managedptr; + } + + inline Object^ userptr() const + { + return m_userptr; + } + + + private: + + /// <summary> + /// Using gcroot to hold the managed delegate pointer (since it cannot be stored directly). + /// Note: not using auto_gcroot since it will result in 'Dispose' of the ICacheWriter + /// to be called which is not what is desired when this object is destroyed. Normally this + /// managed object may be created by the user and will be handled automatically by the GC. + /// </summary> + gcroot<Apache::Geode::Client::ICacheWriter<Object^, Object^>^> m_managedptr; + + gcroot<Object^> m_userptr; + }; + + } // namespace client + } // namespace geode +} // namespace apache http://git-wip-us.apache.org/repos/asf/geode-native/blob/6cbd424f/clicache/src/impl/ManagedCacheableDelta.cpp ---------------------------------------------------------------------- diff --git a/clicache/src/impl/ManagedCacheableDelta.cpp b/clicache/src/impl/ManagedCacheableDelta.cpp new file mode 100644 index 0000000..8c0c0d1 --- /dev/null +++ b/clicache/src/impl/ManagedCacheableDelta.cpp @@ -0,0 +1,282 @@ +/* + * 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 "begin_native.hpp" +#include <GeodeTypeIdsImpl.hpp> +#include "end_native.hpp" + +#include "ManagedCacheableDelta.hpp" +#include "../DataInput.hpp" +#include "../DataOutput.hpp" +#include "../CacheableString.hpp" +#include "../ExceptionTypes.hpp" +#include "SafeConvert.hpp" + + +using namespace System; + +namespace apache +{ + namespace geode + { + namespace client + { + + void ManagedCacheableDeltaGeneric::toData(DataOutput& output) const + { + try { + System::UInt32 pos = (int)output.getBufferLength(); + Apache::Geode::Client::DataOutput mg_output(&output, true); + m_managedSerializableptr->ToData(%mg_output); + //this will move the cursor in c++ layer + mg_output.WriteBytesToUMDataOutput(); + ManagedCacheableDeltaGeneric* tmp = const_cast<ManagedCacheableDeltaGeneric*>(this); + tmp->m_objectSize = (int)(output.getBufferLength() - pos); + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + } + + Serializable* ManagedCacheableDeltaGeneric::fromData(DataInput& input) + { + try { + int pos = input.getBytesRead(); + Apache::Geode::Client::DataInput mg_input(&input, true, input.getCache()); + m_managedSerializableptr->FromData(%mg_input); + + //this will move the cursor in c++ layer + input.advanceCursor(mg_input.BytesReadInternally); + + m_objectSize = input.getBytesRead() - pos; + + if (m_hashcode == 0) + m_hashcode = m_managedptr->GetHashCode(); + + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + return this; + } + + System::UInt32 ManagedCacheableDeltaGeneric::objectSize() const + { + try { + int ret = m_managedSerializableptr->ObjectSize; + if (ret > m_objectSize) + return ret; + else + return m_objectSize; + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + return 0; + } + + System::Int32 ManagedCacheableDeltaGeneric::classId() const + { + System::UInt32 classId; + try { + classId = m_managedSerializableptr->ClassId; + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + return (classId >= 0x80000000 ? 0 : classId); + } + + int8_t ManagedCacheableDeltaGeneric::typeId() const + { + try { + System::UInt32 classId = m_classId; + if (classId >= 0x80000000) { + return (int8_t)((classId - 0x80000000) % 0x20000000); + } + else if (classId <= 0x7F) { + return (int8_t)GeodeTypeIdsImpl::CacheableUserData; + } + else if (classId <= 0x7FFF) { + return (int8_t)GeodeTypeIdsImpl::CacheableUserData2; + } + else { + return (int8_t)GeodeTypeIdsImpl::CacheableUserData4; + } + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + return 0; + } + + int8_t ManagedCacheableDeltaGeneric::DSFID() const + { + // convention that [0x8000000, 0xa0000000) is for FixedIDDefault, + // [0xa000000, 0xc0000000) is for FixedIDByte, + // [0xc0000000, 0xe0000000) is for FixedIDShort + // and [0xe0000000, 0xffffffff] is for FixedIDInt + // Note: depends on fact that FixedIDByte is 1, FixedIDShort is 2 + // and FixedIDInt is 3; if this changes then correct this accordingly + System::UInt32 classId = m_managedSerializableptr->ClassId; + if (classId >= 0x80000000) { + return (int8_t)((classId - 0x80000000) / 0x20000000); + } + return 0; + } + + bool ManagedCacheableDeltaGeneric::hasDelta() + { + return m_managedptr->HasDelta(); + } + + void ManagedCacheableDeltaGeneric::toDelta(DataOutput& output) const + { + try { + Apache::Geode::Client::DataOutput mg_output(&output, true); + m_managedptr->ToDelta(%mg_output); + //this will move the cursor in c++ layer + mg_output.WriteBytesToUMDataOutput(); + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + } + + void ManagedCacheableDeltaGeneric::fromDelta(DataInput& input) + { + try { + Apache::Geode::Client::DataInput mg_input(&input, true, input.getCache()); + m_managedptr->FromDelta(%mg_input); + + //this will move the cursor in c++ layer + input.advanceCursor(mg_input.BytesReadInternally); + + m_hashcode = m_managedptr->GetHashCode(); + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + } + + DeltaPtr ManagedCacheableDeltaGeneric::clone() + { + try { + ICloneable^ cloneable = dynamic_cast<ICloneable^>(( + Apache::Geode::Client::IGeodeDelta^) m_managedptr); + if (cloneable) { + Apache::Geode::Client::IGeodeSerializable^ Mclone = + dynamic_cast<Apache::Geode::Client::IGeodeSerializable^>(cloneable->Clone()); + return DeltaPtr(static_cast<ManagedCacheableDeltaGeneric*>( + SafeMSerializableConvertGeneric(Mclone))); + } + else { + return Delta::clone(); + } + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + return nullptr; + } + + bool ManagedCacheableDeltaGeneric::operator ==(const apache::geode::client::CacheableKey& other) const + { + try { + // now checking classId(), typeId(), DSFID() etc. will be much more + // expensive than just a dynamic_cast + const ManagedCacheableDeltaGeneric* p_other = + dynamic_cast<const ManagedCacheableDeltaGeneric*>(&other); + if (p_other != NULL) { + return m_managedptr->Equals(p_other->ptr()); + } + return false; + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + return false; + } + + bool ManagedCacheableDeltaGeneric::operator == (const ManagedCacheableDeltaGeneric& other) const + { + try { + return m_managedptr->Equals(other.ptr()); + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + return false; + + } + + System::Int32 ManagedCacheableDeltaGeneric::hashcode() const + { + throw gcnew System::NotSupportedException; + } + + size_t ManagedCacheableDeltaGeneric::logString(char* buffer, size_t maxLength) const + { + try { + if (maxLength > 0) { + String^ logstr = m_managedptr->GetType()->Name + '(' + + m_managedptr->ToString() + ')'; + Apache::Geode::Client::ManagedString mg_str(logstr); + return snprintf(buffer, maxLength, "%s", mg_str.CharPtr); + } + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + return 0; + } + } // namespace client + } // namespace geode +} // namespace apache http://git-wip-us.apache.org/repos/asf/geode-native/blob/6cbd424f/clicache/src/impl/ManagedCacheableDelta.hpp ---------------------------------------------------------------------- diff --git a/clicache/src/impl/ManagedCacheableDelta.hpp b/clicache/src/impl/ManagedCacheableDelta.hpp new file mode 100644 index 0000000..9211a8d --- /dev/null +++ b/clicache/src/impl/ManagedCacheableDelta.hpp @@ -0,0 +1,189 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "../geode_defs.hpp" +#include <vcclr.h> +#include "begin_native.hpp" +#include <geode/Delta.hpp> +#include "end_native.hpp" + +#include "../IGeodeDelta.hpp" +#include "../IGeodeSerializable.hpp" + + +using namespace System; +//using namespace apache::geode::client; + +namespace Apache +{ + namespace Geode + { + namespace Client + { + + interface class IGeodeSerializable; + interface class IGeodeDelta; + } // namespace Client + } // namespace Geode +} // namespace Apache + + +namespace apache +{ + namespace geode + { + namespace client + { + + /// <summary> + /// Wraps the managed <see cref="Apache.Geode.Client.IGeodeDelta" /> + /// object and implements the native <c>apache::geode::client::CacheableKey</c> interface. + /// </summary> + class ManagedCacheableDeltaGeneric + : public apache::geode::client::CacheableKey, public apache::geode::client::Delta + { + private: + int m_hashcode; + int m_classId; + int m_objectSize; + public: + + /// <summary> + /// Constructor to initialize with the provided managed object. + /// </summary> + /// <param name="managedptr"> + /// The managed object. + /// </param> + inline ManagedCacheableDeltaGeneric( + Apache::Geode::Client::IGeodeDelta^ managedptr) + : Delta(nullptr), m_managedptr(managedptr) + { + m_managedSerializableptr = dynamic_cast <Apache::Geode::Client::IGeodeSerializable^> (managedptr); + m_classId = m_managedSerializableptr->ClassId; + m_objectSize = 0; + } + + inline ManagedCacheableDeltaGeneric( + Apache::Geode::Client::IGeodeDelta^ managedptr, int hashcode, int classId) + :Delta(nullptr), m_managedptr(managedptr) { + m_hashcode = hashcode; + m_classId = classId; + m_managedSerializableptr = dynamic_cast <Apache::Geode::Client::IGeodeSerializable^> (managedptr); + m_objectSize = 0; + } + + /// <summary> + /// serialize this object + /// </summary> + virtual void toData(apache::geode::client::DataOutput& output) const; + + /// <summary> + /// deserialize this object, typical implementation should return + /// the 'this' pointer. + /// </summary> + virtual apache::geode::client::Serializable* fromData(apache::geode::client::DataInput& input); + + virtual void toDelta(apache::geode::client::DataOutput& output) const; + + virtual void fromDelta(apache::geode::client::DataInput& input); + + /// <summary> + /// return the size of this object in bytes + /// </summary> + virtual System::UInt32 objectSize() const; + + /// <summary> + /// return the classId of the instance being serialized. + /// This is used by deserialization to determine what instance + /// type to create and deserialize into. + /// </summary> + virtual System::Int32 classId() const; + + /// <summary> + /// return the typeId of the instance being serialized. + /// This is used by deserialization to determine what instance + /// type to create and deserialize into. + /// </summary> + virtual int8_t typeId() const; + + /// <summary> + /// return the Data Serialization Fixed ID type. + /// This is used to determine what instance type to create + /// and deserialize into. + /// + /// Note that this should not be overridden by custom implementations + /// and is reserved only for builtin types. + /// </summary> + virtual int8_t DSFID() const; + + virtual bool hasDelta(); + + virtual apache::geode::client::DeltaPtr clone(); + + /// <summary> + /// return the hashcode for this key. + /// </summary> + virtual System::Int32 hashcode() const; + + /// <summary> + /// return true if this key matches other CacheableKey + /// </summary> + virtual bool operator == (const CacheableKey& other) const; + + /// <summary> + /// return true if this key matches other ManagedCacheableDeltaGeneric + /// </summary> + virtual bool operator == (const ManagedCacheableDeltaGeneric& other) const; + + /// <summary> + /// Copy the string form of a key into a char* buffer for logging purposes. + /// implementations should only generate a string as long as maxLength chars, + /// and return the number of chars written. buffer is expected to be large + /// enough to hold at least maxLength chars. + /// The default implementation renders the classname and instance address. + /// </summary> + virtual size_t logString(char* buffer, size_t maxLength) const; + + /// <summary> + /// Returns the wrapped managed object reference. + /// </summary> + inline Apache::Geode::Client::IGeodeDelta^ ptr() const + { + return m_managedptr; + } + + + private: + + /// <summary> + /// Using gcroot to hold the managed delegate pointer (since it cannot be stored directly). + /// Note: not using auto_gcroot since it will result in 'Dispose' of the IGeodeDelta + /// to be called which is not what is desired when this object is destroyed. Normally this + /// managed object may be created by the user and will be handled automatically by the GC. + /// </summary> + gcroot<Apache::Geode::Client::IGeodeDelta^> m_managedptr; + gcroot<Apache::Geode::Client::IGeodeSerializable^> m_managedSerializableptr; + // Disable the copy and assignment constructors + ManagedCacheableDeltaGeneric(const ManagedCacheableDeltaGeneric&); + ManagedCacheableDeltaGeneric& operator = (const ManagedCacheableDeltaGeneric&); + }; + + } // namespace client + } // namespace geode +} // namespace apache http://git-wip-us.apache.org/repos/asf/geode-native/blob/6cbd424f/clicache/src/impl/ManagedCacheableDeltaBytes.cpp ---------------------------------------------------------------------- diff --git a/clicache/src/impl/ManagedCacheableDeltaBytes.cpp b/clicache/src/impl/ManagedCacheableDeltaBytes.cpp new file mode 100644 index 0000000..18472c4 --- /dev/null +++ b/clicache/src/impl/ManagedCacheableDeltaBytes.cpp @@ -0,0 +1,337 @@ +/* + * 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 "begin_native.hpp" +#include <GeodeTypeIdsImpl.hpp> +#include "end_native.hpp" + +#include "ManagedCacheableDeltaBytes.hpp" +#include "../DataInput.hpp" +#include "../DataOutput.hpp" +#include "../CacheableString.hpp" +#include "../ExceptionTypes.hpp" +#include "SafeConvert.hpp" + + +using namespace System; + +namespace apache +{ + namespace geode + { + namespace client + { + + void ManagedCacheableDeltaBytesGeneric::toData(DataOutput& output) const + { + Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytesGeneric::toData: current domain ID: " + System::Threading::Thread::GetDomainID() + " for object: " + System::Convert::ToString((uint64_t) this) + " with its domain ID: " + m_domainId); + try { + output.writeBytesOnly(m_bytes, m_size); + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + } + + Serializable* ManagedCacheableDeltaBytesGeneric::fromData(DataInput& input) + { + try { + Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytes::fromData: classid " + m_classId); + Apache::Geode::Client::DataInput mg_input(&input, true, input.getCache()); + const System::Byte* objStartPos = input.currentBufferPosition(); + + Apache::Geode::Client::IGeodeSerializable^ obj = + Apache::Geode::Client::Serializable::GetTypeFactoryMethodGeneric(m_classId)(); + obj->FromData(%mg_input); + input.advanceCursor(mg_input.BytesReadInternally); + + m_hashCode = obj->GetHashCode(); + + const System::Byte* objEndPos = input.currentBufferPosition(); + + //m_size = mg_input.BytesRead; + m_size = (System::UInt32)(objEndPos - objStartPos); + Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytes::fromData: objectSize = " + m_size + " m_hashCode = " + m_hashCode); + m_bytes = input.getBufferCopyFrom(objStartPos, m_size); + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + return this; + } + + System::UInt32 ManagedCacheableDeltaBytesGeneric::objectSize() const + { + try { + return m_size; + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + return 0; + } + + System::Int32 ManagedCacheableDeltaBytesGeneric::classId() const + { + System::UInt32 classId; + try { + classId = m_classId; + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + return (classId >= 0x80000000 ? 0 : classId); + } + + int8_t ManagedCacheableDeltaBytesGeneric::typeId() const + { + try { + System::UInt32 classId = m_classId; + if (classId >= 0x80000000) { + return (int8_t)((classId - 0x80000000) % 0x20000000); + } + else if (classId <= 0x7F) { + return (int8_t)GeodeTypeIdsImpl::CacheableUserData; + } + else if (classId <= 0x7FFF) { + return (int8_t)GeodeTypeIdsImpl::CacheableUserData2; + } + else { + return (int8_t)GeodeTypeIdsImpl::CacheableUserData4; + } + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + return 0; + } + + int8_t ManagedCacheableDeltaBytesGeneric::DSFID() const + { + // convention that [0x8000000, 0xa0000000) is for FixedIDDefault, + // [0xa000000, 0xc0000000) is for FixedIDByte, + // [0xc0000000, 0xe0000000) is for FixedIDShort + // and [0xe0000000, 0xffffffff] is for FixedIDInt + // Note: depends on fact that FixedIDByte is 1, FixedIDShort is 2 + // and FixedIDInt is 3; if this changes then correct this accordingly + System::UInt32 classId = m_classId; + if (classId >= 0x80000000) { + return (int8_t)((classId - 0x80000000) / 0x20000000); + } + return 0; + } + + bool ManagedCacheableDeltaBytesGeneric::hasDelta() + { + //Apache::Geode::Client::IGeodeDelta^ deltaObj = this->getManagedObject(); + //return deltaObj->HasDelta(); + return m_hasDelta; + } + + void ManagedCacheableDeltaBytesGeneric::toDelta(DataOutput& output) const + { + try { + Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytes::toDelta: current domain ID: " + System::Threading::Thread::GetDomainID() + " for object: " + System::Convert::ToString((uint64_t) this) + " with its domain ID: " + m_domainId); + Apache::Geode::Client::IGeodeDelta^ deltaObj = this->getManagedObject(); + Apache::Geode::Client::DataOutput mg_output(&output, true); + deltaObj->ToDelta(%mg_output); + mg_output.WriteBytesToUMDataOutput(); + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + } + + void ManagedCacheableDeltaBytesGeneric::fromDelta(DataInput& input) + { + try { + Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytes::fromDelta:"); + Apache::Geode::Client::IGeodeDelta^ deltaObj = this->getManagedObject(); + Apache::Geode::Client::DataInput mg_input(&input, true, input.getCache()); + deltaObj->FromDelta(%mg_input); + + Apache::Geode::Client::IGeodeSerializable^ managedptr = + dynamic_cast <Apache::Geode::Client::IGeodeSerializable^> (deltaObj); + if (managedptr != nullptr) + { + Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytes::fromDelta: current domain ID: " + System::Threading::Thread::GetDomainID() + " for object: " + System::Convert::ToString((uint64_t) this) + " with its domain ID: " + m_domainId); + Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytes::fromDelta: classid " + managedptr->ClassId + " : " + managedptr->ToString()); + auto dataOut = input.getCache()->createDataOutput(); + Apache::Geode::Client::DataOutput mg_output(dataOut.get(), true); + managedptr->ToData(%mg_output); + + //move cursor + //dataOut.advanceCursor(mg_output.BufferLength); + mg_output.WriteBytesToUMDataOutput(); + + GF_SAFE_DELETE(m_bytes); + m_bytes = dataOut->getBufferCopy(); + m_size = dataOut->getBufferLength(); + Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytes::fromDelta objectSize = " + m_size + " m_hashCode = " + m_hashCode); + m_hashCode = managedptr->GetHashCode(); + } + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + } + + DeltaPtr ManagedCacheableDeltaBytesGeneric::clone() + { + try { + Apache::Geode::Client::IGeodeDelta^ deltaObj = this->getManagedObject(); + ICloneable^ cloneable = dynamic_cast<ICloneable^>((Apache::Geode::Client::IGeodeDelta^) deltaObj); + if (cloneable) { + Apache::Geode::Client::IGeodeSerializable^ Mclone = + dynamic_cast<Apache::Geode::Client::IGeodeSerializable^>(cloneable->Clone()); + return DeltaPtr(static_cast<ManagedCacheableDeltaBytesGeneric*>( + SafeMSerializableConvertGeneric(Mclone))); + } + else { + return Delta::clone(); + } + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + return nullptr; + } + + Apache::Geode::Client::IGeodeDelta^ + ManagedCacheableDeltaBytesGeneric::getManagedObject() const + { + + Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytes::getManagedObject"); + + auto dinp = m_cache->createDataInput(m_bytes, m_size); + Apache::Geode::Client::DataInput mg_dinp(dinp.get(), true, m_cache); + Apache::Geode::Client::TypeFactoryMethodGeneric^ creationMethod = + Apache::Geode::Client::Serializable::GetTypeFactoryMethodGeneric(m_classId); + Apache::Geode::Client::IGeodeSerializable^ newObj = creationMethod(); + + Apache::Geode::Client::IGeodeDelta^ managedDeltaptr = + dynamic_cast <Apache::Geode::Client::IGeodeDelta^> (newObj->FromData(%mg_dinp)); + return managedDeltaptr; + } + + bool ManagedCacheableDeltaBytesGeneric::operator ==(const apache::geode::client::CacheableKey& other) const + { + try { + Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytesGeneric::equal"); + // now checking classId(), typeId(), DSFID() etc. will be much more + // expensive than just a dynamic_cast + const ManagedCacheableDeltaBytesGeneric* p_other = + dynamic_cast<const ManagedCacheableDeltaBytesGeneric*>(&other); + if (p_other != NULL) { + auto di = m_cache->createDataInput(m_bytes, m_size); + Apache::Geode::Client::DataInput mg_input(di.get(), true, m_cache); + Apache::Geode::Client::IGeodeSerializable^ obj = + Apache::Geode::Client::Serializable::GetTypeFactoryMethodGeneric(m_classId)(); + obj->FromData(%mg_input); + bool ret = obj->Equals(p_other->ptr()); + Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytesGeneric::equal return VAL = " + ret); + return ret; + } + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytesGeneric::equal returns false"); + return false; + } + + bool ManagedCacheableDeltaBytesGeneric::operator ==(const ManagedCacheableDeltaBytesGeneric& other) const + { + try { + Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytesGeneric::equal. "); + auto di = m_cache->createDataInput(m_bytes, m_size); + Apache::Geode::Client::DataInput mg_input(di.get(), true, m_cache); + Apache::Geode::Client::IGeodeSerializable^ obj = + Apache::Geode::Client::Serializable::GetTypeFactoryMethodGeneric(m_classId)(); + obj->FromData(%mg_input); + bool ret = obj->Equals(other.ptr()); + Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytesGeneric::equal return VAL = " + ret); + return ret; + //return obj->Equals(other.get()); + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytesGeneric::equal return false"); + return false; + } + + System::Int32 ManagedCacheableDeltaBytesGeneric::hashcode() const + { + throw gcnew System::NotSupportedException; + } + + size_t ManagedCacheableDeltaBytesGeneric::logString(char* buffer, size_t maxLength) const + { + try { + Apache::Geode::Client::IGeodeDelta^ manageObject = getManagedObject(); + if (manageObject != nullptr) + { + if (maxLength > 0) { + String^ logstr = manageObject->GetType()->Name + '(' + + manageObject->ToString() + ')'; + Apache::Geode::Client::ManagedString mg_str(logstr); + return snprintf(buffer, maxLength, "%s", mg_str.CharPtr); + } + } + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + return 0; + } + } // namespace client + } // namespace geode +} // namespace apache http://git-wip-us.apache.org/repos/asf/geode-native/blob/6cbd424f/clicache/src/impl/ManagedCacheableDeltaBytes.hpp ---------------------------------------------------------------------- diff --git a/clicache/src/impl/ManagedCacheableDeltaBytes.hpp b/clicache/src/impl/ManagedCacheableDeltaBytes.hpp new file mode 100644 index 0000000..c5fcbb2 --- /dev/null +++ b/clicache/src/impl/ManagedCacheableDeltaBytes.hpp @@ -0,0 +1,218 @@ +/* + * 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. + */ + +#pragma once + +#include "../geode_defs.hpp" +#include <vcclr.h> +#include "begin_native.hpp" +#include "SerializationRegistry.hpp" +#include <geode/Cache.hpp> +#include <geode/Delta.hpp> +#include <geode/DataOutput.hpp> +#include "end_native.hpp" + +#include "../Log.hpp" +#include "../DataOutput.hpp" + +using namespace System; + +namespace Apache +{ + namespace Geode + { + namespace Client + { + + interface class IGeodeSerializable; + interface class IGeodeDelta; + } // namespace Client + } // namespace Geode +} // namespace Apache + + +namespace apache +{ + namespace geode + { + namespace client + { + + + /// <summary> + /// Wraps the managed <see cref="Apache.Geode.Client.IGeodeDelta" /> + /// object and implements the native <c>apache::geode::client::CacheableKey</c> interface. + /// </summary> + class ManagedCacheableDeltaBytesGeneric + : public CacheableKey, public Delta + { + public: + + /// <summary> + /// Constructor to initialize with the provided managed object. + /// </summary> + /// <param name="managedDeltaptr"> + /// The managed object. + /// </param> + inline ManagedCacheableDeltaBytesGeneric( + Apache::Geode::Client::IGeodeDelta^ managedDeltaptr, bool storeBytes) + :Delta(nullptr), m_domainId(System::Threading::Thread::GetDomainID()), + m_classId(0), + m_bytes(NULL), + m_size(0), + m_hasDelta(false), + m_hashCode(0) + { + if (storeBytes) + m_hasDelta = managedDeltaptr->HasDelta(); + Apache::Geode::Client::IGeodeSerializable^ managedptr = + dynamic_cast <Apache::Geode::Client::IGeodeSerializable^> (managedDeltaptr); + if (managedptr != nullptr) + { + m_classId = managedptr->ClassId; + Apache::Geode::Client::Log::Finer("ManagedCacheableDeltaBytes::Constructor: current AppDomain ID: " + System::Threading::Thread::GetDomainID() + " for object: " + System::Convert::ToString((uint64_t) this) + " with its AppDomain ID: " + m_domainId); + Apache::Geode::Client::Log::Finer("ManagedCacheableDeltaBytes::Constructor: class ID " + managedptr->ClassId + " : " + managedptr->ToString() + " storeBytes:" + storeBytes); + if (storeBytes) + { + auto dataOut = m_cache->createDataOutput(); + Apache::Geode::Client::DataOutput mg_output(dataOut.get(), true); + managedptr->ToData(%mg_output); + + //move cursor + //dataOut.advanceCursor(mg_output.BufferLength); + mg_output.WriteBytesToUMDataOutput(); + + m_bytes = dataOut->getBufferCopy(); + m_size = dataOut->getBufferLength(); + m_hashCode = managedptr->GetHashCode(); + Apache::Geode::Client::Log::Finer("ManagedCacheableDeltaBytes::Constructor objectSize = " + m_size + " m_hashCode = " + m_hashCode); + } + } + } + + /// <summary> + /// serialize this object + /// </summary> + virtual void toData(apache::geode::client::DataOutput& output) const; + + /// <summary> + /// deserialize this object, typical implementation should return + /// the 'this' pointer. + /// </summary> + virtual apache::geode::client::Serializable* fromData(apache::geode::client::DataInput& input); + + virtual void toDelta(apache::geode::client::DataOutput& output) const; + + virtual void fromDelta(apache::geode::client::DataInput& input); + + /// <summary> + /// return the size of this object in bytes + /// </summary> + virtual System::UInt32 objectSize() const; + + /// <summary> + /// return the classId of the instance being serialized. + /// This is used by deserialization to determine what instance + /// type to create and deserialize into. + /// </summary> + virtual System::Int32 classId() const; + + /// <summary> + /// return the typeId of the instance being serialized. + /// This is used by deserialization to determine what instance + /// type to create and deserialize into. + /// </summary> + virtual int8_t typeId() const; + + /// <summary> + /// return the Data Serialization Fixed ID type. + /// This is used to determine what instance type to create + /// and deserialize into. + /// + /// Note that this should not be overridden by custom implementations + /// and is reserved only for builtin types. + /// </summary> + virtual int8_t DSFID() const; + + virtual bool hasDelta(); + + virtual apache::geode::client::DeltaPtr clone(); + + /// <summary> + /// return the hashcode for this key. + /// </summary> + virtual System::Int32 hashcode() const; + + /// <summary> + /// return true if this key matches other CacheableKey + /// </summary> + virtual bool operator == (const CacheableKey& other) const; + + /// <summary> + /// return true if this key matches other ManagedCacheableDeltaBytesGeneric + /// </summary> + virtual bool operator == (const ManagedCacheableDeltaBytesGeneric& other) const; + + /// <summary> + /// Copy the string form of a key into a char* buffer for logging purposes. + /// implementations should only generate a string as long as maxLength chars, + /// and return the number of chars written. buffer is expected to be large + /// enough to hold at least maxLength chars. + /// The default implementation renders the classname and instance address. + /// </summary> + virtual size_t logString(char* buffer, size_t maxLength) const; + + /// <summary> + /// Returns the wrapped managed object reference. + /// </summary> + inline Apache::Geode::Client::IGeodeDelta^ ptr() const + { + return getManagedObject(); + } + + inline ~ManagedCacheableDeltaBytesGeneric() + { + Apache::Geode::Client::Log::Finer("ManagedCacheableDeltaBytes::Destructor current AppDomain ID: " + System::Threading::Thread::GetDomainID() + " for object: " + System::Convert::ToString((uint64_t) this) + " with its AppDomain ID: " + m_domainId); + GF_SAFE_DELETE(m_bytes); + } + + private: + Apache::Geode::Client::IGeodeDelta^ getManagedObject() const; + /// <summary> + /// Using gcroot to hold the managed delegate pointer (since it cannot be stored directly). + /// Note: not using auto_gcroot since it will result in 'Dispose' of the IGeodeDelta + /// to be called which is not what is desired when this object is destroyed. Normally this + /// managed object may be created by the user and will be handled automatically by the GC. + /// </summary> + //gcroot<Apache::Geode::Client::IGeodeDelta^> m_managedptr; + //gcroot<Apache::Geode::Client::IGeodeSerializable^> m_managedSerializableptr; + + int m_domainId; + UInt32 m_classId; + System::Byte * m_bytes; + System::UInt32 m_size; + System::UInt32 m_hashCode; + bool m_hasDelta; + + // Disable the copy and assignment constructors + ManagedCacheableDeltaBytesGeneric(const ManagedCacheableDeltaBytesGeneric&); + ManagedCacheableDeltaBytesGeneric& operator = (const ManagedCacheableDeltaBytesGeneric&); + }; + + } + } +} http://git-wip-us.apache.org/repos/asf/geode-native/blob/6cbd424f/clicache/src/impl/ManagedCacheableKey.cpp ---------------------------------------------------------------------- diff --git a/clicache/src/impl/ManagedCacheableKey.cpp b/clicache/src/impl/ManagedCacheableKey.cpp new file mode 100644 index 0000000..8cefef9 --- /dev/null +++ b/clicache/src/impl/ManagedCacheableKey.cpp @@ -0,0 +1,230 @@ +/* + * 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 "begin_native.hpp" +#include <GeodeTypeIdsImpl.hpp> +#include "end_native.hpp" + +#include "../ICacheableKey.hpp" +#include "ManagedCacheableKey.hpp" +#include "../DataInput.hpp" +#include "../DataOutput.hpp" +#include "../CacheableString.hpp" +#include "../ExceptionTypes.hpp" +#include "../Log.hpp" + +using namespace System; + +namespace apache +{ + namespace geode + { + namespace client + { + + void ManagedCacheableKeyGeneric::toData(apache::geode::client::DataOutput& output) const + { + try { + System::UInt32 pos = (int)output.getBufferLength(); + //Apache::Geode::Client::Log::Debug("ManagedCacheableKeyGeneric::toData"); + Apache::Geode::Client::DataOutput mg_output(&output, true); + m_managedptr->ToData(%mg_output); + //this will move the cursor in c++ layer + mg_output.WriteBytesToUMDataOutput(); + + ManagedCacheableKeyGeneric* tmp = const_cast<ManagedCacheableKeyGeneric*>(this); + tmp->m_objectSize = (int)(output.getBufferLength() - pos); + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + } + + apache::geode::client::Serializable* ManagedCacheableKeyGeneric::fromData(apache::geode::client::DataInput& input) + { + try { + int pos = input.getBytesRead(); + //Apache::Geode::Client::Log::Debug("ManagedCacheableKeyGeneric::fromData"); + Apache::Geode::Client::DataInput mg_input(&input, true, input.getCache()); + m_managedptr = m_managedptr->FromData(%mg_input); + + //this will move the cursor in c++ layer + input.advanceCursor(mg_input.BytesReadInternally); + m_objectSize = input.getBytesRead() - pos; + //if(m_hashcode == 0) + //m_hashcode = m_managedptr->GetHashCode(); + + + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + return this; + } + + System::UInt32 ManagedCacheableKeyGeneric::objectSize() const + { + try { + int ret = m_managedptr->ObjectSize; + if (ret > m_objectSize) + return ret; + else + return m_objectSize; + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + return 0; + } + + System::Int32 ManagedCacheableKeyGeneric::classId() const + { + return (m_classId >= 0x80000000 ? 0 : m_classId); + } + + int8_t ManagedCacheableKeyGeneric::typeId() const + { + if (m_classId >= 0x80000000) { + return (int8_t)((m_classId - 0x80000000) % 0x20000000); + } + else if (m_classId <= 0x7F) { + return (int8_t)GeodeTypeIdsImpl::CacheableUserData; + } + else if (m_classId <= 0x7FFF) { + return (int8_t)GeodeTypeIdsImpl::CacheableUserData2; + } + else { + return (int8_t)GeodeTypeIdsImpl::CacheableUserData4; + } + } + + int8_t ManagedCacheableKeyGeneric::DSFID() const + { + if (m_classId >= 0x80000000) { + return (int8_t)((m_classId - 0x80000000) / 0x20000000); + } + return 0; + } + + apache::geode::client::CacheableStringPtr ManagedCacheableKeyGeneric::toString() const + { + try { + apache::geode::client::CacheableStringPtr cStr; + Apache::Geode::Client::CacheableString::GetCacheableString( + m_managedptr->ToString(), cStr); + return cStr; + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + return nullptr; + } + + bool ManagedCacheableKeyGeneric::operator ==(const apache::geode::client::CacheableKey& other) const + { + try { + // now checking classId(), typeId(), DSFID() etc. will be much more + // expensive than just a dynamic_cast + const ManagedCacheableKeyGeneric* p_other = + dynamic_cast<const ManagedCacheableKeyGeneric*>(&other); + if (p_other != NULL) { + return static_cast<Apache::Geode::Client::ICacheableKey^>( + (static_cast<Apache::Geode::Client::IGeodeSerializable^>((Apache::Geode::Client::IGeodeSerializable^)m_managedptr)))->Equals( + static_cast<Apache::Geode::Client::ICacheableKey^>(p_other->ptr())); + } + return false; + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + return false; + } + + bool ManagedCacheableKeyGeneric::operator ==(const ManagedCacheableKeyGeneric& other) const + { + try { + return static_cast<Apache::Geode::Client::ICacheableKey^>( + (Apache::Geode::Client::IGeodeSerializable^)(Apache::Geode::Client::IGeodeSerializable^)m_managedptr)->Equals( + static_cast<Apache::Geode::Client::ICacheableKey^>(other.ptr())); + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + return false; + } + + System::Int32 ManagedCacheableKeyGeneric::hashcode() const + { + if (m_hashcode != 0) + return m_hashcode; + try { + + ManagedCacheableKeyGeneric* tmp = const_cast<ManagedCacheableKeyGeneric*>(this); + tmp->m_hashcode = ((Apache::Geode::Client::ICacheableKey^) + (Apache::Geode::Client::IGeodeSerializable^)m_managedptr) + ->GetHashCode(); + return m_hashcode; + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + return 0; + } + + size_t ManagedCacheableKeyGeneric::logString(char* buffer, size_t maxLength) const + { + try { + if (maxLength > 0) { + String^ logstr = m_managedptr->GetType()->Name + '(' + + m_managedptr->ToString() + ')'; + Apache::Geode::Client::ManagedString mg_str(logstr); + return snprintf(buffer, maxLength, "%s", mg_str.CharPtr); + } + } + catch (Apache::Geode::Client::GeodeException^ ex) { + ex->ThrowNative(); + } + catch (System::Exception^ ex) { + Apache::Geode::Client::GeodeException::ThrowNative(ex); + } + return 0; + } + + } // namespace client + } // namespace geode +} // namespace apache http://git-wip-us.apache.org/repos/asf/geode-native/blob/6cbd424f/clicache/src/impl/ManagedCacheableKey.hpp ---------------------------------------------------------------------- diff --git a/clicache/src/impl/ManagedCacheableKey.hpp b/clicache/src/impl/ManagedCacheableKey.hpp new file mode 100644 index 0000000..1f3c27f --- /dev/null +++ b/clicache/src/impl/ManagedCacheableKey.hpp @@ -0,0 +1,173 @@ +/* + * 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. + */ + +#pragma once + +#include "../geode_defs.hpp" +#include <vcclr.h> +#include "begin_native.hpp" +#include <geode/CacheableKey.hpp> +#include <GeodeTypeIdsImpl.hpp> +#include "SerializationRegistry.hpp" +#include "end_native.hpp" + +#include "../IGeodeSerializable.hpp" + +using namespace System; + +namespace apache +{ + namespace geode + { + namespace client + { + namespace native = apache::geode::client; + + /// <summary> + /// Wraps the managed <see cref="Apache.Geode.Client.IGeodeSerializable" /> + /// object and implements the native <c>apache::geode::client::CacheableKey</c> interface. + /// </summary> + class ManagedCacheableKeyGeneric + : public apache::geode::client::CacheableKey + { + private: + int m_hashcode; + int m_classId; + native::SerializationRegistry* m_serializationRegistry; + int m_objectSize; + public: + + inline ManagedCacheableKeyGeneric( + Apache::Geode::Client::IGeodeSerializable^ managedptr, int hashcode, int classId, native::SerializationRegistry * serializationRegistry) + : m_managedptr(managedptr) { + m_hashcode = hashcode; + m_classId = classId; + m_serializationRegistry = serializationRegistry; + m_objectSize = 0; + } + /// <summary> + /// Constructor to initialize with the provided managed object. + /// </summary> + /// <param name="managedptr"> + /// The managed object. + /// </param> + inline ManagedCacheableKeyGeneric(Apache::Geode::Client::IGeodeSerializable^ managedptr, native::SerializationRegistry * serializationRegistry) + : m_managedptr(managedptr) { + // m_hashcode = managedptr->GetHashCode(); + m_hashcode = 0; + m_classId = managedptr->ClassId; + m_serializationRegistry = serializationRegistry; + m_objectSize = 0; + } + + /// <summary> + /// serialize this object + /// </summary> + virtual void toData(apache::geode::client::DataOutput& output) const; + + /// <summary> + /// deserialize this object, typical implementation should return + /// the 'this' pointer. + /// </summary> + virtual apache::geode::client::Serializable* fromData(apache::geode::client::DataInput& input); + + + /// <summary> + /// return the size of this object in bytes + /// </summary> + virtual System::UInt32 objectSize() const; + + /// <summary> + /// return the classId of the instance being serialized. + /// This is used by deserialization to determine what instance + /// type to create and deserialize into. + /// </summary> + virtual System::Int32 classId() const; + + /// <summary> + /// return the typeId of the instance being serialized. + /// This is used by deserialization to determine what instance + /// type to create and deserialize into. + /// </summary> + virtual int8_t typeId() const; + + /// <summary> + /// return the Data Serialization Fixed ID type. + /// This is used to determine what instance type to create + /// and deserialize into. + /// + /// Note that this should not be overridden by custom implementations + /// and is reserved only for builtin types. + /// </summary> + virtual int8_t DSFID() const; + + /// <summary> + /// Display this object as 'string', which depends on the implementation in + /// the managed class + /// </summary> + virtual apache::geode::client::CacheableStringPtr toString() const; + + /// <summary> + /// return true if this key matches other CacheableKey + /// </summary> + virtual bool operator == (const CacheableKey& other) const; + /// <summary> + /// return true if this key matches other ManagedCacheableKey + /// </summary> + virtual bool operator == (const ManagedCacheableKeyGeneric& other) const; + + /// <summary> + /// return the hashcode for this key. + /// </summary> + virtual System::Int32 hashcode() const; + + /// <summary> + /// Copy the string form of a key into a char* buffer for logging purposes. + /// implementations should only generate a string as long as maxLength chars, + /// and return the number of chars written. buffer is expected to be large + /// enough to hold at least maxLength chars. + /// The default implementation renders the classname and instance address. + /// </summary> + virtual size_t logString(char* buffer, size_t maxLength) const; + + /// <summary> + /// Returns the wrapped managed object reference. + /// </summary> + inline Apache::Geode::Client::IGeodeSerializable^ ptr() const + { + return m_managedptr; + } + + + private: + + /// <summary> + /// Using gcroot to hold the managed delegate pointer (since it cannot be stored directly). + /// Note: not using auto_gcroot since it will result in 'Dispose' of the IGeodeSerializable + /// to be called which is not what is desired when this object is destroyed. Normally this + /// managed object may be created by the user and will be handled automatically by the GC. + /// </summary> + gcroot<Apache::Geode::Client::IGeodeSerializable^> m_managedptr; + + // Disable the copy and assignment constructors + ManagedCacheableKeyGeneric(const ManagedCacheableKeyGeneric&); + ManagedCacheableKeyGeneric& operator = (const ManagedCacheableKeyGeneric&); + }; + + } // namespace client + } // namespace geode +} // namespace apache