Skip to content

Commit

Permalink
MemoryPack Serializer (#438)
Browse files Browse the repository at this point in the history
* MemoryPack serializer

* some cleanups

Co-authored-by: amirsolhi <[email protected]>
  • Loading branch information
amiru3f and amirsolhi authored Dec 31, 2022
1 parent 4cc0ab9 commit db8c5af
Show file tree
Hide file tree
Showing 12 changed files with 338 additions and 44 deletions.
9 changes: 8 additions & 1 deletion EasyCaching.sln
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.2.32616.157
MinimumVisualStudioVersion = 10.0.40219.1
Expand Down Expand Up @@ -76,6 +76,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyCaching.Bus.Zookeeper",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyCaching.FasterKv", "src\EasyCaching.FasterKv\EasyCaching.FasterKv.csproj", "{7191E567-38DF-4879-82E1-73EC618AFCAC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EasyCaching.Serialization.MemoryPack", "serialization\EasyCaching.Serialization.MemoryPack\EasyCaching.Serialization.MemoryPack.csproj", "{EEF22C21-F380-4980-B72C-F14488369333}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -202,6 +204,10 @@ Global
{7191E567-38DF-4879-82E1-73EC618AFCAC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7191E567-38DF-4879-82E1-73EC618AFCAC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7191E567-38DF-4879-82E1-73EC618AFCAC}.Release|Any CPU.Build.0 = Release|Any CPU
{EEF22C21-F380-4980-B72C-F14488369333}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EEF22C21-F380-4980-B72C-F14488369333}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EEF22C21-F380-4980-B72C-F14488369333}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EEF22C21-F380-4980-B72C-F14488369333}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -237,6 +243,7 @@ Global
{F7FBADEB-D766-4595-949A-07104B52692C} = {B337509B-75F9-4851-821F-9BBE87C4E4BC}
{5E488583-391E-4E15-83C1-7301B4FE79AE} = {B337509B-75F9-4851-821F-9BBE87C4E4BC}
{7191E567-38DF-4879-82E1-73EC618AFCAC} = {A0F5CC7E-155F-4726-8DEB-E966950B3FE9}
{EEF22C21-F380-4980-B72C-F14488369333} = {15070C49-A507-4844-BCFE-D319CFBC9A63}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {63A57886-054B-476C-AAE1-8D7C8917682E}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@
<ProjectReference Include="..\..\src\EasyCaching.Memcached\EasyCaching.Memcached.csproj" />
<ProjectReference Include="..\..\src\EasyCaching.Redis\EasyCaching.Redis.csproj" />
<ProjectReference Include="..\..\src\EasyCaching.ResponseCaching\EasyCaching.ResponseCaching.csproj" />
<ProjectReference Include="..\..\src\EasyCaching.SQLite\EasyCaching.SQLite.csproj" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\serialization\EasyCaching.Serialization.Json\EasyCaching.Serialization.Json.csproj" />
<ProjectReference Include="..\..\serialization\EasyCaching.Serialization.MessagePack\EasyCaching.Serialization.MessagePack.csproj" />
<ProjectReference Include="..\..\serialization\EasyCaching.Serialization.Protobuf\EasyCaching.Serialization.Protobuf.csproj" />
<ProjectReference Include="..\..\src\EasyCaching.SQLite\EasyCaching.SQLite.csproj" />
<ProjectReference Include="..\..\serialization\EasyCaching.Serialization.MemoryPack\EasyCaching.Serialization.MemoryPack.csproj" />
</ItemGroup>

</Project>
76 changes: 51 additions & 25 deletions sample/EasyCaching.Demo.ConsoleApp/Program.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
using System.Threading.Tasks;
using EasyCaching.Serialization.MemoryPack;

