You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by mm...@apache.org on 2021/12/08 23:16:06 UTC

[geode-native] 02/02: Genericize netcore-lib

This is an automated email from the ASF dual-hosted git repository.

mmartell pushed a commit to branch GEODE-9712-genericize-netcore
in repository https://gitbox.apache.org/repos/asf/geode-native.git

commit 2503eedd75c8ee9320cf48a4d01af6b4d5d65815
Author: Mike Martell <mm...@pivotal.io>
AuthorDate: Wed Dec 8 15:15:39 2021 -0800

    Genericize netcore-lib
---
 netcore/netcore-lib/Cache.cs                       | 113 ++++++++++----------
 netcore/netcore-lib/{Cache.cs => CacheInterop.cs}  |   8 +-
 .../netcore-lib/{IRegionService.cs => IRegion.cs}  |  12 ++-
 netcore/netcore-lib/IRegionService.cs              |   8 +-
 netcore/netcore-lib/PoolManager.cs                 |   7 ++
 netcore/netcore-lib/Region.cs                      | 117 +++++++--------------
 netcore/netcore-lib/RegionFactory.cs               |  44 +++++---
 .../{RegionFactory.cs => RegionFactoryInterop.cs}  |  10 +-
 .../netcore-lib/{Region.cs => RegionInterop.cs}    |  69 +++++++++---
 9 files changed, 206 insertions(+), 182 deletions(-)

