diff --git a/PartitionFileStorageTest/PartitionFileStorageTest.csproj b/PartitionFileStorageTest/PartitionFileStorageTest.csproj
index 6fb9333..b95bc06 100644
--- a/PartitionFileStorageTest/PartitionFileStorageTest.csproj
+++ b/PartitionFileStorageTest/PartitionFileStorageTest.csproj
@@ -8,7 +8,7 @@
-
+
diff --git a/PartitionFileStorageTest/Program.cs b/PartitionFileStorageTest/Program.cs
index ecc89d9..ae51b5e 100644
--- a/PartitionFileStorageTest/Program.cs
+++ b/PartitionFileStorageTest/Program.cs
@@ -31,50 +31,67 @@ namespace PartitionFileStorageTest
return num_base + (uint)r.Next(999999);
}
- private static void FastTest(StoreOptions options)
+ private static async Task FastTest(StoreOptions options)
{
var r = new Random(Environment.TickCount);
- var store = new Store(options);
- var storePart = store.CreateBuilder(new Metadata { Date = new DateTime(2022, 11, 08) });
+ var store = new Store(options, new StoreSerializers(
+ async (w, n) => await w.WriteULongAsync(n),
+ async (w, n) => await w.WriteULongAsync(n),
+ async (r) => { try { return new DeserializeResult(true, await r.ReadULongAsync()); } catch { return new DeserializeResult(false, 0); } },
+ async (r) => { try { return new DeserializeResult(true, await r.ReadULongAsync()); } catch { return new DeserializeResult(false, 0); } },
+ async (r) => { try { return new DeserializeResult(true, await r.ReadBytesAsync()); } catch { return new DeserializeResult(false, new byte[0]); } }));
- Console.WriteLine("Small test start");
var c1 = (ulong)(86438 * 128);
var c2 = (ulong)(83438 * 128);
var c3 = (ulong)(831238 * 128);
- storePart.Store(c1, Generate(r));
- storePart.Store(c1, Generate(r));
- storePart.Store(c1, Generate(r));
- storePart.Store(c2, Generate(r));
- storePart.Store(c2, Generate(r));
- storePart.Store(c2, Generate(r));
- storePart.Store(c2, Generate(r));
- storePart.Store(c2, Generate(r));
- storePart.Store(c3, Generate(r));
- storePart.Store(c3, Generate(r));
- storePart.Store(c3, Generate(r));
- storePart.CompleteAdding();
- storePart.Compress();
- var readPart = store.CreateAccessor(new Metadata { Date = new DateTime(2022, 11, 08) });
- Console.WriteLine("Data:");
- foreach (var e in readPart.Iterate())
- {
- Console.WriteLine($"{e.Key}: {e.Value.Length}");
+ using (var storePart = store.CreateBuilder(new Metadata { Date = new DateTime(2022, 11, 08) }))
+ {
+ Console.WriteLine("Small test start");
+ await storePart.Store(c1, Generate(r));
+ await storePart.Store(c1, Generate(r));
+ await storePart.Store(c1, Generate(r));
+ await storePart.Store(c2, Generate(r));
+ await storePart.Store(c2, Generate(r));
+ await storePart.Store(c2, Generate(r));
+ await storePart.Store(c2, Generate(r));
+ await storePart.Store(c2, Generate(r));
+ await storePart.Store(c3, Generate(r));
+ await storePart.Store(c3, Generate(r));
+ await storePart.Store(c3, Generate(r));
+ storePart.CompleteAdding();
+ await storePart.Compress();
}
- readPart.RemoveKey(c1);
- Console.WriteLine("Data after remove:");
- foreach (var e in readPart.Iterate())
+
+ using (var readPart = store.CreateAccessor(new Metadata { Date = new DateTime(2022, 11, 08) }))
{
- Console.WriteLine($"{e.Key}: {e.Value.Length}");
+ Console.WriteLine("Data:");
+ await foreach (var kv in readPart.Iterate())
+ {
+ Console.WriteLine($"{kv.Key}: {kv.Value.Length}");
+ }
+
+ await readPart.RemoveKey(c1);
+ Console.WriteLine("Data after remove:");
+
+ await foreach (var kv in readPart.Iterate())
+ {
+ Console.WriteLine($"{kv.Key}: {kv.Value.Length}");
+ }
}
}
- private static void FullStoreTest(StoreOptions options,
+ private static async Task FullStoreTest(StoreOptions options,
List<(ulong, ulong)> pairs)
{
var meta = new Metadata { Date = new DateTime(2022, 11, 08) };
var r = new Random(Environment.TickCount);
- var store = new Store(options);
+ var store = new Store(options, new StoreSerializers(
+ async (w, n) => await w.WriteULongAsync(n),
+ async (w, n) => await w.WriteULongAsync(n),
+ async (r) => { try { return new DeserializeResult(true, await r.ReadULongAsync()); } catch { return new DeserializeResult(false, 0); } },
+ async (r) => { try { return new DeserializeResult(true, await r.ReadULongAsync()); } catch { return new DeserializeResult(false, 0); } },
+ async (r) => { try { return new DeserializeResult(true, await r.ReadBytesAsync()); } catch { return new DeserializeResult(false, new byte[0]); } }));
var storePart = store.CreateBuilder(meta);
var sw = new Stopwatch();
sw.Start();
@@ -90,7 +107,7 @@ namespace PartitionFileStorageTest
var val = pairs[i].Item2;
if (testData.ContainsKey(key) == false) testData[key] = new HashSet();
testData[key].Add(val);
- storePart.Store(key, val);
+ await storePart.Store(key, val);
if (key % 717 == 0)
{
testKeys1.Add(key);
@@ -105,7 +122,7 @@ namespace PartitionFileStorageTest
Log.Info($"Fill journal: {sw.ElapsedMilliseconds}ms. Records writed: {storePart.TotalRecords}");
sw.Restart();
storePart.CompleteAdding();
- storePart.Compress();
+ await storePart.Compress();
sw.Stop();
Log.Info($"Compress: {sw.ElapsedMilliseconds}ms");
sw.Restart();
@@ -135,7 +152,7 @@ namespace PartitionFileStorageTest
ulong totalKeys = 0;
foreach (var key in testKeys1)
{
- var result = readPart.Find(key);
+ var result = readPart.Find(key).Result;
totalData += (ulong)(result.Value?.Length ?? 0);
totalKeys++;
}
@@ -145,7 +162,7 @@ namespace PartitionFileStorageTest
Log.Info("Test #1 remove by keys");
for (int i = 0; i < testKeys1.Count; i++)
{
- readPart.RemoveKey(testKeys1[i], false);
+ await readPart.RemoveKey(testKeys1[i], false);
}
sw.Restart();
readPart.RebuildIndex();
@@ -155,7 +172,7 @@ namespace PartitionFileStorageTest
foreach (var key in testKeys1)
{
var result = readPart.Find(key);
- totalData += (ulong)(result.Value?.Length ?? 0);
+ totalData += (ulong)(result.Result.Value?.Length ?? 0);
totalKeys++;
}
Log.Info($"\t\tFound: {totalKeys} keys. {totalData} bytes");
@@ -165,19 +182,19 @@ namespace PartitionFileStorageTest
foreach (var key in testKeys2)
{
var result = readPart.Find(key);
- totalData += (ulong)(result.Value?.Length ?? 0);
+ totalData += (ulong)(result.Result.Value?.Length ?? 0);
totalKeys++;
}
Log.Info($"\t\tFound: {totalKeys} keys. {totalData} bytes");
totalData = 0;
totalKeys = 0;
Log.Info("Test #2 remove keys batch");
- readPart.RemoveKeys(testKeys2);
+ await readPart.RemoveKeys(testKeys2);
Log.Info("Test #2 reading after remove");
foreach (var key in testKeys2)
{
var result = readPart.Find(key);
- totalData += (ulong)(result.Value?.Length ?? 0);
+ totalData += (ulong)(result.Result.Value?.Length ?? 0);
totalKeys++;
}
Log.Info($"\t\tFound: {totalKeys} keys. {totalData} bytes");
@@ -185,11 +202,12 @@ namespace PartitionFileStorageTest
totalKeys = 0;
Log.Info("Iterator test");
- foreach (var e in readPart.Iterate())
+ await foreach (var kv in readPart.Iterate())
{
- totalData += (ulong)(e.Value?.Length ?? 0);
+ totalData += (ulong)(kv.Value?.Length ?? 0);
totalKeys++;
}
+
Log.Info($"\t\tFound: {totalKeys} keys. {totalData} bytes");
totalData = 0;
totalKeys = 0;
@@ -199,7 +217,7 @@ namespace PartitionFileStorageTest
{
if (test.Value.Count > 0 && testKeys1.Contains(test.Key) == false && testKeys2.Contains(test.Key) == false)
{
- var result = Compressor.DecodeBytesContent(readPart.Find(test.Key).Value).ToHashSet();
+ var result = Compressor.DecodeBytesContent(readPart.Find(test.Key).Result.Value).ToHashSet();
if (test.Value.Count != result.Count)
{
Log.Info($"Key '{test.Key}' not found!");
@@ -227,12 +245,17 @@ namespace PartitionFileStorageTest
}
}
- private static void FullStoreMultithreadTest(StoreOptions options)
+ private static async Task FullStoreMultithreadTest(StoreOptions options)
{
var meta = new Metadata { Date = new DateTime(2022, 11, 08) };
var r = new Random(Environment.TickCount);
- var store = new Store(options);
- var storePart = store.CreateBuilder(meta);
+ var store = new Store(options, new StoreSerializers(
+ async (w, n) => await w.WriteULongAsync(n),
+ async (w, n) => await w.WriteULongAsync(n),
+ async (r) => { try { return new DeserializeResult(true, await r.ReadULongAsync()); } catch { return new DeserializeResult(false, 0); } },
+ async (r) => { try { return new DeserializeResult(true, await r.ReadULongAsync()); } catch { return new DeserializeResult(false, 0); } },
+ async (r) => { try { return new DeserializeResult(true, await r.ReadBytesAsync()); } catch { return new DeserializeResult(false, new byte[0]); } }));
+
var sw = new Stopwatch();
sw.Start();
var insertCount = (long)(0.7 * PAIRS_COUNT);
@@ -241,58 +264,60 @@ namespace PartitionFileStorageTest
var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = 24 };
var Keys = new ConcurrentHashSet();
- Parallel.ForEach(MassGenerator((long)(0.7 * PAIRS_COUNT)), parallelOptions, pair =>
+ using (var storePart = store.CreateBuilder(meta))
{
- var key = pair.Item1;
- var val = pair.Item2;
- storePart.Store(key, val);
- if (key % 717 == 0)
+ Parallel.ForEach(MassGenerator((long)(0.7 * PAIRS_COUNT)), parallelOptions, pair =>
{
- testKeys1.Add(key);
- }
- if (key % 117 == 0)
+ var key = pair.Item1;
+ var val = pair.Item2;
+ storePart.Store(key, val);
+ if (key % 717 == 0)
+ {
+ testKeys1.Add(key);
+ }
+ if (key % 117 == 0)
+ {
+ testKeys2.Add(key);
+ }
+ Keys.Add(key);
+ });
+ if (storePart.TotalRecords != insertCount)
{
- testKeys2.Add(key);
+ Log.Error($"Count of stored record no equals expected. Recorded: {storePart.TotalRecords}. Expected: {insertCount}. Unique keys: {Keys.Count}");
}
- Keys.Add(key);
- });
-
- if (storePart.TotalRecords != insertCount)
- {
- Log.Error($"Count of stored record no equals expected. Recorded: {storePart.TotalRecords}. Expected: {insertCount}. Unique keys: {Keys.Count}");
+ sw.Stop();
+ Log.Info($"Fill journal: {sw.ElapsedMilliseconds}ms");
+ sw.Restart();
+ storePart.CompleteAdding();
+ await storePart.Compress();
+ sw.Stop();
+ Log.Info($"Compress: {sw.ElapsedMilliseconds}ms");
+ sw.Restart();
+ storePart.RebuildIndex();
}
-
- sw.Stop();
- Log.Info($"Fill journal: {sw.ElapsedMilliseconds}ms");
- sw.Restart();
- storePart.CompleteAdding();
- storePart.Compress();
- sw.Stop();
- Log.Info($"Compress: {sw.ElapsedMilliseconds}ms");
- sw.Restart();
- storePart.RebuildIndex();
sw.Stop();
Log.Info($"Rebuild indexes: {sw.ElapsedMilliseconds}ms");
Log.Info("Start merge test");
sw.Restart();
- var merger = store.CreateMergeAccessor(meta, data => Compressor.DecodeBytesContent(data));
-
- Parallel.ForEach(MassGenerator((long)(0.3 * PAIRS_COUNT)), parallelOptions, pair =>
+ using (var merger = store.CreateMergeAccessor(meta, data => Compressor.DecodeBytesContent(data)))
{
- var key = pair.Item1;
- var val = pair.Item2;
- merger.Store(key, val);
- Keys.Add(key);
- });
+ Parallel.ForEach(MassGenerator((long)(0.3 * PAIRS_COUNT)), parallelOptions, pair =>
+ {
+ var key = pair.Item1;
+ var val = pair.Item2;
+ merger.Store(key, val);
+ Keys.Add(key);
+ });
- if (merger.TotalRecords != ((long)(0.3 * PAIRS_COUNT)))
- {
- Log.Error($"Count of stored record no equals expected. Recorded: {merger.TotalRecords}. Expected: {((long)(0.3 * PAIRS_COUNT))}");
- }
+ if (merger.TotalRecords != ((long)(0.3 * PAIRS_COUNT)))
+ {
+ Log.Error($"Count of stored record no equals expected. Recorded: {merger.TotalRecords}. Expected: {((long)(0.3 * PAIRS_COUNT))}");
+ }
- Log.Info($"Merge journal filled: {sw.ElapsedMilliseconds}ms. Total data count: {PAIRS_COUNT}. Unique keys: {Keys.Count}");
- merger.Compress(); // auto reindex
+ Log.Info($"Merge journal filled: {sw.ElapsedMilliseconds}ms. Total data count: {PAIRS_COUNT}. Unique keys: {Keys.Count}");
+ merger.Compress(); // auto reindex
+ }
sw.Stop();
Log.Info($"Compress after merge: {sw.ElapsedMilliseconds}ms");
@@ -300,10 +325,10 @@ namespace PartitionFileStorageTest
ulong totalKeys = 0;
var s = new HashSet();
- store.Bypass(meta, (k, v) =>
+ await foreach (var kv in store.Bypass(meta))
{
- s.Add(k);
- });
+ s.Add(kv.Key);
+ }
Log.Info($"Keys count: {s.Count}");
using (var readPart = store.CreateAccessor(meta))
@@ -343,14 +368,14 @@ namespace PartitionFileStorageTest
foreach (var key in testKeys2)
{
var result = readPart.Find(key);
- totalData += (ulong)(result.Value?.Length ?? 0);
+ totalData += (ulong)(result.Result.Value?.Length ?? 0);
totalKeys++;
}
Log.Info($"\t\tFound: {totalKeys}/{Keys.Count} keys. {totalData} bytes");
totalData = 0;
totalKeys = 0;
Log.Info("Test #2 remove keys batch");
- readPart.RemoveKeys(testKeys2);
+ await readPart.RemoveKeys(testKeys2);
foreach (var k in testKeys2)
{
Keys.TryRemove(k);
@@ -359,7 +384,7 @@ namespace PartitionFileStorageTest
foreach (var key in testKeys2)
{
var result = readPart.Find(key);
- totalData += (ulong)(result.Value?.Length ?? 0);
+ totalData += (ulong)(result.Result.Value?.Length ?? 0);
totalKeys++;
}
Log.Info($"\t\tFound: {totalKeys} keys. {totalData} bytes");
@@ -367,9 +392,9 @@ namespace PartitionFileStorageTest
totalKeys = 0;
Log.Info("Iterator test");
- foreach (var e in readPart.Iterate())
+ await foreach (var kv in readPart.Iterate())
{
- totalData += (ulong)(e.Value?.Length ?? 0);
+ totalData += (ulong)(kv.Value?.Length ?? 0);
totalKeys++;
}
}
@@ -380,7 +405,12 @@ namespace PartitionFileStorageTest
private static void FaultIndexTest(string filePath)
{
- var serializer = new StoreStandartSerializer();
+ var serializer = new StoreSerializers(
+ async (w, n) => await w.WriteULongAsync(n),
+ async (w, n) => await w.WriteULongAsync(n),
+ async (r) => { try { return new DeserializeResult(true, await r.ReadULongAsync()); } catch { return new DeserializeResult(false, 0); } },
+ async (r) => { try { return new DeserializeResult(true, await r.ReadULongAsync()); } catch { return new DeserializeResult(false, 0); } },
+ async (r) => { try { return new DeserializeResult(true, await r.ReadBytesAsync()); } catch { return new DeserializeResult(false, new byte[0]); } });
// 1 build index
var index = new Dictionary();
using (var reader = new MemoryStreamReader(new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 4096 * 1024)))
@@ -390,11 +420,13 @@ namespace PartitionFileStorageTest
{
counter--;
var pos = reader.Position;
- serializer.KeyDeserializer.Invoke(reader, out var k);
- serializer.ValueDeserializer.Invoke(reader, out var _);
+
+ var kv = serializer.KeyDeserializer.Invoke(reader).Result;
+ var vv = serializer.ValueDeserializer.Invoke(reader).Result;
+
if (counter == 0)
{
- index[k] = pos;
+ index[kv.Value] = pos;
counter = 16;
}
}
@@ -407,12 +439,12 @@ namespace PartitionFileStorageTest
var accessor = fileReader.GetAccessor(pair.Value);
using (var reader = new MemoryStreamReader(accessor))
{
- serializer.KeyDeserializer.Invoke(reader, out var k);
- if (k != pair.Key)
+ var kv = serializer.KeyDeserializer.Invoke(reader).Result;
+ if (kv.Value != pair.Key)
{
Log.Warning("Broken index");
}
- serializer.ValueDeserializer.Invoke(reader, out var _);
+ serializer.ValueDeserializer.Invoke(reader).Wait();
}
}
@@ -436,7 +468,12 @@ namespace PartitionFileStorageTest
private static void FaultUncompressedReadTest(string filePath)
{
- var serializer = new StoreStandartSerializer();
+ var serializer = new StoreSerializers(
+ async (w, n) => await w.WriteULongAsync(n),
+ async (w, n) => await w.WriteULongAsync(n),
+ async (r) => { try { return new DeserializeResult(true, await r.ReadULongAsync()); } catch { return new DeserializeResult(false, 0); } },
+ async (r) => { try { return new DeserializeResult(true, await r.ReadULongAsync()); } catch { return new DeserializeResult(false, 0); } },
+ async (r) => { try { return new DeserializeResult(true, await r.ReadBytesAsync()); } catch { return new DeserializeResult(false, new byte[0]); } });
// 1 build index
var dict = new Dictionary>();
using (var reader = new MemoryStreamReader(new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None, 4096 * 1024)))
@@ -445,17 +482,17 @@ namespace PartitionFileStorageTest
{
try
{
- serializer.KeyDeserializer.Invoke(reader, out var key);
- if (false == dict.ContainsKey(key))
+ var key = serializer.KeyDeserializer.Invoke(reader).Result;
+ if (false == dict.ContainsKey(key.Value))
{
- dict[key] = new HashSet();
+ dict[key.Value] = new HashSet();
}
if (reader.EOS)
{
break;
}
- serializer.InputDeserializer.Invoke(reader, out var input);
- dict[key].Add(input);
+ var input = serializer.InputDeserializer.Invoke(reader).Result;
+ dict[key.Value].Add(input.Value);
}
catch (Exception ex)
{
@@ -490,12 +527,17 @@ namespace PartitionFileStorageTest
KeyComparer = (left, right) => string.Compare(left, right, true),
ThreadSafeWriting = true
};
- var store = new Store(options);
+ var store = new Store(options, new StoreSerializers(
+ async (w, n) => await w.WriteStringAsync(n),
+ async (w, n) => await w.WriteULongAsync(n),
+ async (r) => { try { return new DeserializeResult(true, await r.ReadStringAsync()); } catch { return new DeserializeResult(false, string.Empty); } },
+ async (r) => { try { return new DeserializeResult(true, await r.ReadULongAsync()); } catch { return new DeserializeResult(false, 0); } },
+ async (r) => { try { return new DeserializeResult(true, await r.ReadBytesAsync()); } catch { return new DeserializeResult(false, new byte[0]); } }));
var builder = store.CreateBuilder(meta);
builder.Compress();
}
- static void Main(string[] args)
+ static async Task Main(string[] args)
{
//FaultCompressionTest(@"F:\Desktop\DATKA\DNS", new StoreMetadata { Date = new DateTime(2023, 01, 20) });
@@ -558,22 +600,23 @@ namespace PartitionFileStorageTest
}
*/
Log.Info("Start test");
- // FastTest(options);
+
FSUtils.CleanAndTestFolder(root);
- FullStoreMultithreadTest(optionsMultiThread);
+ await FastTest(options);
+ FSUtils.CleanAndTestFolder(root);
+ await FullStoreMultithreadTest(optionsMultiThread);
- /*
- FSUtils.CleanAndTestFolder(root);
- FullStoreTest(options, pairs);
- */
- //TestParallelFileReadingMMF();
- /*
-
+
+ /*FSUtils.CleanAndTestFolder(root);
+ FullStoreTest(options, pairs);*/
+
FSUtils.CleanAndTestFolder(root);
-
- */
+ //TestParallelFileReadingMMF();
+
+
+ Console.WriteLine("Completed");
Console.ReadKey();
}
diff --git a/TestApp/Program.cs b/TestApp/Program.cs
index 243d099..4ad4a61 100644
--- a/TestApp/Program.cs
+++ b/TestApp/Program.cs
@@ -1,21 +1,62 @@
using System;
+using System.Linq;
+using System.Reflection;
+using ZeroLevel.Services.Invokation;
+using ZeroLevel.Services.ObjectMapping;
+using ZeroLevel.Services.Serialization;
namespace TestApp
{
internal static class Program
{
- private static void Main(string[] args)
+ private class Wrapper
{
- AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
- }
+ public string ReadId;
+ public string WriteId;
+ public IInvokeWrapper Invoker;
- private static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs e)
- {
- if (e.Name.StartsWith("Microsoft.Build."))
+ public T Read(IBinaryReader reader)
+ {
+ return (T)Invoker.Invoke(reader, ReadId);
+ }
+
+ public object ReadObject(IBinaryReader reader)
+ {
+ return Invoker.Invoke(reader, ReadId);
+ }
+
+ public void Write(IBinaryWriter writer, T value)
+ {
+ Invoker.Invoke(writer, WriteId, new object[] { value });
+ }
+
+ public void WriteObject(IBinaryWriter writer, object value)
{
- // искать в локальной папке
+ Invoker.Invoke(writer, WriteId, new object[] { value });
}
- return null;
+ }
+
+ private static Func CreateArrayPredicate()
+ {
+ var typeArg = typeof(T).GetElementType();
+ return mi => mi.Name.Equals("WriteArray", StringComparison.Ordinal) &&
+ mi.GetParameters().First().ParameterType.GetElementType().IsAssignableFrom(typeArg);
+ }
+
+ private static Func CreateCollectionPredicate()
+ {
+ var typeArg = typeof(T).GetGenericArguments().First();
+ return mi => mi.Name.Equals("WriteCollection", StringComparison.Ordinal) &&
+ mi.GetParameters().First().ParameterType.GetGenericArguments().First().IsAssignableFrom(typeArg);
+ }
+
+ private static void Main(string[] args)
+ {
+ var wrapper = new Wrapper { Invoker = InvokeWrapper.Create() };
+ var ReadId = wrapper.Invoker.Configure(typeof(MemoryStreamReader), "ReadDateTimeArray").First();
+ var WriteId = wrapper.Invoker.Configure(typeof(MemoryStreamWriter), CreateArrayPredicate()).First();
+
+ Console.Write(WriteId);
}
}
}
\ No newline at end of file
diff --git a/TestApp/TestApp.csproj b/TestApp/TestApp.csproj
index 45fe2fd..0d41ae4 100644
--- a/TestApp/TestApp.csproj
+++ b/TestApp/TestApp.csproj
@@ -7,7 +7,7 @@
-
+
diff --git a/ZeroLevel.Discovery/ZeroLevel.Discovery.csproj b/ZeroLevel.Discovery/ZeroLevel.Discovery.csproj
index d23cfc5..d0cfea3 100644
--- a/ZeroLevel.Discovery/ZeroLevel.Discovery.csproj
+++ b/ZeroLevel.Discovery/ZeroLevel.Discovery.csproj
@@ -7,7 +7,7 @@
-
+
diff --git a/ZeroLevel.HNSW/ZeroLevel.HNSW.csproj b/ZeroLevel.HNSW/ZeroLevel.HNSW.csproj
index 34df9da..63d56ea 100644
--- a/ZeroLevel.HNSW/ZeroLevel.HNSW.csproj
+++ b/ZeroLevel.HNSW/ZeroLevel.HNSW.csproj
@@ -44,4 +44,8 @@
+
+
+
+
diff --git a/ZeroLevel.Qdrant/ZeroLevel.Qdrant.csproj b/ZeroLevel.Qdrant/ZeroLevel.Qdrant.csproj
index ec569e0..a0521fd 100644
--- a/ZeroLevel.Qdrant/ZeroLevel.Qdrant.csproj
+++ b/ZeroLevel.Qdrant/ZeroLevel.Qdrant.csproj
@@ -18,7 +18,7 @@
-
+
diff --git a/ZeroLevel.UnitTests/SerializationTests.cs b/ZeroLevel.UnitTests/SerializationTests.cs
index 4f2b1fa..8f15365 100644
--- a/ZeroLevel.UnitTests/SerializationTests.cs
+++ b/ZeroLevel.UnitTests/SerializationTests.cs
@@ -337,9 +337,9 @@ namespace ZeroLevel.Serialization
[Fact]
public void SerializeCollectionDateTime()
{
- MakeCollectionTest(null);
- MakeCollectionTest(new DateTime[] { });
- MakeCollectionTest(new DateTime[] { DateTime.Now, DateTime.UtcNow, DateTime.Today, DateTime.Now.AddYears(2000), DateTime.MinValue, DateTime.MaxValue });
+ MakeCollectionTest(null);
+ MakeCollectionTest(new DateTime?[] { });
+ MakeCollectionTest(new DateTime?[] { DateTime.Now, DateTime.UtcNow, DateTime.Today, DateTime.Now.AddYears(2000), null, DateTime.MinValue, DateTime.MaxValue });
}
[Fact]
diff --git a/ZeroLevel.UnitTests/ZeroLevel.UnitTests.csproj b/ZeroLevel.UnitTests/ZeroLevel.UnitTests.csproj
index ca24844..990ceec 100644
--- a/ZeroLevel.UnitTests/ZeroLevel.UnitTests.csproj
+++ b/ZeroLevel.UnitTests/ZeroLevel.UnitTests.csproj
@@ -9,9 +9,9 @@
-
-
-
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/ZeroLevel/Services/Memory/IViewAccessor.cs b/ZeroLevel/Services/Memory/IViewAccessor.cs
index 9223405..d8d53f4 100644
--- a/ZeroLevel/Services/Memory/IViewAccessor.cs
+++ b/ZeroLevel/Services/Memory/IViewAccessor.cs
@@ -1,16 +1,18 @@
using System;
+using System.Threading.Tasks;
namespace ZeroLevel.Services.Memory
{
public interface IViewAccessor
: IDisposable
{
+ bool IsMemoryStream { get; }
///
/// End of view
///
bool EOV { get; }
long Position { get; }
- byte[] ReadBuffer(int count);
+ Task ReadBuffer(int count);
bool CheckOutOfRange(int offset);
void Seek(long offset);
}
diff --git a/ZeroLevel/Services/Memory/MMFViewAccessor.cs b/ZeroLevel/Services/Memory/MMFViewAccessor.cs
index 2d86277..bd17fe9 100644
--- a/ZeroLevel/Services/Memory/MMFViewAccessor.cs
+++ b/ZeroLevel/Services/Memory/MMFViewAccessor.cs
@@ -1,6 +1,8 @@
using System;
using System.IO;
using System.IO.MemoryMappedFiles;
+using System.Runtime.CompilerServices;
+using System.Threading.Tasks;
namespace ZeroLevel.Services.Memory
{
@@ -20,29 +22,27 @@ namespace ZeroLevel.Services.Memory
public long Position => _absoluteOffset + _accessor.Position;
- public bool CheckOutOfRange(int offset)
- {
- return offset < 0 || (_accessor.Position + offset) > _accessor.Length;
- }
+ public bool IsMemoryStream => false;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public bool CheckOutOfRange(int offset) => offset < 0 || (_accessor.Position + offset) > _accessor.Length;
public void Dispose()
{
_accessor?.Dispose();
}
- public byte[] ReadBuffer(int count)
+ public async Task ReadBuffer(int count)
{
if (count == 0) return null;
var buffer = new byte[count];
- var readedCount = _accessor.Read(buffer, 0, count);
+ var readedCount = await _accessor.ReadAsync(buffer, 0, count);
if (count != readedCount)
throw new InvalidOperationException($"The stream returned less data ({count} bytes) than expected ({readedCount} bytes)");
return buffer;
}
- public void Seek(long offset)
- {
- _accessor.Seek(offset, SeekOrigin.Begin);
- }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Seek(long offset) => _accessor.Seek(offset, SeekOrigin.Begin);
}
}
diff --git a/ZeroLevel/Services/Memory/StreamVewAccessor.cs b/ZeroLevel/Services/Memory/StreamVewAccessor.cs
index 3558b67..ade51cf 100644
--- a/ZeroLevel/Services/Memory/StreamVewAccessor.cs
+++ b/ZeroLevel/Services/Memory/StreamVewAccessor.cs
@@ -1,5 +1,7 @@
using System;
using System.IO;
+using System.Runtime.CompilerServices;
+using System.Threading.Tasks;
namespace ZeroLevel.Services.Memory
{
@@ -16,16 +18,16 @@ namespace ZeroLevel.Services.Memory
public long Position => _stream.Position;
- public bool CheckOutOfRange(int offset)
- {
- return offset < 0 || (_stream.Position + offset) > _stream.Length;
- }
+ public bool IsMemoryStream => _stream is MemoryStream;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public bool CheckOutOfRange(int offset) => offset < 0 || (_stream.Position + offset) > _stream.Length;
- public byte[] ReadBuffer(int count)
+ public async Task ReadBuffer(int count)
{
if (count == 0) return null;
var buffer = new byte[count];
- var readedCount = _stream.Read(buffer, 0, count);
+ var readedCount = await _stream.ReadAsync(buffer, 0, count);
if (count != readedCount)
throw new InvalidOperationException($"The stream returned less data ({count} bytes) than expected ({readedCount} bytes)");
return buffer;
@@ -36,9 +38,7 @@ namespace ZeroLevel.Services.Memory
_stream.Dispose();
}
- public void Seek(long offset)
- {
- _stream.Seek(offset, SeekOrigin.Begin);
- }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void Seek(long offset) => _stream.Seek(offset, SeekOrigin.Begin);
}
}
diff --git a/ZeroLevel/Services/PartitionStorage/Indexes/ValuesIndex/ValueIndex.cs b/ZeroLevel/Services/PartitionStorage/Indexes/ValuesIndex/ValueIndex.cs
deleted file mode 100644
index 595f82a..0000000
--- a/ZeroLevel/Services/PartitionStorage/Indexes/ValuesIndex/ValueIndex.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace ZeroLevel.Services.PartitionStorage
-{
- /*TODO IN FUTURE*/
- internal struct ValueIndex
- {
- public TValue Value { get; set; }
- public long Offset { get; set; }
- }
-}
diff --git a/ZeroLevel/Services/PartitionStorage/Interfaces/IStore.cs b/ZeroLevel/Services/PartitionStorage/Interfaces/IStore.cs
index 6121dc4..1fcbaec 100644
--- a/ZeroLevel/Services/PartitionStorage/Interfaces/IStore.cs
+++ b/ZeroLevel/Services/PartitionStorage/Interfaces/IStore.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Threading.Tasks;
using ZeroLevel.Services.PartitionStorage.Interfaces;
namespace ZeroLevel.Services.PartitionStorage
@@ -28,15 +29,15 @@ namespace ZeroLevel.Services.PartitionStorage
///
/// Performs a search for data in the repository
///
- StoreSearchResult Search(StoreSearchRequest searchRequest);
+ Task> Search(StoreSearchRequest searchRequest);
///
/// bypass all key value by meta
///
- void Bypass(TMeta meta, Action handler);
+ IAsyncEnumerable> Bypass(TMeta meta);
///
/// true - if key exists
///
- bool Exists(TMeta meta, TKey key);
+ Task Exists(TMeta meta, TKey key);
///
/// Deleting a partition
///
diff --git a/ZeroLevel/Services/PartitionStorage/Interfaces/IStorePartitionAccessor.cs b/ZeroLevel/Services/PartitionStorage/Interfaces/IStorePartitionAccessor.cs
index 76cc7d1..d686f3b 100644
--- a/ZeroLevel/Services/PartitionStorage/Interfaces/IStorePartitionAccessor.cs
+++ b/ZeroLevel/Services/PartitionStorage/Interfaces/IStorePartitionAccessor.cs
@@ -1,4 +1,6 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
namespace ZeroLevel.Services.PartitionStorage
{
@@ -18,42 +20,42 @@ namespace ZeroLevel.Services.PartitionStorage
///
/// Search in a partition for a specified key
///
- StorePartitionKeyValueSearchResult Find(TKey key);
+ Task> Find(TKey key);
///
/// Search in a partition for a specified keys
///
- IEnumerable> Find(IEnumerable keys);
+ Task Find(IEnumerable keys, Action searchResultHandler);
///
/// Iterating over all recorded data
///
- IEnumerable> Iterate();
+ IAsyncEnumerable> Iterate();
///
/// Iterating over all recorded data of the file with the specified key
///
- IEnumerable> IterateKeyBacket(TKey key);
+ Task IterateKeyBacket(TKey key, Action kvHandler);
///
/// Deleting the specified key and associated data
///
/// Key
/// true - automatically rebuild the index of the file from which data was deleted (default = false)
- void RemoveKey(TKey key, bool autoReindex = false);
+ Task RemoveKey(TKey key, bool autoReindex = false);
///
/// Deleting the specified keys and associated data
///
/// Keys
/// true - automatically rebuild the index of the file from which data was deleted (default = true)
- void RemoveKeys(IEnumerable keys, bool autoReindex = true);
+ Task RemoveKeys(IEnumerable keys, bool autoReindex = true);
///
/// Delete all keys with data except the specified key
///
/// Key
/// true - automatically rebuild the index of the file from which data was deleted (default = true)
- void RemoveAllExceptKey(TKey key, bool autoReindex = true);
+ Task RemoveAllExceptKey(TKey key, bool autoReindex = true);
///
/// Delete all keys with data other than the specified ones
///
/// Keys
/// true - automatically rebuild the index of the file from which data was deleted (default = true)
- void RemoveAllExceptKeys(IEnumerable keys, bool autoReindex = true);
+ Task RemoveAllExceptKeys(IEnumerable keys, bool autoReindex = true);
}
}
diff --git a/ZeroLevel/Services/PartitionStorage/Interfaces/IStorePartitionBuilder.cs b/ZeroLevel/Services/PartitionStorage/Interfaces/IStorePartitionBuilder.cs
index 2a86373..cf0b162 100644
--- a/ZeroLevel/Services/PartitionStorage/Interfaces/IStorePartitionBuilder.cs
+++ b/ZeroLevel/Services/PartitionStorage/Interfaces/IStorePartitionBuilder.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using System.Threading.Tasks;
namespace ZeroLevel.Services.PartitionStorage
{
@@ -15,11 +16,11 @@ namespace ZeroLevel.Services.PartitionStorage
{
get;
}
- IEnumerable> Iterate();
+ IAsyncEnumerable> Iterate();
///
/// Writing a key-value pair
///
- void Store(TKey key, TInput value);
+ Task Store(TKey key, TInput value);
///
/// Called after all key-value pairs are written to the partition
///
@@ -27,7 +28,7 @@ namespace ZeroLevel.Services.PartitionStorage
///
/// Performs compression/grouping of recorded data in a partition
///
- void Compress();
+ Task Compress();
///
/// Rebuilds indexes for data in a partition
///
diff --git a/ZeroLevel/Services/PartitionStorage/Interfaces/IStorePartitionMergeBuilder.cs b/ZeroLevel/Services/PartitionStorage/Interfaces/IStorePartitionMergeBuilder.cs
index 95c72a0..9fe0e02 100644
--- a/ZeroLevel/Services/PartitionStorage/Interfaces/IStorePartitionMergeBuilder.cs
+++ b/ZeroLevel/Services/PartitionStorage/Interfaces/IStorePartitionMergeBuilder.cs
@@ -1,4 +1,6 @@
-namespace ZeroLevel.Services.PartitionStorage.Interfaces
+using System.Threading.Tasks;
+
+namespace ZeroLevel.Services.PartitionStorage.Interfaces
{
///
/// Provides write operations in catalog partition
@@ -16,10 +18,10 @@
///
/// Writing a key-value pair
///
- void Store(TKey key, TInput value);
+ Task Store(TKey key, TInput value);
///
/// Perform the conversion of the records from (TKey; TInput) to (TKey; TValue). Called after CompleteAdding
///
- void Compress();
+ Task Compress();
}
}
diff --git a/ZeroLevel/Services/PartitionStorage/Interfaces/IStoreSerializer.cs b/ZeroLevel/Services/PartitionStorage/Interfaces/IStoreSerializer.cs
index 6132807..ac34e98 100644
--- a/ZeroLevel/Services/PartitionStorage/Interfaces/IStoreSerializer.cs
+++ b/ZeroLevel/Services/PartitionStorage/Interfaces/IStoreSerializer.cs
@@ -1,14 +1,19 @@
using System;
+using System.Threading.Tasks;
using ZeroLevel.Services.Serialization;
namespace ZeroLevel.Services.PartitionStorage.Interfaces
{
public interface IStoreSerializer
{
- Action KeySerializer { get; }
- Action InputSerializer { get; }
- TryDeserializeMethod KeyDeserializer { get; }
- TryDeserializeMethod InputDeserializer { get; }
- TryDeserializeMethod ValueDeserializer { get; }
+ Func KeySerializer { get; }
+
+ Func InputSerializer { get; }
+
+ Func>> KeyDeserializer { get; }
+
+ Func>> InputDeserializer { get; }
+
+ Func>> ValueDeserializer { get; }
}
}
diff --git a/ZeroLevel/Services/PartitionStorage/KV.cs b/ZeroLevel/Services/PartitionStorage/KV.cs
new file mode 100644
index 0000000..df51584
--- /dev/null
+++ b/ZeroLevel/Services/PartitionStorage/KV.cs
@@ -0,0 +1,4 @@
+namespace ZeroLevel.Services.PartitionStorage
+{
+ public record KV(TKey Key, TValue Value);
+}
diff --git a/ZeroLevel/Services/PartitionStorage/Partition/CompactKeyStorePartitionBuilder.cs b/ZeroLevel/Services/PartitionStorage/Partition/CompactKeyStorePartitionBuilder.cs
index 08852cb..cbe32ef 100644
--- a/ZeroLevel/Services/PartitionStorage/Partition/CompactKeyStorePartitionBuilder.cs
+++ b/ZeroLevel/Services/PartitionStorage/Partition/CompactKeyStorePartitionBuilder.cs
@@ -13,7 +13,7 @@ namespace ZeroLevel.Services.PartitionStorage.Partition
internal sealed class CompactKeyStorePartitionBuilder
: BasePartition, IStorePartitionBuilder
{
- private readonly Action _storeMethod;
+ private readonly Func _storeMethod;
private long _totalRecords = 0;
@@ -39,9 +39,9 @@ namespace ZeroLevel.Services.PartitionStorage.Partition
#region IStorePartitionBuilder
- public void Store(TKey key, TInput value)
+ public async Task Store(TKey key, TInput value)
{
- _storeMethod.Invoke(key, value);
+ await _storeMethod.Invoke(key, value);
Interlocked.Increment(ref _totalRecords);
}
@@ -50,18 +50,16 @@ namespace ZeroLevel.Services.PartitionStorage.Partition
CloseWriteStreams();
}
- public void Compress()
+ public async Task Compress()
{
var files = Directory.GetFiles(_catalog);
if (files != null && files.Length > 0)
{
- Parallel.ForEach(files, file => CompressFile(file));
+ await Parallel.ForEachAsync(files, async (file, ct) => await CompressFile(file));
}
}
- public IEnumerable> Iterate()
+ public async IAsyncEnumerable> Iterate()
{
- TKey key;
- TInput input;
var files = Directory.GetFiles(_catalog);
if (files != null && files.Length > 0)
{
@@ -73,9 +71,13 @@ namespace ZeroLevel.Services.PartitionStorage.Partition
{
while (reader.EOS == false)
{
- if (Serializer.KeyDeserializer.Invoke(reader, out key) == false) break;
- if (Serializer.InputDeserializer.Invoke(reader, out input) == false) break;
- yield return new StorePartitionKeyValueSearchResult { Key = key, Value = input, Status = SearchResult.Success };
+ var kv = await Serializer.KeyDeserializer.Invoke(reader);
+ if (kv.Success == false) break;
+
+ var iv = await Serializer.InputDeserializer.Invoke(reader);
+ if (iv.Success == false) break;
+
+ yield return new SearchResult { Key = kv.Value, Value = iv.Value, Success = true };
}
}
}
@@ -86,17 +88,16 @@ namespace ZeroLevel.Services.PartitionStorage.Partition
#endregion
#region Private methods
- private void StoreDirect(TKey key, TInput value)
+ private async Task StoreDirect(TKey key, TInput value)
{
var groupKey = _options.GetFileName(key, _info);
if (TryGetWriteStream(groupKey, out var stream))
{
- Serializer.KeySerializer.Invoke(stream, key);
- Thread.MemoryBarrier();
- Serializer.InputSerializer.Invoke(stream, value);
+ await Serializer.KeySerializer.Invoke(stream, key);
+ await Serializer.InputSerializer.Invoke(stream, value);
}
}
- private void StoreDirectSafe(TKey key, TInput value)
+ private async Task StoreDirectSafe(TKey key, TInput value)
{
var groupKey = _options.GetFileName(key, _info);
bool lockTaken = false;
@@ -105,9 +106,8 @@ namespace ZeroLevel.Services.PartitionStorage.Partition
Monitor.Enter(stream, ref lockTaken);
try
{
- Serializer.KeySerializer.Invoke(stream, key);
- Thread.MemoryBarrier();
- Serializer.InputSerializer.Invoke(stream, value);
+ await Serializer.KeySerializer.Invoke(stream, key);
+ await Serializer.InputSerializer.Invoke(stream, value);
}
finally
{
@@ -119,10 +119,8 @@ namespace ZeroLevel.Services.PartitionStorage.Partition
}
}
- internal void CompressFile(string file)
+ internal async Task CompressFile(string file)
{
- TKey key;
- TInput input;
var dict = new Dictionary>();
PhisicalFileAccessorCachee.LockFile(file);
try
@@ -131,23 +129,25 @@ namespace ZeroLevel.Services.PartitionStorage.Partition
{
while (reader.EOS == false)
{
- if (false == Serializer.KeyDeserializer.Invoke(reader, out key))
+ var kv = await Serializer.KeyDeserializer.Invoke(reader);
+ if (kv.Success == false)
{
throw new Exception($"[StorePartitionBuilder.CompressFile] Fault compress data in file '{file}'. Incorrect file structure. Fault read key.");
}
- if (false == dict.ContainsKey(key))
+ if (false == dict.ContainsKey(kv.Value))
{
- dict[key] = new HashSet();
+ dict[kv.Value] = new HashSet();
}
if (reader.EOS)
{
break;
}
- if (false == Serializer.InputDeserializer.Invoke(reader, out input))
+ var iv = await Serializer.InputDeserializer.Invoke(reader);
+ if (iv.Success == false)
{
throw new Exception($"[StorePartitionBuilder.CompressFile] Fault compress data in file '{file}'. Incorrect file structure. Fault input value.");
}
- dict[key].Add(input);
+ dict[kv.Value].Add(iv.Value);
}
}
var tempFile = FSUtils.GetAppLocalTemporaryFile();
diff --git a/ZeroLevel/Services/PartitionStorage/Partition/InternalDirectHybridPartition.cs b/ZeroLevel/Services/PartitionStorage/Partition/InternalDirectHybridPartition.cs
deleted file mode 100644
index 57f4532..0000000
--- a/ZeroLevel/Services/PartitionStorage/Partition/InternalDirectHybridPartition.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace ZeroLevel.Services.PartitionStorage.Partition
-{
- internal class InternalDirectHybridPartition
- {
-
- }
-}
diff --git a/ZeroLevel/Services/PartitionStorage/Partition/StoreMergePartitionAccessor.cs b/ZeroLevel/Services/PartitionStorage/Partition/StoreMergePartitionAccessor.cs
index 42651ce..356869f 100644
--- a/ZeroLevel/Services/PartitionStorage/Partition/StoreMergePartitionAccessor.cs
+++ b/ZeroLevel/Services/PartitionStorage/Partition/StoreMergePartitionAccessor.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Threading.Tasks;
using ZeroLevel.Services.PartitionStorage.Interfaces;
using ZeroLevel.Services.PartitionStorage.Partition;
using ZeroLevel.Services.Serialization;
@@ -60,14 +61,14 @@ namespace ZeroLevel.Services.PartitionStorage
///
public void DropData() => _temporaryAccessor.DropData();
public string GetCatalogPath() => _accessor.GetCatalogPath();
- public void Store(TKey key, TInput value) => _temporaryAccessor.Store(key, value);
+ public async Task Store(TKey key, TInput value) => await _temporaryAccessor.Store(key, value);
public int CountDataFiles() => Math.Max(_accessor.CountDataFiles(),
_temporaryAccessor.CountDataFiles());
///
/// Performs compression/grouping of recorded data in a partition
///
- public void Compress()
+ public async Task Compress()
{
var newFiles = Directory.GetFiles(_temporaryAccessor.GetCatalogPath());
@@ -88,7 +89,7 @@ namespace ZeroLevel.Services.PartitionStorage
{
foreach (var i in r.Value)
{
- _temporaryAccessor.Store(r.Key, i);
+ await _temporaryAccessor.Store(r.Key, i);
}
}
}
@@ -99,7 +100,7 @@ namespace ZeroLevel.Services.PartitionStorage
// compress new file
foreach (var file in newFiles)
{
- (_temporaryAccessor as StorePartitionBuilder)
+ await (_temporaryAccessor as StorePartitionBuilder)
.CompressFile(file);
}
@@ -141,7 +142,7 @@ namespace ZeroLevel.Services.PartitionStorage
#endregion
#region Private methods
- private IEnumerable>>
+ private IEnumerable>>
IterateReadKeyInputs(string filePath)
{
if (File.Exists(filePath))
@@ -154,11 +155,11 @@ namespace ZeroLevel.Services.PartitionStorage
var k = _keyDeserializer.Invoke(reader);
var v = _valueDeserializer.Invoke(reader);
var input = _decompress(v);
- yield return new StorePartitionKeyValueSearchResult>
+ yield return new SearchResult>
{
Key = k,
Value = input,
- Status = SearchResult.Success
+ Success = true
};
}
}
diff --git a/ZeroLevel/Services/PartitionStorage/Partition/StorePartitionAccessor.cs b/ZeroLevel/Services/PartitionStorage/Partition/StorePartitionAccessor.cs
index ebd92e2..368d561 100644
--- a/ZeroLevel/Services/PartitionStorage/Partition/StorePartitionAccessor.cs
+++ b/ZeroLevel/Services/PartitionStorage/Partition/StorePartitionAccessor.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Threading.Tasks;
using ZeroLevel.Services.FileSystem;
using ZeroLevel.Services.Memory;
using ZeroLevel.Services.PartitionStorage.Interfaces;
@@ -29,10 +30,8 @@ namespace ZeroLevel.Services.PartitionStorage
#region IStorePartitionAccessor
- public StorePartitionKeyValueSearchResult Find(TKey key)
+ public async Task> Find(TKey key)
{
- TKey k;
- TValue v;
IViewAccessor memoryAccessor;
try
{
@@ -49,10 +48,10 @@ namespace ZeroLevel.Services.PartitionStorage
catch (Exception ex)
{
Log.SystemError(ex, $"[StorePartitionAccessor.Find] Fault get IViewAccessor by key {(key == null ? string.Empty : key.ToString())}");
- return new StorePartitionKeyValueSearchResult
+ return new SearchResult
{
Key = key,
- Status = SearchResult.FileLockedOrUnavaliable,
+ Success = false,
Value = default
};
}
@@ -62,14 +61,18 @@ namespace ZeroLevel.Services.PartitionStorage
{
while (reader.EOS == false)
{
- if (Serializer.KeyDeserializer.Invoke(reader, out k) == false) break;
- if (Serializer.ValueDeserializer.Invoke(reader, out v) == false) break;
- var c = _options.KeyComparer(key, k);
- if (c == 0) return new StorePartitionKeyValueSearchResult
+ var kv = await Serializer.KeyDeserializer.Invoke(reader);
+ if (kv.Success == false) break;
+
+ var vv = await Serializer.ValueDeserializer.Invoke(reader);
+ if(vv.Success == false) break;
+
+ var c = _options.KeyComparer(key, kv.Value);
+ if (c == 0) return new SearchResult
{
Key = key,
- Value = v,
- Status = SearchResult.Success
+ Value = vv.Value,
+ Success = true
};
if (c == -1)
{
@@ -78,14 +81,14 @@ namespace ZeroLevel.Services.PartitionStorage
}
}
}
- return new StorePartitionKeyValueSearchResult
+ return new SearchResult
{
Key = key,
- Status = SearchResult.NotFound,
+ Success = false,
Value = default
};
}
- public IEnumerable> Find(IEnumerable keys)
+ public async Task Find(IEnumerable keys, Action searchResultHandler)
{
var results = keys.Distinct()
.GroupBy(
@@ -93,18 +96,13 @@ namespace ZeroLevel.Services.PartitionStorage
k => k, (key, g) => new { FileName = key, Keys = g.ToArray() });
foreach (var group in results)
{
- foreach (var r in Find(group.FileName, group.Keys))
- {
- yield return r;
- }
+ await Find(group.FileName, group.Keys, searchResultHandler);
}
}
- public IEnumerable> Iterate()
+ public async IAsyncEnumerable> Iterate()
{
if (Directory.Exists(_catalog))
{
- TKey k;
- TValue v;
var files = Directory.GetFiles(_catalog);
if (files != null && files.Length > 0)
{
@@ -117,9 +115,13 @@ namespace ZeroLevel.Services.PartitionStorage
{
while (reader.EOS == false)
{
- if (Serializer.KeyDeserializer.Invoke(reader, out k) == false) break;
- if (Serializer.ValueDeserializer.Invoke(reader, out v) == false) break;
- yield return new StorePartitionKeyValueSearchResult { Key = k, Value = v, Status = SearchResult.Success };
+ var kv = await Serializer.KeyDeserializer.Invoke(reader);
+ if (kv.Success == false) break;
+
+ var vv = await Serializer.ValueDeserializer.Invoke(reader);
+ if (vv.Success == false) break;
+
+ yield return new KV(kv.Value, vv.Value);
}
}
}
@@ -127,10 +129,8 @@ namespace ZeroLevel.Services.PartitionStorage
}
}
}
- public IEnumerable> IterateKeyBacket(TKey key)
+ public async Task IterateKeyBacket(TKey key, Action kvHandler)
{
- TKey k;
- TValue v;
var fileName = _options.GetFileName(key, _info);
var filePath = Path.Combine(_catalog, fileName);
if (File.Exists(filePath))
@@ -142,9 +142,13 @@ namespace ZeroLevel.Services.PartitionStorage
{
while (reader.EOS == false)
{
- if (Serializer.KeyDeserializer.Invoke(reader, out k) == false) break;
- if (Serializer.ValueDeserializer.Invoke(reader, out v) == false) break;
- yield return new StorePartitionKeyValueSearchResult { Key = k, Value = v, Status = SearchResult.Success };
+ var kv = await Serializer.KeyDeserializer.Invoke(reader);
+ if (kv.Success == false) break;
+
+ var vv = await Serializer.ValueDeserializer.Invoke(reader);
+ if (vv.Success == false) break;
+
+ kvHandler.Invoke(kv.Value, vv.Value);
}
}
}
@@ -158,11 +162,11 @@ namespace ZeroLevel.Services.PartitionStorage
Indexes.ResetCachee();
}
}
- public void RemoveAllExceptKey(TKey key, bool autoReindex = true)
+ public async Task RemoveAllExceptKey(TKey key, bool autoReindex = true)
{
- RemoveAllExceptKeys(new[] { key }, autoReindex);
+ await RemoveAllExceptKeys(new[] { key }, autoReindex);
}
- public void RemoveAllExceptKeys(IEnumerable keys, bool autoReindex = true)
+ public async Task RemoveAllExceptKeys(IEnumerable keys, bool autoReindex = true)
{
var results = keys.Distinct()
.GroupBy(
@@ -170,18 +174,18 @@ namespace ZeroLevel.Services.PartitionStorage
k => k, (key, g) => new { FileName = key, Keys = g.OrderBy(k => k).ToArray() });
foreach (var group in results)
{
- RemoveKeyGroup(group.FileName, group.Keys, false, autoReindex);
+ await RemoveKeyGroup(group.FileName, group.Keys, false, autoReindex);
if (_options.Index.Enabled)
{
Indexes.RemoveCacheeItem(group.FileName);
}
}
}
- public void RemoveKey(TKey key, bool autoReindex = false)
+ public async Task RemoveKey(TKey key, bool autoReindex = false)
{
- RemoveKeys(new[] { key }, autoReindex);
+ await RemoveKeys(new[] { key }, autoReindex);
}
- public void RemoveKeys(IEnumerable keys, bool autoReindex = true)
+ public async Task RemoveKeys(IEnumerable keys, bool autoReindex = true)
{
var results = keys.Distinct()
.GroupBy(
@@ -189,7 +193,7 @@ namespace ZeroLevel.Services.PartitionStorage
k => k, (key, g) => new { FileName = key, Keys = g.OrderBy(k => k).ToArray() });
foreach (var group in results)
{
- RemoveKeyGroup(group.FileName, group.Keys, true, autoReindex);
+ await RemoveKeyGroup(group.FileName, group.Keys, true, autoReindex);
if (_options.Index.Enabled)
{
Indexes.RemoveCacheeItem(group.FileName);
@@ -200,8 +204,7 @@ namespace ZeroLevel.Services.PartitionStorage
#region Private methods
- private IEnumerable> Find(string fileName,
- TKey[] keys)
+ private async Task Find(string fileName, TKey[] keys, Action searchResultHandler)
{
TKey k;
TValue v;
@@ -230,17 +233,16 @@ namespace ZeroLevel.Services.PartitionStorage
{
while (reader.EOS == false)
{
- if (Serializer.KeyDeserializer.Invoke(reader, out k) == false) break;
- if (Serializer.ValueDeserializer.Invoke(reader, out v) == false) break;
- var c = _options.KeyComparer(searchKey, k);
+ var kv = await Serializer.KeyDeserializer.Invoke(reader);
+ if (kv.Success == false) break;
+
+ var vv = await Serializer.ValueDeserializer.Invoke(reader);
+ if (vv.Success == false) break;
+
+ var c = _options.KeyComparer(searchKey, kv.Value);
if (c == 0)
{
- yield return new StorePartitionKeyValueSearchResult
- {
- Key = searchKey,
- Value = v,
- Status = SearchResult.Success
- };
+ searchResultHandler.Invoke(kv.Value, vv.Value);
break;
}
else if (c == -1)
@@ -263,17 +265,16 @@ namespace ZeroLevel.Services.PartitionStorage
var keys_arr = keys.OrderBy(k => k).ToArray();
while (reader.EOS == false && index < keys_arr.Length)
{
- if (Serializer.KeyDeserializer.Invoke(reader, out k) == false) break;
- if (Serializer.ValueDeserializer.Invoke(reader, out v) == false) break;
- var c = _options.KeyComparer(keys_arr[index], k);
+ var kv = await Serializer.KeyDeserializer.Invoke(reader);
+ if (kv.Success == false) break;
+
+ var vv = await Serializer.ValueDeserializer.Invoke(reader);
+ if (vv.Success == false) break;
+
+ var c = _options.KeyComparer(keys_arr[index], kv.Value);
if (c == 0)
{
- yield return new StorePartitionKeyValueSearchResult
- {
- Key = keys_arr[index],
- Value = v,
- Status = SearchResult.Success
- };
+ searchResultHandler.Invoke(kv.Value, vv.Value);
index++;
}
else if (c == -1)
@@ -283,7 +284,7 @@ namespace ZeroLevel.Services.PartitionStorage
index++;
if (index < keys_arr.Length)
{
- c = _options.KeyComparer(keys_arr[index], k);
+ c = _options.KeyComparer(keys_arr[index], kv.Value);
}
} while (index < keys_arr.Length && c == -1);
}
@@ -294,9 +295,8 @@ namespace ZeroLevel.Services.PartitionStorage
}
}
- private void RemoveKeyGroup(string fileName, TKey[] keys, bool inverseRemove, bool autoReindex)
+ private async Task RemoveKeyGroup(string fileName, TKey[] keys, bool inverseRemove, bool autoReindex)
{
- TKey k;
var filePath = Path.Combine(_catalog, fileName);
if (File.Exists(filePath))
{
@@ -325,18 +325,22 @@ namespace ZeroLevel.Services.PartitionStorage
while (reader.EOS == false)
{
var startPosition = reader.Position;
- if (Serializer.KeyDeserializer.Invoke(reader, out k) == false)
+
+ var kv = await Serializer.KeyDeserializer.Invoke(reader);
+ if (kv.Success == false)
{
Log.Error($"[StorePartitionAccessor.RemoveKeyGroup] Fault remove keys from file '{fileName}'. Incorrect file structure. Fault read key.");
return;
}
- if (Serializer.ValueDeserializer.Invoke(reader, out var _) == false)
+
+ var vv = await Serializer.ValueDeserializer.Invoke(reader);
+ if (vv.Success == false)
{
Log.Error($"[StorePartitionAccessor.RemoveKeyGroup] Fault remove keys from file '{fileName}'. Incorrect file structure. Fault read value.");
return;
}
var endPosition = reader.Position;
- var c = _options.KeyComparer(searchKey, k);
+ var c = _options.KeyComparer(searchKey, kv.Value);
if (c == 0)
{
ranges.Add(new FilePositionRange { Start = startPosition, End = endPosition });
@@ -362,18 +366,23 @@ namespace ZeroLevel.Services.PartitionStorage
while (reader.EOS == false && index < keys_arr.Length)
{
var startPosition = reader.Position;
- if (Serializer.KeyDeserializer.Invoke(reader, out k) == false)
+
+ var kv = await Serializer.KeyDeserializer.Invoke(reader);
+ if (kv.Success == false)
{
Log.Error($"[StorePartitionAccessor.RemoveKeyGroup] Fault remove keys from file '{fileName}'. Incorrect file structure. Fault read key.");
return;
}
- if (Serializer.ValueDeserializer.Invoke(reader, out var _) == false)
+
+ var vv = await Serializer.ValueDeserializer.Invoke(reader);
+ if (vv.Success == false)
{
Log.Error($"[StorePartitionAccessor.RemoveKeyGroup] Fault remove keys from file '{fileName}'. Incorrect file structure. Fault read value.");
return;
}
+
var endPosition = reader.Position;
- var c = _options.KeyComparer(keys_arr[index], k);
+ var c = _options.KeyComparer(keys_arr[index], kv.Value);
if (c == 0)
{
ranges.Add(new FilePositionRange { Start = startPosition, End = endPosition });
@@ -386,7 +395,7 @@ namespace ZeroLevel.Services.PartitionStorage
index++;
if (index < keys_arr.Length)
{
- c = _options.KeyComparer(keys_arr[index], k);
+ c = _options.KeyComparer(keys_arr[index], kv.Value);
}
} while (index < keys_arr.Length && c == -1);
}
diff --git a/ZeroLevel/Services/PartitionStorage/Partition/StorePartitionBuilder.cs b/ZeroLevel/Services/PartitionStorage/Partition/StorePartitionBuilder.cs
index 9d04b11..edc2eaf 100644
--- a/ZeroLevel/Services/PartitionStorage/Partition/StorePartitionBuilder.cs
+++ b/ZeroLevel/Services/PartitionStorage/Partition/StorePartitionBuilder.cs
@@ -14,7 +14,7 @@ namespace ZeroLevel.Services.PartitionStorage
internal sealed class StorePartitionBuilder
: BasePartition, IStorePartitionBuilder
{
- private readonly Func _storeMethod;
+ private readonly Func> _storeMethod;
private long _totalRecords = 0;
@@ -40,9 +40,9 @@ namespace ZeroLevel.Services.PartitionStorage
#region IStorePartitionBuilder
- public void Store(TKey key, TInput value)
+ public async Task Store(TKey key, TInput value)
{
- if (_storeMethod.Invoke(key, value))
+ if (await _storeMethod.Invoke(key, value))
{
Interlocked.Increment(ref _totalRecords);
}
@@ -53,18 +53,16 @@ namespace ZeroLevel.Services.PartitionStorage
CloseWriteStreams();
}
- public void Compress()
+ public async Task Compress()
{
var files = Directory.GetFiles(_catalog);
if (files != null && files.Length > 0)
{
- Parallel.ForEach(files, file => CompressFile(file));
+ await Parallel.ForEachAsync(files, async(file, _) => await CompressFile(file));
}
}
- public IEnumerable> Iterate()
+ public async IAsyncEnumerable> Iterate()
{
- TKey key;
- TInput val;
var files = Directory.GetFiles(_catalog);
if (files != null && files.Length > 0)
{
@@ -77,9 +75,13 @@ namespace ZeroLevel.Services.PartitionStorage
{
while (reader.EOS == false)
{
- if (Serializer.KeyDeserializer.Invoke(reader, out key) == false) break;
- if (Serializer.InputDeserializer.Invoke(reader, out val) == false) break;
- yield return new StorePartitionKeyValueSearchResult { Key = key, Value = val, Status = SearchResult.Success };
+ var kv = await Serializer.KeyDeserializer.Invoke(reader);
+ if (kv.Success == false) break;
+
+ var vv = await Serializer.InputDeserializer.Invoke(reader);
+ if (vv.Success == false) break;
+
+ yield return new SearchResult { Key = kv.Value, Value = vv.Value, Success = true };
}
}
}
@@ -90,14 +92,14 @@ namespace ZeroLevel.Services.PartitionStorage
#endregion
#region Private methods
- private bool StoreDirect(TKey key, TInput value)
+ private async Task StoreDirect(TKey key, TInput value)
{
var groupKey = _options.GetFileName(key, _info);
if (TryGetWriteStream(groupKey, out var stream))
{
- Serializer.KeySerializer.Invoke(stream, key);
+ await Serializer.KeySerializer.Invoke(stream, key);
Thread.MemoryBarrier();
- Serializer.InputSerializer.Invoke(stream, value);
+ await Serializer.InputSerializer.Invoke(stream, value);
return true;
}
else
@@ -106,7 +108,7 @@ namespace ZeroLevel.Services.PartitionStorage
}
return false;
}
- private bool StoreDirectSafe(TKey key, TInput value)
+ private async Task StoreDirectSafe(TKey key, TInput value)
{
var groupKey = _options.GetFileName(key, _info);
bool lockTaken = false;
@@ -115,9 +117,9 @@ namespace ZeroLevel.Services.PartitionStorage
Monitor.Enter(stream, ref lockTaken);
try
{
- Serializer.KeySerializer.Invoke(stream, key);
+ await Serializer.KeySerializer.Invoke(stream, key);
Thread.MemoryBarrier();
- Serializer.InputSerializer.Invoke(stream, value);
+ await Serializer.InputSerializer.Invoke(stream, value);
return true;
}
finally
@@ -135,10 +137,8 @@ namespace ZeroLevel.Services.PartitionStorage
return false;
}
- internal void CompressFile(string file)
+ internal async Task CompressFile(string file)
{
- TKey key;
- TInput input;
PhisicalFileAccessorCachee.LockFile(file);
try
{
@@ -150,25 +150,27 @@ namespace ZeroLevel.Services.PartitionStorage
{
while (reader.EOS == false)
{
- if (Serializer.KeyDeserializer.Invoke(reader, out key) == false)
+ var kv = await Serializer.KeyDeserializer.Invoke(reader);
+ if (kv.Success == false)
{
throw new Exception($"[StorePartitionBuilder.CompressFile] Fault compress data in file '{file}'. Incorrect file structure. Fault read key.");
}
- if (key != null)
+ if (kv.Value != null)
{
- if (false == dict.ContainsKey(key))
+ if (false == dict.ContainsKey(kv.Value))
{
- dict[key] = new HashSet();
+ dict[kv.Value] = new HashSet();
}
if (reader.EOS)
{
break;
}
- if (Serializer.InputDeserializer.Invoke(reader, out input) == false)
+ var iv = await Serializer.InputDeserializer.Invoke(reader);
+ if (iv.Success == false)
{
throw new Exception($"[StorePartitionBuilder.CompressFile] Fault compress data in file '{file}'. Incorrect file structure. Fault read input value.");
}
- dict[key].Add(input);
+ dict[kv.Value].Add(iv.Value);
}
else
{
diff --git a/ZeroLevel/Services/PartitionStorage/Search/SearchResult.cs b/ZeroLevel/Services/PartitionStorage/Search/SearchResult.cs
index 1792b40..f85d15a 100644
--- a/ZeroLevel/Services/PartitionStorage/Search/SearchResult.cs
+++ b/ZeroLevel/Services/PartitionStorage/Search/SearchResult.cs
@@ -1,9 +1,9 @@
namespace ZeroLevel.Services.PartitionStorage
{
- public enum SearchResult
+ public class SearchResult
{
- Success,
- NotFound,
- FileLockedOrUnavaliable
+ public bool Success { get; set; }
+ public TKey Key { get; set; }
+ public TValue Value { get; set; }
}
}
diff --git a/ZeroLevel/Services/PartitionStorage/Search/StorePartitionKeyValueSearchResult.cs b/ZeroLevel/Services/PartitionStorage/Search/StorePartitionKeyValueSearchResult.cs
deleted file mode 100644
index 61ba3de..0000000
--- a/ZeroLevel/Services/PartitionStorage/Search/StorePartitionKeyValueSearchResult.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace ZeroLevel.Services.PartitionStorage
-{
- public class StorePartitionKeyValueSearchResult
- {
- public SearchResult Status { get; set; }
- public TKey Key { get; set; }
- public TValue Value { get; set; }
- }
-}
diff --git a/ZeroLevel/Services/PartitionStorage/Search/StoreSearchResult.cs b/ZeroLevel/Services/PartitionStorage/Search/StoreSearchResult.cs
index 7fe275a..850f4f6 100644
--- a/ZeroLevel/Services/PartitionStorage/Search/StoreSearchResult.cs
+++ b/ZeroLevel/Services/PartitionStorage/Search/StoreSearchResult.cs
@@ -4,6 +4,6 @@ namespace ZeroLevel.Services.PartitionStorage
{
public class StoreSearchResult
{
- public IDictionary>> Results { get; set; }
+ public IDictionary>> Results { get; set; }
}
}
diff --git a/ZeroLevel/Services/PartitionStorage/Store.cs b/ZeroLevel/Services/PartitionStorage/Store.cs
index d834aa0..dbc8a6c 100644
--- a/ZeroLevel/Services/PartitionStorage/Store.cs
+++ b/ZeroLevel/Services/PartitionStorage/Store.cs
@@ -17,18 +17,12 @@ namespace ZeroLevel.Services.PartitionStorage
private readonly PhisicalFileAccessorCachee _fileAccessorCachee;
public Store(StoreOptions options,
- IStoreSerializer serializer = null)
+ IStoreSerializer serializer)
{
if (options == null) throw new ArgumentNullException(nameof(options));
+ if (serializer == null) throw new ArgumentNullException(nameof(serializer));
_options = options;
- if (serializer == null)
- {
- _serializer = new StoreStandartSerializer();
- }
- else
- {
- _serializer = serializer;
- }
+ _serializer = serializer;
if (Directory.Exists(_options.RootFolder) == false)
{
Directory.CreateDirectory(_options.RootFolder);
@@ -76,10 +70,10 @@ namespace ZeroLevel.Services.PartitionStorage
_fileAccessorCachee.DropAllIndexReaders();
}
- public StoreSearchResult Search(StoreSearchRequest searchRequest)
+ public async Task> Search(StoreSearchRequest searchRequest)
{
var result = new StoreSearchResult();
- var results = new ConcurrentDictionary>>();
+ var results = new ConcurrentDictionary>>();
if (searchRequest.PartitionSearchRequests?.Any() ?? false)
{
var partitionsSearchInfo = searchRequest
@@ -89,16 +83,19 @@ namespace ZeroLevel.Services.PartitionStorage
{
MaxDegreeOfParallelism = _options.MaxDegreeOfParallelism
};
- Parallel.ForEach(partitionsSearchInfo, options, (pair, _) =>
+ await Parallel.ForEachAsync(partitionsSearchInfo, options, async (pair, _) =>
{
var accessor = CreateAccessor(pair.Key);
if (accessor != null)
{
using (accessor)
{
- results[pair.Key] = accessor
- .Find(pair.Value)
- .ToArray();
+ var set = new List>();
+ await foreach (var kv in accessor.Iterate())
+ {
+ set.Add(new KV(kv.Key, kv.Value));
+ }
+ results[pair.Key] = set;
}
}
});
@@ -112,29 +109,30 @@ namespace ZeroLevel.Services.PartitionStorage
_fileAccessorCachee.Dispose();
}
- public void Bypass(TMeta meta, Action handler)
+ public async IAsyncEnumerable> Bypass(TMeta meta)
{
var accessor = CreateAccessor(meta);
if (accessor != null)
{
using (accessor)
{
- foreach (var kv in accessor.Iterate())
+ await foreach (var kv in accessor.Iterate())
{
- handler.Invoke(kv.Key, kv.Value);
+ yield return kv;
}
}
}
}
- public bool Exists(TMeta meta, TKey key)
+ public async Task Exists(TMeta meta, TKey key)
{
var accessor = CreateAccessor(meta);
if (accessor != null)
{
using (accessor)
{
- return accessor.Find(key).Status == SearchResult.Success;
+ var info = await accessor.Find(key);
+ return info.Success;
}
}
return false;
diff --git a/ZeroLevel/Services/PartitionStorage/StoreSerializers.cs b/ZeroLevel/Services/PartitionStorage/StoreSerializers.cs
new file mode 100644
index 0000000..b2eb16e
--- /dev/null
+++ b/ZeroLevel/Services/PartitionStorage/StoreSerializers.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Threading.Tasks;
+using ZeroLevel.Services.PartitionStorage.Interfaces;
+using ZeroLevel.Services.Serialization;
+
+namespace ZeroLevel.Services.PartitionStorage
+{
+ public record DeserializeResult(bool Success, T Value);
+
+ public delegate Task> TryDeserializeMethod(MemoryStreamReader reader);
+
+ public sealed class StoreSerializers
+ : IStoreSerializer
+ {
+ private readonly Func _keySerializer;
+ private readonly Func _inputSerializer;
+ private readonly Func>> _keyDeserializer;
+ private readonly Func>> _inputDeserializer;
+ private readonly Func>> _valueDeserializer;
+
+ public StoreSerializers(Func keySerializer,
+ Func inputSerializer,
+ Func>> keyDeserializer,
+ Func>> inputDeserializer,
+ Func>> valueDeserializer)
+ {
+ _keySerializer = keySerializer;
+ _inputSerializer = inputSerializer;
+ _keyDeserializer = keyDeserializer;
+ _inputDeserializer = inputDeserializer;
+ _valueDeserializer = valueDeserializer;
+ }
+
+ public Func KeySerializer => _keySerializer;
+
+ public Func InputSerializer => _inputSerializer;
+
+ public Func>> KeyDeserializer => _keyDeserializer;
+
+ public Func>> InputDeserializer => _inputDeserializer;
+
+ public Func>> ValueDeserializer => _valueDeserializer;
+ }
+}
diff --git a/ZeroLevel/Services/PartitionStorage/StoreStandartSerializer.cs b/ZeroLevel/Services/PartitionStorage/StoreStandartSerializer.cs
deleted file mode 100644
index 5dcbc68..0000000
--- a/ZeroLevel/Services/PartitionStorage/StoreStandartSerializer.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-using System;
-using ZeroLevel.Services.PartitionStorage.Interfaces;
-using ZeroLevel.Services.Serialization;
-
-namespace ZeroLevel.Services.PartitionStorage
-{
-
-
- // TODO INTERNAL
- public sealed class StoreStandartSerializer
- : IStoreSerializer
- {
- private readonly Action _keySerializer;
- private readonly Action _inputSerializer;
- private readonly TryDeserializeMethod _keyDeserializer;
- private readonly TryDeserializeMethod _inputDeserializer;
- private readonly TryDeserializeMethod _valueDeserializer;
-
- public StoreStandartSerializer()
- {
- _keySerializer = MessageSerializer.GetSerializer();
- _inputSerializer = MessageSerializer.GetSerializer();
-
- _keyDeserializer = MessageSerializer.GetSafetyDeserializer();
- _inputDeserializer = MessageSerializer.GetSafetyDeserializer();
- _valueDeserializer = MessageSerializer.GetSafetyDeserializer();
- }
-
- public Action KeySerializer => _keySerializer;
-
- public Action InputSerializer => _inputSerializer;
-
- public TryDeserializeMethod KeyDeserializer => _keyDeserializer;
-
- public TryDeserializeMethod InputDeserializer => _inputDeserializer;
-
- public TryDeserializeMethod ValueDeserializer => _valueDeserializer;
- }
-}
diff --git a/ZeroLevel/Services/PartitionStorage/UniformKeyValueStorage.cs b/ZeroLevel/Services/PartitionStorage/UniformKeyValueStorage.cs
deleted file mode 100644
index cfc755b..0000000
--- a/ZeroLevel/Services/PartitionStorage/UniformKeyValueStorage.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace ZeroLevel.Services.PartitionStorage
-{
- public sealed class UniformKeyValueStorage
- {
-
- }
-}
diff --git a/ZeroLevel/Services/Serialization/IBinaryReader.cs b/ZeroLevel/Services/Serialization/IBinaryReader.cs
index a5bd294..a45a048 100644
--- a/ZeroLevel/Services/Serialization/IBinaryReader.cs
+++ b/ZeroLevel/Services/Serialization/IBinaryReader.cs
@@ -2,6 +2,7 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Net;
+using System.Threading.Tasks;
namespace ZeroLevel.Services.Serialization
{
@@ -57,7 +58,7 @@ namespace ZeroLevel.Services.Serialization
IPAddress[] ReadIPArray();
IPEndPoint[] ReadIPEndPointArray();
Guid[] ReadGuidArray();
- DateTime[] ReadDateTimeArray();
+ DateTime?[] ReadDateTimeArray();
Int64[] ReadInt64Array();
Int32[] ReadInt32Array();
UInt64[] ReadUInt64Array();
@@ -78,7 +79,7 @@ namespace ZeroLevel.Services.Serialization
List ReadCollection() where T : IBinarySerializable, new();
List ReadStringCollection();
List ReadGuidCollection();
- List ReadDateTimeCollection();
+ List ReadDateTimeCollection();
List ReadCharCollection();
List ReadInt64Collection();
List ReadInt32Collection();
@@ -104,7 +105,7 @@ namespace ZeroLevel.Services.Serialization
IEnumerable ReadIPCollectionLazy();
IEnumerable ReadIPEndPointCollectionLazy();
IEnumerable ReadGuidCollectionLazy();
- IEnumerable ReadDateTimeCollectionLazy();
+ IEnumerable ReadDateTimeCollectionLazy();
IEnumerable ReadInt64CollectionLazy();
IEnumerable ReadInt32CollectionLazy();
IEnumerable ReadUInt64CollectionLazy();
@@ -134,4 +135,86 @@ namespace ZeroLevel.Services.Serialization
void SetPosition(long position);
}
+
+ public interface IBinaryReaderAsync
+ : IDisposable
+ {
+ Task ReadBooleanAsync();
+ Task ReadCharAsync();
+ Task ReadByteAsync();
+ Task ReadBytesAsync();
+ Task ReadDoubleAsync();
+ Task ReadFloatAsync();
+ Task ReadShortAsync();
+ Task ReadUShortAsync();
+ Task ReadInt32Async();
+ Task ReadUInt32Async();
+ Task ReadLongAsync();
+ Task ReadULongAsync();
+ Task ReadStringAsync();
+ Task ReadGuidAsync();
+ Task ReadDateTimeAsync();
+ Task ReadTimeAsync();
+ Task ReadDateAsync();
+ Task ReadDecimalAsync();
+ Task ReadTimeSpanAsync();
+ Task ReadIPAsync();
+ Task ReadIPEndpointAsync();
+
+ #region Extensions
+
+ #region Arrays
+ Task ReadArrayAsync() where T : IAsyncBinarySerializable, new();
+ Task