namespace EasyCaching.Demo.ConsoleApp
{
using EasyCaching.Core;
using EasyCaching.SQLite;
using MemoryPack;
using Microsoft.Extensions.DependencyInjection;
using System;

Expand All @@ -16,15 +17,18 @@ static void Main(string[] args)
IServiceCollection services = new ServiceCollection();
services.AddEasyCaching(option =>
{
option.WithMemoryPack(configure =>
{
}, "mempack");

option.UseInMemory("m1");

// option.UseRedis(config =>
// {
// config.DBConfig = new Redis.RedisDBOptions { Configuration = "localhost" };
// config.SerializerName = "json";
// }, "r1");
//

option.UseRedis((options) =>
{
options.SerializerName = "mempack";
options.DBConfig.Endpoints.Add(new Core.Configurations.ServerEndPoint("localhost", 6388));
}, "r1");

option.UseSQLite(c =>
{
c.DBConfig = new SQLiteDBOptions
Expand All @@ -43,7 +47,7 @@ static void Main(string[] args)

IServiceProvider serviceProvider = services.BuildServiceProvider();
var factory = serviceProvider.GetService<IEasyCachingProviderFactory>();

// var redisCache = factory.GetCachingProvider("r1");
//
// redisCache.Set<Product>("rkey", new Product() { Name = "test" }, TimeSpan.FromSeconds(20));
Expand All @@ -55,41 +59,63 @@ static void Main(string[] args)
// Console.WriteLine($"redis cache get value, {redisVal.HasValue} {redisVal.IsNull} {redisVal.Value}");



var mCache = factory.GetCachingProvider("m1");

mCache.Set<Product>("mkey1", new Product() { Name = "test" }, TimeSpan.FromSeconds(20));

var mVal1 = mCache.Get<Product>("mkey1");
var rCache = factory.GetCachingProvider("r1");

var prod = new Product()
{
Name = "Name1",
Lastname = "Lastname1",
Inner = new()
{
Name = "Name2",
Lastname = "Lastname2"
}
};

prod.Inner.Inner = prod;
rCache.Set<Product>("mkey1", prod, TimeSpan.FromSeconds(20));

var mVal1 = rCache.Get<Product>("mkey1");

rCache.Set<string>("mkey", "mvalue", TimeSpan.FromSeconds(20));

var mVal = rCache.Get<string>("mkey");

var mAllKey = rCache.GetAllKeysByPrefix("mk");

mCache.Set<string>("mkey", "mvalue", TimeSpan.FromSeconds(20));

var mVal = mCache.Get<string>("mkey");

var mAllKey = mCache.GetAllKeysByPrefix("mk");

Console.WriteLine($"in-memory cache get value, {mVal.HasValue} {mVal.IsNull} {mVal.Value} ");


var sCache = factory.GetCachingProvider("s1");


sCache.Set<string>("skey", "svalue", TimeSpan.FromSeconds(20));


var sVal = sCache.Get<string>("skey");


Console.WriteLine($"sqlite cache get value, {sVal.HasValue} {sVal.IsNull} {sVal.Value} ");

Console.ReadKey();
}
}

public class Product
[MemoryPackable(GenerateType.CircularReference)]
public partial class Product
{

[MemoryPackOrder(0)]
public string Name { get; set; }

[MemoryPackOrder(1)]

public string Lastname { get; set; }

[MemoryPackOrder(2)]

public Product Inner { set; get; }
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using MemoryPack;

namespace EasyCaching.Serialization.MemoryPack;

/// <summary>
/// EasyCaching memory pack serializer options.
/// </summary>
public record EasyCachingMemPackSerializerOptions
{
public StringEncoding StringEncoding { set; get; }
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using MemoryPack;
using EasyCaching.Core.Configurations;
using EasyCaching.Serialization.Json;

namespace EasyCaching.Serialization.MemoryPack;

/// <summary>
/// Easy caching options extensions.
/// </summary>
public static class EasyCachingOptionsExtensions
{
/// <summary>
/// Withs the memory pack serializer.
/// </summary>
/// <param name="options">Options.</param>
/// <param name="name">The name of this serializer instance.</param>
public static EasyCachingOptions WithMemoryPack(this EasyCachingOptions options, string name = "mempack")
{
options.RegisterExtension(new MemoryPackOptionsExtension(name, null));

return options;
}

/// <summary>
/// Withs the memory pack serializer.
/// </summary>
/// <param name="options">Options.</param>
/// <param name="configure">Configure serializer settings.</param>
/// <param name="name">The name of this serializer instance.</param>
public static EasyCachingOptions WithMemoryPack(this EasyCachingOptions options, Action<EasyCachingMemPackSerializerOptions> serializerOptions, string name)
{
options.RegisterExtension(new MemoryPackOptionsExtension(name, serializerOptions));

return options;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
namespace EasyCaching.Serialization.Json;

using System;
using EasyCaching.Core.Configurations;
using EasyCaching.Core.Serialization;
using EasyCaching.Serialization.MemoryPack;
using global::MemoryPack;
using Microsoft.Extensions.DependencyInjection;

/// <summary>
/// MemoryPack options extension.
/// </summary>
internal sealed class MemoryPackOptionsExtension : IEasyCachingOptionsExtension
{
/// <summary>
/// The name.
/// </summary>
private readonly string _name;

/// <summary>
/// The configure.
/// </summary>
private readonly Action<EasyCachingMemPackSerializerOptions> _configure;

/// <summary>
/// Initializes a new instance of the <see cref="T:EasyCaching.Serialization.MemoryPack.MemoryPackOptionsExtension"/> class.
/// </summary>
/// <param name="name">Name.</param>
/// <param name="configure">Configure.</param>
public MemoryPackOptionsExtension(string name, Action<EasyCachingMemPackSerializerOptions> configure)
{
this._name = name;
this._configure = configure;
}

/// <summary>
/// Adds the services.
/// </summary>
/// <param name="services">Services.</param>
public void AddServices(IServiceCollection services)
{
Action<EasyCachingMemPackSerializerOptions> configure = _configure ?? (_ => { });

services.AddOptions();
services.Configure(_name, configure);

services.AddSingleton<IEasyCachingSerializer, DefaultMemoryPackSerializer>(x =>
{
var optionsMon = x.GetRequiredService<Microsoft.Extensions.Options.IOptionsMonitor<EasyCachingMemPackSerializerOptions>>();
var easyCachingOptions = optionsMon.Get(_name);
var options = new MemoryPackSerializerOptions { StringEncoding = easyCachingOptions.StringEncoding };
return new DefaultMemoryPackSerializer(_name, options);
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using EasyCaching.Core.Serialization;
using MemoryPack;

namespace EasyCaching.Serialization.MemoryPack;

/// <summary>
/// Default MemoryPack serializer
/// </summary>
public class DefaultMemoryPackSerializer : IEasyCachingSerializer
{
private readonly string _name;
private readonly MemoryPackSerializerOptions _memoryPackSerializerOptions;

public string Name => _name;

public DefaultMemoryPackSerializer(string name, MemoryPackSerializerOptions options = null)
{
_name = name;
_memoryPackSerializerOptions = options;
}

public T Deserialize<T>(byte[] bytes) => MemoryPackSerializer.Deserialize<T>(bytes, _memoryPackSerializerOptions);
public object Deserialize(byte[] bytes, Type type) => MemoryPackSerializer.Deserialize(type, bytes, _memoryPackSerializerOptions);
public object DeserializeObject(ArraySegment<byte> value) => throw new NotImplementedException("this is not supported in MemoryPack serializer");
public byte[] Serialize<T>(T value) => MemoryPackSerializer.Serialize(value, _memoryPackSerializerOptions);

public ArraySegment<byte> SerializeObject(object obj)
{
var bytes = MemoryPackSerializer.Serialize(obj.GetType(), obj, _memoryPackSerializerOptions);
return new ArraySegment<byte>(bytes);
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\EasyCaching.Core\EasyCaching.Core.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="MemoryPack" Version="1.9.7" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -765,7 +765,7 @@ public async Task Remove_Cached_Value_Async_Should_Succeed()
var cacheValue = "value";

await _provider.SetAsync(cacheKey, cacheValue, _defaultTs);
var valBeforeRemove = await _provider.GetAsync<string>(cacheKey, null, _defaultTs);
var valBeforeRemove = await _provider.GetAsync<string>(cacheKey, () => null, _defaultTs);
Assert.NotNull(valBeforeRemove);

await _provider.RemoveAsync(cacheKey);
Expand Down Expand Up @@ -870,15 +870,15 @@ protected virtual async Task RemoveByPrefixAsync_Should_Succeed()
}

#endregion

#region RemoveByPattern/RemoveByPatternAsync

[Fact]
public virtual void RemoveByPattern_Should_Succeed()
{
SetCacheItem("garden:pots:flowers", "ok");
SetCacheItem("garden:pots:flowers:test", "ok");
SetCacheItem("garden:flowerspots:test", "ok" );
SetCacheItem("garden:flowerspots:test", "ok");
SetCacheItem("boo:foo", "ok");
SetCacheItem("boo:test:foo", "ok");
SetCacheItem("sky:birds:bar", "ok");
Expand Down Expand Up @@ -933,13 +933,13 @@ public virtual void RemoveByPattern_Should_Succeed()
Assert.False(val15.HasValue);
Assert.False(val16.HasValue);
}

[Fact]
public virtual async Task RemoveByPatternAsync_Should_Succeed()
{
SetCacheItem("garden:pots:flowers", "ok");
SetCacheItem("garden:pots:flowers:test", "ok");
SetCacheItem("garden:flowerspots:test", "ok" );
SetCacheItem("garden:flowerspots:test", "ok");
SetCacheItem("boo:foo", "ok");
SetCacheItem("boo:test:foo", "ok");
SetCacheItem("sky:birds:bar", "ok");
Expand Down
Loading

0 comments on commit db8c5af

Please sign in to comment.