diff --git a/netcore/netcore-lib/Cache.cs b/netcore/netcore-lib/Cache.cs
index 200e740..064b963 100644
--- a/netcore/netcore-lib/Cache.cs
+++ b/netcore/netcore-lib/Cache.cs
@@ -20,59 +20,29 @@ using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
 namespace Apache.Geode.Client {
-  public class Cache : GeodeNativeObject, IGeodeCache {
+  public class Cache : IGeodeCache {
+    private IntPtr _cacheFactory;
+    private CacheInterop _cacheInterop;
     private static string _name = String.Empty;
     private PoolManager _poolManager = null;
     private PoolFactory _poolFactory = null;
     private IAuthInitialize _authInitialize;
     private GetCredentialsDelegateInternal _getCredentialsDelegate;
     private CloseDelegateInternal _closeDelegate;
+    private bool disposedValue;
 
     internal delegate void GetCredentialsDelegateInternal(IntPtr cache);
 
     internal delegate void CloseDelegateInternal();
 
-    [DllImport(Constants.libPath, CallingConvention = CallingConvention.Cdecl)]
-    private static extern void apache_geode_CacheFactory_SetAuthInitialize(
-        IntPtr factory, GetCredentialsDelegateInternal getCredentials,
-        CloseDelegateInternal close);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern IntPtr apache_geode_CacheFactory_CreateCache(IntPtr factory);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern bool apache_geode_Cache_GetPdxIgnoreUnreadFields(IntPtr cache);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern bool apache_geode_Cache_GetPdxReadSerialized(IntPtr cache);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern IntPtr apache_geode_Cache_GetName(IntPtr cache);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern void apache_geode_Cache_Close(IntPtr cache, bool keepalive);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern bool apache_geode_Cache_IsClosed(IntPtr cache);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern bool apache_geode_AuthInitialize_AddProperty(IntPtr properties,
-                                                                       IntPtr key,
-                                                                       IntPtr value);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern void apache_geode_DestroyCache(IntPtr cache);
-
     internal Cache(IntPtr cacheFactory, IAuthInitialize authInitialize) {
       _authInitialize = authInitialize;
+      _cacheFactory = cacheFactory;
+      _cacheInterop = new CacheInterop(cacheFactory, authInitialize);
       if (_authInitialize != null) {
         _getCredentialsDelegate = new GetCredentialsDelegateInternal(AuthGetCredentials);
         _closeDelegate = new CloseDelegateInternal(AuthClose);
-
-        apache_geode_CacheFactory_SetAuthInitialize(cacheFactory, _getCredentialsDelegate,
-                                                    _closeDelegate);
       }
-      _containedObject = apache_geode_CacheFactory_CreateCache(cacheFactory);
     }
 
     internal void AuthGetCredentials(IntPtr properties) {
@@ -87,7 +57,7 @@ namespace Apache.Geode.Client {
         Console.WriteLine("Found credential: (k, v) = ({0}, {1})", entry.Key, entry.Value);
         var keyPtr = Marshal.StringToCoTaskMemUTF8(entry.Key);
         var valuePtr = Marshal.StringToCoTaskMemUTF8(entry.Value);
-        apache_geode_AuthInitialize_AddProperty(properties, keyPtr, valuePtr);
+        //apache_geode_AuthInitialize_AddProperty(properties, keyPtr, valuePtr);
         Marshal.FreeCoTaskMem(keyPtr);
         Marshal.FreeCoTaskMem(valuePtr);
       }
@@ -98,25 +68,33 @@ namespace Apache.Geode.Client {
     }
 
     public void Close() {
-      apache_geode_Cache_Close(_containedObject, false);
+      _cacheInterop.Close();
     }
 
     public void Close(bool keepalive) {
-      apache_geode_Cache_Close(_containedObject, keepalive);
+      _cacheInterop.Close(keepalive);
+    }
+
+    public bool Closed
+    {
+      get
+      {
+        return _cacheInterop.Closed;
+      }
     }
 
     public bool GetPdxIgnoreUnreadFields() {
-      return apache_geode_Cache_GetPdxIgnoreUnreadFields(_containedObject);
+      return _cacheInterop.GetPdxIgnoreUnreadFields();
     }
 
     public bool GetPdxReadSerialized() {
-      return apache_geode_Cache_GetPdxReadSerialized(_containedObject);
+      return _cacheInterop.GetPdxReadSerialized();
     }
 
     public string Name {
       get {
         if (_name == String.Empty) {
-          _name = Marshal.PtrToStringUTF8(apache_geode_Cache_GetName(_containedObject));
+          _name = _cacheInterop.Name;
         }
 
         return _name;
@@ -126,7 +104,8 @@ namespace Apache.Geode.Client {
     public PoolManager PoolManager {
       get {
         if (_poolManager == null) {
-          _poolManager = new PoolManager(_containedObject);
+          //_poolManager = new PoolManager(_cacheInterop);
+          _poolManager = _cacheInterop.PoolManager;
         }
 
         return _poolManager;
@@ -137,30 +116,44 @@ namespace Apache.Geode.Client {
       get {
         if (_poolFactory == null) {
           _poolFactory = PoolManager.CreatePoolFactory();
+          //_poolFactory = _cacheInterop.PoolManager.CreatePoolFactory();
         }
 
         return _poolFactory;
       }
     }
 
-    public RegionFactory CreateRegionFactory(RegionShortcut regionType) {
-      return new RegionFactory(_containedObject, regionType);
+    public RegionFactory<TValue> CreateRegionFactory<TValue>(RegionShortcut regionType) {
+      return new RegionFactory<TValue>(_cacheInterop, regionType);
     }
 
-    public bool Closed => apache_geode_Cache_IsClosed(_containedObject);
-
-    protected override void DestroyContainedObject() {
-      // It turns out, C# "wrapper" objects need to get rid of
-      // *all* contained objects, due to vagaries of Geode
-      // Native object graph, in order to ensure a leak-free
-      // shutdown.  We get rid of our non-cache objects first
-      // here, in case it makes a difference.
-      _poolManager?.Dispose();
-      _poolManager = null;
-      _poolFactory?.Dispose();
-      _poolFactory = null;
-      apache_geode_DestroyCache(_containedObject);
-      _containedObject = IntPtr.Zero;
+    protected virtual void Dispose(bool disposing)
+    {
+      if (!disposedValue)
+      {
+        if (disposing)
+        {
+          // TODO: dispose managed state (managed objects)
+        }
+
+        // TODO: free unmanaged resources (unmanaged objects) and override finalizer
+        // TODO: set large fields to null
+        disposedValue = true;
+      }
+    }
+
+    // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
+    // ~Cache()
+    // {
+    //     // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
+    //     Dispose(disposing: false);
+    // }
+
+    public void Dispose()
+    {
+      // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
+      Dispose(disposing: true);
+      GC.SuppressFinalize(this);
     }
   }
-}
+  }
diff --git a/netcore/netcore-lib/Cache.cs b/netcore/netcore-lib/CacheInterop.cs
similarity index 95%
copy from netcore/netcore-lib/Cache.cs
copy to netcore/netcore-lib/CacheInterop.cs
index 200e740..f8fe5a1 100644
--- a/netcore/netcore-lib/Cache.cs
+++ b/netcore/netcore-lib/CacheInterop.cs
@@ -20,7 +20,7 @@ using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
 namespace Apache.Geode.Client {
-  public class Cache : GeodeNativeObject, IGeodeCache {
+  public class CacheInterop : GeodeNativeObject {
     private static string _name = String.Empty;
     private PoolManager _poolManager = null;
     private PoolFactory _poolFactory = null;
@@ -63,7 +63,7 @@ namespace Apache.Geode.Client {
     [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
     private static extern void apache_geode_DestroyCache(IntPtr cache);
 
-    internal Cache(IntPtr cacheFactory, IAuthInitialize authInitialize) {
+    internal CacheInterop(IntPtr cacheFactory, IAuthInitialize authInitialize) {
       _authInitialize = authInitialize;
       if (_authInitialize != null) {
         _getCredentialsDelegate = new GetCredentialsDelegateInternal(AuthGetCredentials);
@@ -143,8 +143,8 @@ namespace Apache.Geode.Client {
       }
     }
 
-    public RegionFactory CreateRegionFactory(RegionShortcut regionType) {
-      return new RegionFactory(_containedObject, regionType);
+    public RegionFactoryInterop CreateRegionFactory<TValue>(RegionShortcut regionType) {
+      return new RegionFactoryInterop(_containedObject, regionType);
     }
 
     public bool Closed => apache_geode_Cache_IsClosed(_containedObject);
diff --git a/netcore/netcore-lib/IRegionService.cs b/netcore/netcore-lib/IRegion.cs
similarity index 65%
copy from netcore/netcore-lib/IRegionService.cs
copy to netcore/netcore-lib/IRegion.cs
index d635d71..33b0186 100644
--- a/netcore/netcore-lib/IRegionService.cs
+++ b/netcore/netcore-lib/IRegion.cs
@@ -17,7 +17,15 @@
 using System;
 
 namespace Apache.Geode.Client {
-  public interface IRegionService {
-    RegionFactory CreateRegionFactory(RegionShortcut regionType);
+  //public interface IRegion<TKey, TValue> {
+  //      void Put(TKey key, TValue value); 
+  //      TValue Get(TKey key);
+  //}
+  public interface IRegion<TKey, TValue>
+  {
+#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type
+    void Put(TKey key, TValue value);
+    TValue Get(TKey key);
+#pragma warning restore CS0693 // Type parameter has the same name as the type parameter from outer type
   }
 }
diff --git a/netcore/netcore-lib/IRegionService.cs b/netcore/netcore-lib/IRegionService.cs
index d635d71..87063a7 100644
--- a/netcore/netcore-lib/IRegionService.cs
+++ b/netcore/netcore-lib/IRegionService.cs
@@ -17,7 +17,9 @@
 using System;
 
 namespace Apache.Geode.Client {
-  public interface IRegionService {
-    RegionFactory CreateRegionFactory(RegionShortcut regionType);
-  }
+
+public interface IRegionService {
+  RegionFactory<TValue> CreateRegionFactory<TValue>(RegionShortcut regionType);
 }
+
+}
\ No newline at end of file
diff --git a/netcore/netcore-lib/PoolManager.cs b/netcore/netcore-lib/PoolManager.cs
index 5a06436..b7f1d73 100644
--- a/netcore/netcore-lib/PoolManager.cs
+++ b/netcore/netcore-lib/PoolManager.cs
@@ -19,6 +19,8 @@ using System.Runtime.InteropServices;
 
 namespace Apache.Geode.Client {
   public class PoolManager : GeodeNativeObject {
+    private CacheInterop cacheInterop;
+
     [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
     private static extern IntPtr apache_geode_Cache_GetPoolManager(IntPtr cache);
 
@@ -29,6 +31,11 @@ namespace Apache.Geode.Client {
       _containedObject = apache_geode_Cache_GetPoolManager(cache);
     }
 
+    public PoolManager(CacheInterop cacheInterop)
+    {
+      this.cacheInterop = cacheInterop;
+    }
+
     public PoolFactory CreatePoolFactory() {
       return new PoolFactory(_containedObject);
     }
diff --git a/netcore/netcore-lib/Region.cs b/netcore/netcore-lib/Region.cs
index 68d49a5..17111ee 100644
--- a/netcore/netcore-lib/Region.cs
+++ b/netcore/netcore-lib/Region.cs
@@ -15,100 +15,59 @@
  * limitations under the License.
  */
 using System;
-using System.Runtime.InteropServices;
+using System.IO;
+using System.Runtime.Serialization;
+using System.Runtime.Serialization.Formatters.Binary;
 
 namespace Apache.Geode.Client {
-  public class Region : GeodeNativeObject {
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern IntPtr apache_geode_RegionFactory_CreateRegion(IntPtr cache,
-                                                                         IntPtr regionName);
+  public class Region<TKey, TValue> : IRegion<TKey, TValue> {
+  //public class Region<TValue> : IRegion<TValue> {
+    RegionInterop _regionInterop;
 
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern bool apache_geode_Region_PutString(IntPtr region, IntPtr key,
-                                                             IntPtr value);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern bool apache_geode_Region_PutByteArray(IntPtr region, IntPtr key,
-                                                                IntPtr value, int length);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern IntPtr apache_geode_Region_GetString(IntPtr region, IntPtr key);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern void apache_geode_Region_GetByteArray(IntPtr region, IntPtr key,
-                                                                ref IntPtr value, ref int size);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern void apache_geode_Region_Remove(IntPtr region, IntPtr key);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern bool apache_geode_Region_ContainsValueForKey(IntPtr region,
-                                                                       IntPtr key);
-
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern IntPtr apache_geode_DestroyRegion(IntPtr region);
-
-    internal Region(IntPtr regionFactory, string regionName) {
-      var regionNamePtr = Marshal.StringToCoTaskMemUTF8(regionName);
-      _containedObject = apache_geode_RegionFactory_CreateRegion(regionFactory, regionNamePtr);
-      Marshal.FreeCoTaskMem(regionNamePtr);
+    public Region(RegionInterop regionInterop) {
+      _regionInterop = regionInterop;
     }
 
-    public void PutString(string key, string value) {
-      var keyPtr = Marshal.StringToCoTaskMemUTF8(key);
-      var valuePtr = Marshal.StringToCoTaskMemUTF8(value);
-      apache_geode_Region_PutString(_containedObject, keyPtr, valuePtr);
-      Marshal.FreeCoTaskMem(keyPtr);
-      Marshal.FreeCoTaskMem(valuePtr);
+#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type
+    public TValue Get(TKey key, Object callbackArg) {
+#pragma warning restore CS0693 // Type parameter has the same name as the type parameter from outer type
+      //var byteArray = ObjectToByteArray(key);
+      byte[] bytes = _regionInterop.GetByteArray(key.ToString());
+      return Deserialize<TValue>(bytes);
     }
 
-    public void PutByteArray(string key, byte[] value) {
-      var keyPtr = Marshal.StringToCoTaskMemUTF8(key);
-      var valuePtr = Marshal.AllocCoTaskMem(value.Length);
-      Marshal.Copy(value, 0, valuePtr, value.Length);
-      apache_geode_Region_PutByteArray(_containedObject, keyPtr, valuePtr, value.Length);
-      Marshal.FreeCoTaskMem(keyPtr);
-      Marshal.FreeCoTaskMem(valuePtr);
+    public TValue Get(TKey key) {
+      return Get(key, null);
     }
 
-    public string GetString(string key) {
-      var keyPtr = Marshal.StringToCoTaskMemUTF8(key);
-      var result =
-          Marshal.PtrToStringUTF8(apache_geode_Region_GetString(_containedObject, keyPtr));
-      Marshal.FreeCoTaskMem(keyPtr);
-      return result;
+    public void Put(TKey key, TValue value, Object callbackArg) {
+      var valueByteArray = ObjectToByteArray(value);
+      _regionInterop.PutByteArray(key.ToString(), valueByteArray);
     }
 
-    public byte[] GetByteArray(string key) {
-      var keyPtr = Marshal.StringToCoTaskMemUTF8(key);
-      var valPtr = (IntPtr)0;
-      int size = 0;
-      apache_geode_Region_GetByteArray(_containedObject, keyPtr, ref valPtr, ref size);
-      if (size > 0) {
-        Byte[] byteArray = new Byte[size];
-        Marshal.Copy(valPtr, byteArray, 0, size);
-        Marshal.FreeCoTaskMem(valPtr);
-        return byteArray;
-      } else
-        return null;
+    public void Put(TKey key, TValue value) {
+      Put(key, value, null);
     }
 
-    public void Remove(string key) {
-      var keyPtr = Marshal.StringToCoTaskMemUTF8(key);
-      apache_geode_Region_Remove(_containedObject, keyPtr);
-      Marshal.FreeCoTaskMem(keyPtr);
-    }
-
-    public bool ContainsValueForKey(string key) {
-      var keyPtr = Marshal.StringToCoTaskMemUTF8(key);
-      bool result = apache_geode_Region_ContainsValueForKey(_containedObject, keyPtr);
-      Marshal.FreeCoTaskMem(keyPtr);
-      return result;
+    byte[] ObjectToByteArray(object obj)
+    {
+      if (obj == null)
+        return null;
+      BinaryFormatter bf = new BinaryFormatter();
+      using (MemoryStream ms = new MemoryStream())
+      {
+        bf.Serialize(ms, obj);
+        return ms.ToArray();
+      }
     }
 
-    protected override void DestroyContainedObject() {
-      apache_geode_DestroyRegion(_containedObject);
-      _containedObject = IntPtr.Zero;
+    private T Deserialize<T>(byte[] param)
+    {
+      using (MemoryStream ms = new MemoryStream(param))
+      {
+        IFormatter br = new BinaryFormatter();
+        return (T)br.Deserialize(ms);
+      }
     }
   }
 }
diff --git a/netcore/netcore-lib/RegionFactory.cs b/netcore/netcore-lib/RegionFactory.cs
index 0cf2fd9..bb992e7 100644
--- a/netcore/netcore-lib/RegionFactory.cs
+++ b/netcore/netcore-lib/RegionFactory.cs
@@ -15,28 +15,38 @@
  * limitations under the License.
  */
 using System;
-using System.Runtime.InteropServices;
 
 namespace Apache.Geode.Client {
-  public class RegionFactory : GeodeNativeObject {
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern IntPtr apache_geode_Cache_CreateRegionFactory(IntPtr cache,
-                                                                        int regionType);
 
-    [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
-    private static extern IntPtr apache_geode_DestroyRegionFactory(IntPtr regionFactory);
+public class RegionFactory<TValue> {
+  RegionFactoryInterop _regionFactoryInterop;
+  RegionInterop _regionInterop;
+  RegionShortcut _regionType;
+  IntPtr _cacheInterop;
+  private CacheInterop cacheInterop;
+  private RegionShortcut regionType;
 
-    internal RegionFactory(IntPtr cache, RegionShortcut regionType) {
-      _containedObject = apache_geode_Cache_CreateRegionFactory(cache, (int)regionType);
-    }
+  public RegionFactory(
+    IntPtr cacheInterop,
+    RegionShortcut regionType) {
+    _regionType = regionType;
+    _cacheInterop = cacheInterop;
+  }
 
-    public Region CreateRegion(string regionName) {
-      return new Region(_containedObject, regionName);
-    }
+  public RegionFactory(CacheInterop cacheInterop, RegionShortcut regionType)
+  {
+    this.cacheInterop = cacheInterop;
+    _cacheInterop = cacheInterop.ContainedObject;
+    this.regionType = regionType;
+  }
 
-    protected override void DestroyContainedObject() {
-      apache_geode_DestroyRegionFactory(_containedObject);
-      _containedObject = IntPtr.Zero;
-    }
+#pragma warning disable CS0693 // Type parameter has the same name as the type parameter from outer type
+    public IRegion<TKey, TValue> Create<TKey, TValue>(string regionName) {
+#pragma warning restore CS0693 // Type parameter has the same name as the type parameter from outer type
+      _regionFactoryInterop = new RegionFactoryInterop(_cacheInterop, _regionType);
+    _regionInterop = _regionFactoryInterop.CreateRegion(regionName);
+    return new Region<TKey, TValue>(_regionInterop);
   }
 }
+
+}
\ No newline at end of file
diff --git a/netcore/netcore-lib/RegionFactory.cs b/netcore/netcore-lib/RegionFactoryInterop.cs
similarity index 83%
copy from netcore/netcore-lib/RegionFactory.cs
copy to netcore/netcore-lib/RegionFactoryInterop.cs
index 0cf2fd9..1c154ab 100644
--- a/netcore/netcore-lib/RegionFactory.cs
+++ b/netcore/netcore-lib/RegionFactoryInterop.cs
@@ -18,7 +18,7 @@ using System;
 using System.Runtime.InteropServices;
 
 namespace Apache.Geode.Client {
-  public class RegionFactory : GeodeNativeObject {
+  public class RegionFactoryInterop : GeodeNativeObject {
     [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
     private static extern IntPtr apache_geode_Cache_CreateRegionFactory(IntPtr cache,
                                                                         int regionType);
@@ -26,12 +26,12 @@ namespace Apache.Geode.Client {
     [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
     private static extern IntPtr apache_geode_DestroyRegionFactory(IntPtr regionFactory);
 
-    internal RegionFactory(IntPtr cache, RegionShortcut regionType) {
-      _containedObject = apache_geode_Cache_CreateRegionFactory(cache, (int)regionType);
+    internal RegionFactoryInterop(IntPtr cacheInterop, RegionShortcut regionType) {
+      _containedObject = apache_geode_Cache_CreateRegionFactory(cacheInterop, (int)regionType);
     }
 
-    public Region CreateRegion(string regionName) {
-      return new Region(_containedObject, regionName);
+    public RegionInterop CreateRegion(string regionName) {
+      return new RegionInterop(_containedObject, regionName);
     }
 
     protected override void DestroyContainedObject() {
diff --git a/netcore/netcore-lib/Region.cs b/netcore/netcore-lib/RegionInterop.cs
similarity index 73%
copy from netcore/netcore-lib/Region.cs
copy to netcore/netcore-lib/RegionInterop.cs
index 68d49a5..53a6cc7 100644
--- a/netcore/netcore-lib/Region.cs
+++ b/netcore/netcore-lib/RegionInterop.cs
@@ -17,8 +17,10 @@
 using System;
 using System.Runtime.InteropServices;
 
-namespace Apache.Geode.Client {
-  public class Region : GeodeNativeObject {
+namespace Apache.Geode.Client
+{
+  public class RegionInterop : GeodeNativeObject
+  {
     [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
     private static extern IntPtr apache_geode_RegionFactory_CreateRegion(IntPtr cache,
                                                                          IntPtr regionName);
@@ -48,13 +50,15 @@ namespace Apache.Geode.Client {
     [DllImport(Constants.libPath, CharSet = CharSet.Auto)]
     private static extern IntPtr apache_geode_DestroyRegion(IntPtr region);
 
-    internal Region(IntPtr regionFactory, string regionName) {
+    internal RegionInterop(IntPtr regionFactory, string regionName)
+    {
       var regionNamePtr = Marshal.StringToCoTaskMemUTF8(regionName);
       _containedObject = apache_geode_RegionFactory_CreateRegion(regionFactory, regionNamePtr);
       Marshal.FreeCoTaskMem(regionNamePtr);
     }
 
-    public void PutString(string key, string value) {
+    public void PutString(string key, string value)
+    {
       var keyPtr = Marshal.StringToCoTaskMemUTF8(key);
       var valuePtr = Marshal.StringToCoTaskMemUTF8(value);
       apache_geode_Region_PutString(_containedObject, keyPtr, valuePtr);
@@ -62,7 +66,8 @@ namespace Apache.Geode.Client {
       Marshal.FreeCoTaskMem(valuePtr);
     }
 
-    public void PutByteArray(string key, byte[] value) {
+    public void PutByteArray(string key, byte[] value)
+    {
       var keyPtr = Marshal.StringToCoTaskMemUTF8(key);
       var valuePtr = Marshal.AllocCoTaskMem(value.Length);
       Marshal.Copy(value, 0, valuePtr, value.Length);
@@ -71,7 +76,21 @@ namespace Apache.Geode.Client {
       Marshal.FreeCoTaskMem(valuePtr);
     }
 
-    public string GetString(string key) {
+    public void PutByteArray(byte[] key, byte[] value)
+    {
+      var keyPtr = Marshal.AllocCoTaskMem(key.Length);
+      Marshal.Copy(key, 0, keyPtr, key.Length);
+
+      var valuePtr = Marshal.AllocCoTaskMem(value.Length);
+      Marshal.Copy(value, 0, valuePtr, value.Length);
+
+      apache_geode_Region_PutByteArray(_containedObject, keyPtr, valuePtr, value.Length);
+      Marshal.FreeCoTaskMem(keyPtr);
+      Marshal.FreeCoTaskMem(valuePtr);
+    }
+
+    public string GetString(string key)
+    {
       var keyPtr = Marshal.StringToCoTaskMemUTF8(key);
       var result =
           Marshal.PtrToStringUTF8(apache_geode_Region_GetString(_containedObject, keyPtr));
@@ -79,34 +98,60 @@ namespace Apache.Geode.Client {
       return result;
     }
 
-    public byte[] GetByteArray(string key) {
+    public byte[] GetByteArray(string key)
+    {
       var keyPtr = Marshal.StringToCoTaskMemUTF8(key);
       var valPtr = (IntPtr)0;
       int size = 0;
       apache_geode_Region_GetByteArray(_containedObject, keyPtr, ref valPtr, ref size);
-      if (size > 0) {
+      if (size > 0)
+      {
+        Byte[] byteArray = new Byte[size];
+        Marshal.Copy(valPtr, byteArray, 0, size);
+        Marshal.FreeCoTaskMem(valPtr);
+        return byteArray;
+      }
+      else
+        return null;
+    }
+
+    public byte[] GetByteArray(byte[] key)
+    {
+      var keyPtr = Marshal.AllocCoTaskMem(key.Length);
+      Marshal.Copy(key, 0, keyPtr, key.Length);
+
+      var valPtr = (IntPtr)0;
+      int size = 0;
+      apache_geode_Region_GetByteArray(_containedObject, keyPtr, ref valPtr, ref size);
+      if (size > 0)
+      {
         Byte[] byteArray = new Byte[size];
         Marshal.Copy(valPtr, byteArray, 0, size);
         Marshal.FreeCoTaskMem(valPtr);
+        Marshal.FreeCoTaskMem(keyPtr);
         return byteArray;
-      } else
+      }
+      else
         return null;
     }
 
-    public void Remove(string key) {
+    public void Remove(string key)
+    {
       var keyPtr = Marshal.StringToCoTaskMemUTF8(key);
       apache_geode_Region_Remove(_containedObject, keyPtr);
       Marshal.FreeCoTaskMem(keyPtr);
     }
 
-    public bool ContainsValueForKey(string key) {
+    public bool ContainsValueForKey(string key)
+    {
       var keyPtr = Marshal.StringToCoTaskMemUTF8(key);
       bool result = apache_geode_Region_ContainsValueForKey(_containedObject, keyPtr);
       Marshal.FreeCoTaskMem(keyPtr);
       return result;
     }
 
-    protected override void DestroyContainedObject() {
+    protected override void DestroyContainedObject()
+    {
       apache_geode_DestroyRegion(_containedObject);
       _containedObject = IntPtr.Zero;
     }