Skip to content

Commit

Permalink
Merge pull request #1 from InCerryGit/ls_opt
Browse files Browse the repository at this point in the history
Optimization performance
  • Loading branch information
InCerryGit authored Nov 24, 2022
2 parents da7683a + aa5ca5c commit 7af981d
Show file tree
Hide file tree
Showing 21 changed files with 272 additions and 121 deletions.
2 changes: 1 addition & 1 deletion benchmark/FasterKvCache.Benchmark/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public enum TestType
#nullable disable
public class FasterKvBenchmark
{
private const long Count = 1000;
private const long Count = 10000;
private static readonly Random _random = new Random(1024);
private FasterKvCache<string> _provider;
private static readonly TimeSpan _default = TimeSpan.FromSeconds(30);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using FasterKv.Cache.Core;
using FasterKv.Cache.Core.Abstractions;
using FasterKv.Cache.Core.Configurations;
using FasterKv.Cache.MessagePack;

Expand Down
1 change: 1 addition & 0 deletions sample/FasterKvCache.Sample.ConsoleApp/TFasterKvCache.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using FasterKv.Cache.Core;
using FasterKv.Cache.Core.Abstractions;
using FasterKv.Cache.Core.Configurations;
using FasterKv.Cache.MessagePack;

Expand Down
7 changes: 3 additions & 4 deletions src/FasterKv.Cache.Core/Abstractions/ClientSessionWrap.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
using System;
using System.Collections.Concurrent;
using FASTER.core;
using FasterKv.Cache.Core.Abstractions;

namespace FasterKv.Cache.Core;
namespace FasterKv.Cache.Core.Abstractions;

public class ClientSessionWrap<TValue> : IDisposable
internal sealed class ClientSessionWrap<TValue> : IDisposable
{
public ClientSession<string, ValueWrapper<TValue>, ValueWrapper<TValue>, ValueWrapper<TValue>,
StoreContext<ValueWrapper<TValue>>, StoreFunctions<string, ValueWrapper<TValue>>> Session { get; }
Expand All @@ -31,7 +30,7 @@ public void Dispose()
}
}

public class ClientSessionWrap : IDisposable
internal class ClientSessionWrap : IDisposable
{
public ClientSession<string, ValueWrapper, ValueWrapper, ValueWrapper,
StoreContext<ValueWrapper>, StoreFunctions<string, ValueWrapper>> Session { get; }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
namespace FasterKv.Cache.Core;
using System.IO;

namespace FasterKv.Cache.Core;

public interface IFasterKvCacheSerializer
{
string Name { get;}
byte[] Serialize<TValue>(TValue data);
TValue? Deserialize<TValue>(byte[] serializerData);
void Serialize<TValue>(Stream stream, TValue data);
TValue? Deserialize<TValue>(byte[] bytes, int length);
}
2 changes: 1 addition & 1 deletion src/FasterKv.Cache.Core/Abstractions/ISystemClock.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;

namespace FasterKv.Cache.Core;
namespace FasterKv.Cache.Core.Abstractions;

public interface ISystemClock
{
Expand Down
4 changes: 2 additions & 2 deletions src/FasterKv.Cache.Core/Abstractions/StoreFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace FasterKv.Cache.Core.Abstractions;

public class StoreContext<TOutput>
internal sealed class StoreContext<TOutput>
{
private Status _status;
private TOutput? _output;
Expand All @@ -20,7 +20,7 @@ internal void FinalizeRead(out Status status, out TOutput output)
}
}

public class StoreFunctions<TKey, TOutput> : SimpleFunctions<TKey, TOutput, StoreContext<TOutput>>
internal sealed class StoreFunctions<TKey, TOutput> : SimpleFunctions<TKey, TOutput, StoreContext<TOutput>>
{
public override void ReadCompletionCallback(ref TKey key,
ref TOutput input,
Expand Down
27 changes: 14 additions & 13 deletions src/FasterKv.Cache.Core/Abstractions/ValueWrapper.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
using System;
using MessagePack;
using System.Buffers;

namespace FasterKv.Cache.Core;

public struct ValueWrapper<T>
internal struct ValueWrapper<T>
{
public ValueWrapper()
{

}

public ValueWrapper(T? data, DateTimeOffset? expiryTime = null)
public ValueWrapper(T? data, long? expiryTime = null)
{
ExpiryTime = expiryTime;
Data = data;
Expand All @@ -24,27 +24,27 @@ public ValueWrapper(T? data, DateTimeOffset? expiryTime = null)
/// <summary>
/// Expiry Time
/// </summary>
public DateTimeOffset? ExpiryTime { get; set; }
public long? ExpiryTime { get; set; }

/// <summary>
/// HasExpired
/// </summary>
/// <param name="now">Now</param>
/// <returns>value has expired</returns>
public bool HasExpired(DateTimeOffset now) => now > ExpiryTime;
public bool HasExpired(DateTimeOffset now) => now.ToUnixTimeMilliseconds() > ExpiryTime;
}

[MessagePackObject]
public class ValueWrapper
internal sealed class ValueWrapper
{
internal int DataByteLength = 0;
internal object? Data;

public ValueWrapper()
{

}

public ValueWrapper(object? data, DateTimeOffset? expiryTime = null)
public ValueWrapper(object? data, long? expiryTime = null)
{
ExpiryTime = expiryTime;
Data = data;
Expand All @@ -53,21 +53,19 @@ public ValueWrapper(object? data, DateTimeOffset? expiryTime = null)
/// <summary>
/// Expiry Time
/// </summary>
[Key(0)]
public DateTimeOffset? ExpiryTime { get; set; }
public long? ExpiryTime { get; set; }

/// <summary>
/// DataBytes
/// </summary>
[Key(1)]
public byte[]? DataBytes { get; set; }

/// <summary>
/// HasExpired
/// </summary>
/// <param name="now">Now</param>
/// <returns>value has expired</returns>
public bool HasExpired(DateTimeOffset now) => now > ExpiryTime;
public bool HasExpired(DateTimeOffset now) => now.ToUnixTimeMilliseconds() > ExpiryTime;

/// <summary>
/// Get TValue From Data or DataBytes
Expand All @@ -79,8 +77,11 @@ public ValueWrapper(object? data, DateTimeOffset? expiryTime = null)
{
if (DataBytes is not null)
{
Data = serializer.Deserialize<TValue>(DataBytes);
Data = serializer.Deserialize<TValue>(DataBytes, DataByteLength);
var bytes = DataBytes;
DataBytes = null;
DataByteLength = 0;
ArrayPool<byte>.Shared.Return(bytes);
}

return Data is null ? default : (TValue)Data;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using FasterKv.Cache.Core.Abstractions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
Expand Down
2 changes: 0 additions & 2 deletions src/FasterKv.Cache.Core/FasterKv.Cache.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="MessagePack" Version="2.4.35" />
<PackageReference Include="Microsoft.FASTER.Core" Version="2.1.0" />
<PackageReference Include="System.Text.Json" Version="7.0.0" />
</ItemGroup>

</Project>
13 changes: 11 additions & 2 deletions src/FasterKv.Cache.Core/FasterKvCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,12 @@ public async Task SetAsync<TValue>(string key, TValue? value, TimeSpan expiryTim
private async Task SetInternalAsync<TValue>(ClientSessionWrap sessionWrap, string key, TValue? value,
CancellationToken cancellationToken, TimeSpan? expiryTime = null)
{
var wrapper = new ValueWrapper(value, expiryTime.HasValue ? _systemClock.Now().Add(expiryTime.Value) : null);
var wrapper = new ValueWrapper(value,
expiryTime.HasValue
? _systemClock.Now()
.Add(expiryTime.Value)
.ToUnixTimeMilliseconds()
: null);
(await sessionWrap.Session.UpsertAsync(ref key, ref wrapper, token: cancellationToken)
.ConfigureAwait(false)).Complete();
}
Expand All @@ -184,7 +189,11 @@ private void SetInternal<TValue>(ClientSessionWrap sessionWrap, string key, TVal
TimeSpan? expiryTime = null)
{
var wrapper = new ValueWrapper(value,
expiryTime.HasValue ? _systemClock.Now().Add(expiryTime.Value) : null);
expiryTime.HasValue
? _systemClock.Now()
.Add(expiryTime.Value)
.ToUnixTimeMilliseconds()
: null);
sessionWrap.Session.Upsert(ref key, ref wrapper);
}

Expand Down
4 changes: 2 additions & 2 deletions src/FasterKv.Cache.Core/FasterKvStore.TValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,15 +171,15 @@ private void SetInternal(ClientSessionWrap<TValue> sessionWrap, string key, TVal
TimeSpan? expiryTime = null)
{
var wrapper = new ValueWrapper<TValue>(value,
expiryTime.HasValue ? _systemClock.Now().Add(expiryTime.Value) : null);
expiryTime.HasValue ? _systemClock.Now().Add(expiryTime.Value).ToUnixTimeMilliseconds() : null);
sessionWrap.Session.Upsert(ref key, ref wrapper);
}

private async Task SetInternalAsync(ClientSessionWrap<TValue> sessionWrap, string key, TValue? value,
CancellationToken cancellationToken, TimeSpan? expiryTime = null)
{
var wrapper = new ValueWrapper<TValue>(value,
expiryTime.HasValue ? _systemClock.Now().Add(expiryTime.Value) : null);
expiryTime.HasValue ? _systemClock.Now().Add(expiryTime.Value).ToUnixTimeMilliseconds() : null);
(await sessionWrap.Session.UpsertAsync(ref key, ref wrapper, token: cancellationToken)
.ConfigureAwait(false)).Complete();
}
Expand Down
80 changes: 38 additions & 42 deletions src/FasterKv.Cache.Core/Serializers/FasterKvSerializer.TValue.cs
Original file line number Diff line number Diff line change
@@ -1,65 +1,61 @@
using System;
using System.IO;
using System.Buffers;
using FASTER.core;
using MessagePack;

namespace FasterKv.Cache.Core.Serializers;

public class FasterKvSerializer<TValue> : IObjectSerializer<ValueWrapper<TValue>>
internal sealed class FasterKvSerializer<TValue> : BinaryObjectSerializer<ValueWrapper<TValue>>
{
private Stream? _read;
private Stream? _write;
private readonly IFasterKvCacheSerializer _serializer;

public FasterKvSerializer(IFasterKvCacheSerializer serializer)
{
_serializer = serializer.ArgumentNotNull();
}

public void BeginSerialize(Stream stream)
public override void Deserialize(out ValueWrapper<TValue> obj)
{
_write = stream;
}

public void Serialize(ref ValueWrapper<TValue> obj)
{
var pack = new DataPack
obj = new ValueWrapper<TValue>();
var etNullFlag = reader.ReadByte();
if (etNullFlag == 1)
{
ExpiryTime = obj.ExpiryTime,
SerializerData = _serializer.Serialize(obj.Data)
};
MessagePackSerializer.Serialize(_write, pack);
}
obj.ExpiryTime = reader.ReadInt64();
}

public void BeginDeserialize(Stream stream)
{
_read = stream;
var dataLength = reader.ReadInt32();
var buffer = ArrayPool<byte>.Shared.Rent(dataLength);
try
{
_ = reader.Read(buffer, 0, dataLength);
obj.Data = _serializer.Deserialize<TValue>(buffer, dataLength);
}
finally
{
ArrayPool<byte>.Shared.Return(buffer);
}
}

public void Deserialize(out ValueWrapper<TValue> obj)
public override void Serialize(ref ValueWrapper<TValue> obj)
{
var pack = MessagePackSerializer.Deserialize<DataPack>(_read);
obj = new ValueWrapper<TValue>(_serializer.Deserialize<TValue>(pack.SerializerData), pack.ExpiryTime);
}
if (obj.ExpiryTime is null)
{
// write Expiry Time is null flag
writer.Write((byte)0);
}
else
{
writer.Write((byte)1);
writer.Write(obj.ExpiryTime.Value);
}

public void EndSerialize()
{
}
var beforePos = writer.BaseStream.Position;
var dataPos = writer.BaseStream.Position = writer.BaseStream.Position += sizeof(int);
_serializer.Serialize(writer.BaseStream, obj.Data);
var afterPos = writer.BaseStream.Position;

public void EndDeserialize()
{
}

[MessagePackObject]
public struct DataPack
{
/// <summary>
/// Expiry Time
/// </summary>
[Key(0)]
public DateTimeOffset? ExpiryTime { get; set; }
var length = (int)(afterPos - dataPos);
writer.BaseStream.Position = beforePos;

[Key(1)]
public byte[] SerializerData { get; set; }
writer.Write(length);
writer.BaseStream.Position = afterPos;
}
}
Loading

0 comments on commit 7af981d

Please sign in to comment.