diff --git a/src/Neo/Persistence/DataCache.cs b/src/Neo/Persistence/DataCache.cs
index f70d0000ff..558ce4eaca 100644
--- a/src/Neo/Persistence/DataCache.cs
+++ b/src/Neo/Persistence/DataCache.cs
@@ -42,9 +42,20 @@ public class Trackable(StorageItem item, TrackState state)
public TrackState State { get; set; } = state;
}
+ ///
+ /// Delegate for storage entries
+ ///
+ /// DataCache
+ /// Key
+ /// Item
+ public delegate void OnEntryDelegate(DataCache sender, StorageKey key, StorageItem item);
+
private readonly Dictionary _dictionary = [];
private readonly HashSet? _changeSet;
+ public event OnEntryDelegate? OnRead;
+ public event OnEntryDelegate? OnUpdate;
+
///
/// True if DataCache is readOnly
///
@@ -145,7 +156,7 @@ public virtual void Commit()
trackable.State = TrackState.None;
break;
case TrackState.Changed:
- UpdateInternal(key, trackable.Item);
+ UpdateInternalWrapper(key, trackable.Item);
trackable.State = TrackState.None;
break;
case TrackState.Deleted:
@@ -218,7 +229,7 @@ public void Delete(StorageKey key)
}
else
{
- var item = TryGetInternal(key);
+ var item = TryGetInternalWrapper(key);
if (item == null) return;
_dictionary.Add(key, new Trackable(item, TrackState.Deleted));
_changeSet?.Add(key);
@@ -390,7 +401,7 @@ public bool Contains(StorageKey key)
}
else
{
- var item = TryGetInternal(key);
+ var item = TryGetInternalWrapper(key);
if (item == null)
{
if (factory == null) return null;
@@ -407,6 +418,21 @@ public bool Contains(StorageKey key)
}
}
+ private StorageItem? TryGetInternalWrapper(StorageKey key)
+ {
+ var item = TryGetInternal(key);
+ if (item == null) return null;
+
+ OnRead?.Invoke(this, key, item);
+ return item;
+ }
+
+ private void UpdateInternalWrapper(StorageKey key, StorageItem value)
+ {
+ UpdateInternal(key, value);
+ OnUpdate?.Invoke(this, key, value);
+ }
+
///
/// Reads a specified entry from the cache.
/// If the entry is not in the cache, it will be automatically loaded from the underlying storage.
@@ -440,7 +466,7 @@ public StorageItem GetOrAdd(StorageKey key, Func factory)
}
else
{
- var item = TryGetInternal(key);
+ var item = TryGetInternalWrapper(key);
if (item == null)
{
trackable = new Trackable(factory(), TrackState.Added);
@@ -538,7 +564,7 @@ public StorageItem GetOrAdd(StorageKey key, Func factory)
return null;
return trackable.Item;
}
- var value = TryGetInternal(key);
+ var value = TryGetInternalWrapper(key);
if (value == null) return null;
_dictionary.Add(key, new Trackable(value, TrackState.None));
return value;
diff --git a/src/Neo/Persistence/IStore.cs b/src/Neo/Persistence/IStore.cs
index ba833f7220..6a79ff0549 100644
--- a/src/Neo/Persistence/IStore.cs
+++ b/src/Neo/Persistence/IStore.cs
@@ -23,6 +23,18 @@ public interface IStore :
IWriteStore,
IDisposable
{
+ ///
+ /// Delegate for OnNewSnapshot
+ ///
+ /// Store
+ /// Snapshot
+ public delegate void OnNewSnapshotDelegate(IStore sender, IStoreSnapshot snapshot);
+
+ ///
+ /// Event raised when a new snapshot is created
+ ///
+ public event OnNewSnapshotDelegate? OnNewSnapshot;
+
///
/// Creates a snapshot of the database.
///
diff --git a/src/Neo/Persistence/Providers/MemoryStore.cs b/src/Neo/Persistence/Providers/MemoryStore.cs
index 2786ed4953..cbe8f3d748 100644
--- a/src/Neo/Persistence/Providers/MemoryStore.cs
+++ b/src/Neo/Persistence/Providers/MemoryStore.cs
@@ -27,6 +27,9 @@ public class MemoryStore : IStore
{
private readonly ConcurrentDictionary _innerData = new(ByteArrayEqualityComparer.Default);
+ ///
+ public event IStore.OnNewSnapshotDelegate? OnNewSnapshot;
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Delete(byte[] key)
{
@@ -38,7 +41,9 @@ public void Dispose() { }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public IStoreSnapshot GetSnapshot()
{
- return new MemorySnapshot(this, _innerData);
+ var snapshot = new MemorySnapshot(this, _innerData);
+ OnNewSnapshot?.Invoke(this, snapshot);
+ return snapshot;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
diff --git a/src/Plugins/LevelDBStore/Plugins/Storage/Store.cs b/src/Plugins/LevelDBStore/Plugins/Storage/Store.cs
index ae58cfeaab..c5c3eccce9 100644
--- a/src/Plugins/LevelDBStore/Plugins/Storage/Store.cs
+++ b/src/Plugins/LevelDBStore/Plugins/Storage/Store.cs
@@ -25,6 +25,9 @@ internal class Store : IStore, IEnumerable>
private readonly DB _db;
private readonly Options _options;
+ ///
+ public event IStore.OnNewSnapshotDelegate? OnNewSnapshot;
+
public Store(string path)
{
_options = new Options
@@ -47,8 +50,12 @@ public void Dispose()
_options.Dispose();
}
- public IStoreSnapshot GetSnapshot() =>
- new Snapshot(this, _db);
+ public IStoreSnapshot GetSnapshot()
+ {
+ var snapshot = new Snapshot(this, _db);
+ OnNewSnapshot?.Invoke(this, snapshot);
+ return snapshot;
+ }
public void Put(byte[] key, byte[] value) =>
_db.Put(WriteOptions.Default, key, value);
diff --git a/src/Plugins/RocksDBStore/Plugins/Storage/Store.cs b/src/Plugins/RocksDBStore/Plugins/Storage/Store.cs
index 82f295647a..b94f20a924 100644
--- a/src/Plugins/RocksDBStore/Plugins/Storage/Store.cs
+++ b/src/Plugins/RocksDBStore/Plugins/Storage/Store.cs
@@ -22,6 +22,9 @@ internal class Store : IStore
{
private readonly RocksDb _db;
+ ///
+ public event IStore.OnNewSnapshotDelegate? OnNewSnapshot;
+
public Store(string path)
{
_db = RocksDb.Open(Options.Default, Path.GetFullPath(path));
@@ -34,7 +37,9 @@ public void Dispose()
public IStoreSnapshot GetSnapshot()
{
- return new Snapshot(this, _db);
+ var snapshot = new Snapshot(this, _db);
+ OnNewSnapshot?.Invoke(this, snapshot);
+ return snapshot;
}
///
diff --git a/tests/Neo.UnitTests/Persistence/UT_DataCache.cs b/tests/Neo.UnitTests/Persistence/UT_DataCache.cs
index 35103222ae..aadd1ad404 100644
--- a/tests/Neo.UnitTests/Persistence/UT_DataCache.cs
+++ b/tests/Neo.UnitTests/Persistence/UT_DataCache.cs
@@ -19,84 +19,89 @@
using System.Linq;
using System.Text;
-namespace Neo.UnitTests.IO.Caching
+namespace Neo.UnitTests.Persistence
{
[TestClass]
public class UT_DataCache
{
- private readonly MemoryStore store = new();
- private StoreCache myDataCache;
+ private readonly MemoryStore _store = new();
+ private StoreCache _myDataCache;
- private static readonly StorageKey key1 = new() { Id = 0, Key = Encoding.UTF8.GetBytes("key1") };
- private static readonly StorageKey key2 = new() { Id = 0, Key = Encoding.UTF8.GetBytes("key2") };
- private static readonly StorageKey key3 = new() { Id = 0, Key = Encoding.UTF8.GetBytes("key3") };
- private static readonly StorageKey key4 = new() { Id = 0, Key = Encoding.UTF8.GetBytes("key4") };
- private static readonly StorageKey key5 = new() { Id = 0, Key = Encoding.UTF8.GetBytes("key5") };
+ private static readonly StorageKey s_key1 = new() { Id = 0, Key = Encoding.UTF8.GetBytes("key1") };
+ private static readonly StorageKey s_key2 = new() { Id = 0, Key = Encoding.UTF8.GetBytes("key2") };
+ private static readonly StorageKey s_key3 = new() { Id = 0, Key = Encoding.UTF8.GetBytes("key3") };
+ private static readonly StorageKey s_key4 = new() { Id = 0, Key = Encoding.UTF8.GetBytes("key4") };
+ private static readonly StorageKey s_key5 = new() { Id = 0, Key = Encoding.UTF8.GetBytes("key5") };
- private static readonly StorageItem value1 = new(Encoding.UTF8.GetBytes("value1"));
- private static readonly StorageItem value2 = new(Encoding.UTF8.GetBytes("value2"));
- private static readonly StorageItem value3 = new(Encoding.UTF8.GetBytes("value3"));
- private static readonly StorageItem value4 = new(Encoding.UTF8.GetBytes("value4"));
- private static readonly StorageItem value5 = new(Encoding.UTF8.GetBytes("value5"));
+ private static readonly StorageItem s_value1 = new(Encoding.UTF8.GetBytes("value1"));
+ private static readonly StorageItem s_value2 = new(Encoding.UTF8.GetBytes("value2"));
+ private static readonly StorageItem s_value3 = new(Encoding.UTF8.GetBytes("value3"));
+ private static readonly StorageItem s_value4 = new(Encoding.UTF8.GetBytes("value4"));
+ private static readonly StorageItem s_value5 = new(Encoding.UTF8.GetBytes("value5"));
[TestInitialize]
public void Initialize()
{
- myDataCache = new(store, false);
+ _myDataCache = new(_store, false);
}
[TestMethod]
public void TestAccessByKey()
{
- myDataCache.Add(key1, value1);
- myDataCache.Add(key2, value2);
+ _myDataCache.Add(s_key1, s_value1);
+ _myDataCache.Add(s_key2, s_value2);
- Assert.IsTrue(myDataCache[key1].EqualsTo(value1));
+ Assert.IsTrue(_myDataCache[s_key1].EqualsTo(s_value1));
// case 2 read from inner
- store.Put(key3.ToArray(), value3.ToArray());
- Assert.IsTrue(myDataCache[key3].EqualsTo(value3));
+ _store.Put(s_key3.ToArray(), s_value3.ToArray());
+ Assert.IsTrue(_myDataCache[s_key3].EqualsTo(s_value3));
}
[TestMethod]
public void TestAccessByNotFoundKey()
{
- Action action = () =>
+ Assert.ThrowsExactly(() =>
{
- var item = myDataCache[key1];
- };
- Assert.ThrowsExactly(action);
+ _ = _myDataCache[s_key1];
+ });
}
[TestMethod]
public void TestAccessByDeletedKey()
{
- store.Put(key1.ToArray(), value1.ToArray());
- myDataCache.Delete(key1);
+ _store.Put(s_key1.ToArray(), s_value1.ToArray());
+ _myDataCache.Delete(s_key1);
- Action action = () =>
+ Assert.ThrowsExactly(() =>
{
- var item = myDataCache[key1];
- };
- Assert.ThrowsExactly(action);
+ _ = _myDataCache[s_key1];
+ });
}
[TestMethod]
public void TestAdd()
{
- myDataCache.Add(key1, value1);
- Assert.AreEqual(value1, myDataCache[key1]);
+ var read = 0;
+ var updated = 0;
+ _myDataCache.OnRead += (sender, key, value) => { read++; };
+ _myDataCache.OnUpdate += (sender, key, value) => { updated++; };
+ _myDataCache.Add(s_key1, s_value1);
- Action action = () => myDataCache.Add(key1, value1);
+ Assert.AreEqual(s_value1, _myDataCache[s_key1]);
+ Assert.AreEqual(0, read);
+ Assert.AreEqual(0, updated);
+
+ Action action = () => _myDataCache.Add(s_key1, s_value1);
Assert.ThrowsExactly(action);
- store.Put(key2.ToArray(), value2.ToArray());
- myDataCache.Delete(key2);
- Assert.AreEqual(TrackState.Deleted, myDataCache.GetChangeSet().Where(u => u.Key.Equals(key2)).Select(u => u.Value.State).FirstOrDefault());
- myDataCache.Add(key2, value2);
- Assert.AreEqual(TrackState.Changed, myDataCache.GetChangeSet().Where(u => u.Key.Equals(key2)).Select(u => u.Value.State).FirstOrDefault());
+ _store.Put(s_key2.ToArray(), s_value2.ToArray());
+ _myDataCache.Delete(s_key2);
+ Assert.AreEqual(TrackState.Deleted, _myDataCache.GetChangeSet().Where(u => u.Key.Equals(s_key2)).Select(u => u.Value.State).FirstOrDefault());
+ _myDataCache.Add(s_key2, s_value2);
+ Assert.AreEqual(TrackState.Changed, _myDataCache.GetChangeSet().Where(u => u.Key.Equals(s_key2)).Select(u => u.Value.State).FirstOrDefault());
- action = () => myDataCache.Add(key2, value2);
+ action = () => _myDataCache.Add(s_key2, s_value2);
Assert.ThrowsExactly(action);
}
@@ -104,138 +109,156 @@ public void TestAdd()
public void TestCommit()
{
using var store = new MemoryStore();
- store.Put(key2.ToArray(), value2.ToArray());
- store.Put(key3.ToArray(), value3.ToArray());
+ store.Put(s_key2.ToArray(), s_value2.ToArray());
+ store.Put(s_key3.ToArray(), s_value3.ToArray());
using var snapshot = store.GetSnapshot();
using var myDataCache = new StoreCache(snapshot);
- myDataCache.Add(key1, value1);
- Assert.AreEqual(TrackState.Added, myDataCache.GetChangeSet().Where(u => u.Key.Equals(key1)).Select(u => u.Value.State).FirstOrDefault());
+ var read = 0;
+ var updated = 0;
+ myDataCache.OnRead += (sender, key, value) => { read++; };
+ myDataCache.OnUpdate += (sender, key, value) => { updated++; };
+
+ myDataCache.Add(s_key1, s_value1);
+ Assert.AreEqual(TrackState.Added, myDataCache.GetChangeSet().Where(u => u.Key.Equals(s_key1)).Select(u => u.Value.State).FirstOrDefault());
+ Assert.AreEqual(0, read);
+ Assert.AreEqual(0, updated);
+
+ myDataCache.Delete(s_key2);
+
+ Assert.AreEqual(TrackState.Deleted, myDataCache.GetChangeSet().Where(u => u.Key.Equals(s_key2)).Select(u => u.Value.State).FirstOrDefault());
+ Assert.AreEqual(1, read);
+ Assert.AreEqual(0, updated);
+ Assert.AreEqual(TrackState.None, myDataCache.GetChangeSet().Where(u => u.Key.Equals(s_key3)).Select(u => u.Value.State).FirstOrDefault());
- myDataCache.Delete(key2);
- Assert.AreEqual(TrackState.Deleted, myDataCache.GetChangeSet().Where(u => u.Key.Equals(key2)).Select(u => u.Value.State).FirstOrDefault());
+ myDataCache.Delete(s_key3);
- Assert.AreEqual(TrackState.None, myDataCache.GetChangeSet().Where(u => u.Key.Equals(key3)).Select(u => u.Value.State).FirstOrDefault());
- myDataCache.Delete(key3);
- Assert.AreEqual(TrackState.Deleted, myDataCache.GetChangeSet().Where(u => u.Key.Equals(key3)).Select(u => u.Value.State).FirstOrDefault());
- myDataCache.Add(key3, value4);
- Assert.AreEqual(TrackState.Changed, myDataCache.GetChangeSet().Where(u => u.Key.Equals(key3)).Select(u => u.Value.State).FirstOrDefault());
+ Assert.AreEqual(2, read);
+ Assert.AreEqual(0, updated);
+ Assert.AreEqual(TrackState.Deleted, myDataCache.GetChangeSet().Where(u => u.Key.Equals(s_key3)).Select(u => u.Value.State).FirstOrDefault());
+
+ myDataCache.Add(s_key3, s_value4);
+ Assert.AreEqual(TrackState.Changed, myDataCache.GetChangeSet().Where(u => u.Key.Equals(s_key3)).Select(u => u.Value.State).FirstOrDefault());
+ Assert.AreEqual(2, read);
+ Assert.AreEqual(0, updated);
// If we use myDataCache after it is committed, it will return wrong result.
myDataCache.Commit();
- Assert.AreEqual(0, myDataCache.GetChangeSet().Count());
- Assert.IsTrue(store.TryGet(key1.ToArray()).SequenceEqual(value1.ToArray()));
- Assert.IsNull(store.TryGet(key2.ToArray()));
- Assert.IsTrue(store.TryGet(key3.ToArray()).SequenceEqual(value4.ToArray()));
+ Assert.AreEqual(0, myDataCache.GetChangeSet().Count());
+ Assert.AreEqual(2, read);
+ Assert.AreEqual(1, updated);
+ Assert.IsTrue(store.TryGet(s_key1.ToArray()).SequenceEqual(s_value1.ToArray()));
+ Assert.IsNull(store.TryGet(s_key2.ToArray()));
+ Assert.IsTrue(store.TryGet(s_key3.ToArray()).SequenceEqual(s_value4.ToArray()));
- Assert.IsTrue(myDataCache.TryGet(key1).Value.ToArray().SequenceEqual(value1.ToArray()));
+ Assert.IsTrue(myDataCache.TryGet(s_key1).Value.ToArray().SequenceEqual(s_value1.ToArray()));
// Though value is deleted from the store, the value can still be gotten from the snapshot cache.
- Assert.IsTrue(myDataCache.TryGet(key2).Value.ToArray().SequenceEqual(value2.ToArray()));
- Assert.IsTrue(myDataCache.TryGet(key3).Value.ToArray().SequenceEqual(value4.ToArray()));
+ Assert.IsTrue(myDataCache.TryGet(s_key2).Value.ToArray().SequenceEqual(s_value2.ToArray()));
+ Assert.IsTrue(myDataCache.TryGet(s_key3).Value.ToArray().SequenceEqual(s_value4.ToArray()));
}
[TestMethod]
public void TestCreateSnapshot()
{
- Assert.IsNotNull(myDataCache.CloneCache());
+ Assert.IsNotNull(_myDataCache.CloneCache());
}
[TestMethod]
public void TestDelete()
{
using var store = new MemoryStore();
- store.Put(key2.ToArray(), value2.ToArray());
+ store.Put(s_key2.ToArray(), s_value2.ToArray());
using var snapshot = store.GetSnapshot();
using var myDataCache = new StoreCache(snapshot);
- myDataCache.Add(key1, value1);
- myDataCache.Delete(key1);
- Assert.IsNull(store.TryGet(key1.ToArray()));
+ myDataCache.Add(s_key1, s_value1);
+ myDataCache.Delete(s_key1);
+ Assert.IsNull(store.TryGet(s_key1.ToArray()));
- myDataCache.Delete(key2);
+ myDataCache.Delete(s_key2);
myDataCache.Commit();
- Assert.IsNull(store.TryGet(key2.ToArray()));
+ Assert.IsNull(store.TryGet(s_key2.ToArray()));
}
[TestMethod]
public void TestFind()
{
- myDataCache.Add(key1, value1);
- myDataCache.Add(key2, value2);
+ _myDataCache.Add(s_key1, s_value1);
+ _myDataCache.Add(s_key2, s_value2);
- store.Put(key3.ToArray(), value3.ToArray());
- store.Put(key4.ToArray(), value4.ToArray());
+ _store.Put(s_key3.ToArray(), s_value3.ToArray());
+ _store.Put(s_key4.ToArray(), s_value4.ToArray());
- var k1 = key1.ToArray();
- var items = myDataCache.Find(k1);
- Assert.AreEqual(key1, items.ElementAt(0).Key);
- Assert.AreEqual(value1, items.ElementAt(0).Value);
+ var k1 = s_key1.ToArray();
+ var items = _myDataCache.Find(k1);
+ Assert.AreEqual(s_key1, items.ElementAt(0).Key);
+ Assert.AreEqual(s_value1, items.ElementAt(0).Value);
Assert.AreEqual(1, items.Count());
// null and empty with the forward direction -> finds everything.
- items = myDataCache.Find(null);
+ items = _myDataCache.Find(null);
Assert.AreEqual(4, items.Count());
- items = myDataCache.Find([]);
+ items = _myDataCache.Find([]);
Assert.AreEqual(4, items.Count());
// null and empty with the backwards direction -> miserably fails.
- Action action = () => myDataCache.Find(null, SeekDirection.Backward);
+ Action action = () => _myDataCache.Find(null, SeekDirection.Backward);
Assert.ThrowsExactly(action);
- action = () => myDataCache.Find([], SeekDirection.Backward);
+ action = () => _myDataCache.Find([], SeekDirection.Backward);
Assert.ThrowsExactly(action);
- items = myDataCache.Find(k1, SeekDirection.Backward);
- Assert.AreEqual(key1, items.ElementAt(0).Key);
- Assert.AreEqual(value1, items.ElementAt(0).Value);
+ items = _myDataCache.Find(k1, SeekDirection.Backward);
+ Assert.AreEqual(s_key1, items.ElementAt(0).Key);
+ Assert.AreEqual(s_value1, items.ElementAt(0).Value);
Assert.AreEqual(1, items.Count());
- var prefix = k1.Take(k1.Count() - 1).ToArray(); // Just the "key" part to match everything.
- items = myDataCache.Find(prefix);
+ var prefix = k1.Take(k1.Length - 1).ToArray(); // Just the "key" part to match everything.
+ items = _myDataCache.Find(prefix);
Assert.AreEqual(4, items.Count());
- Assert.AreEqual(key1, items.ElementAt(0).Key);
- Assert.AreEqual(value1, items.ElementAt(0).Value);
- Assert.AreEqual(key2, items.ElementAt(1).Key);
- Assert.AreEqual(value2, items.ElementAt(1).Value);
- Assert.AreEqual(key3, items.ElementAt(2).Key);
- Assert.IsTrue(items.ElementAt(2).Value.EqualsTo(value3));
- Assert.AreEqual(key4, items.ElementAt(3).Key);
- Assert.IsTrue(items.ElementAt(3).Value.EqualsTo(value4));
-
- items = myDataCache.Find(prefix, SeekDirection.Backward);
+ Assert.AreEqual(s_key1, items.ElementAt(0).Key);
+ Assert.AreEqual(s_value1, items.ElementAt(0).Value);
+ Assert.AreEqual(s_key2, items.ElementAt(1).Key);
+ Assert.AreEqual(s_value2, items.ElementAt(1).Value);
+ Assert.AreEqual(s_key3, items.ElementAt(2).Key);
+ Assert.IsTrue(items.ElementAt(2).Value.EqualsTo(s_value3));
+ Assert.AreEqual(s_key4, items.ElementAt(3).Key);
+ Assert.IsTrue(items.ElementAt(3).Value.EqualsTo(s_value4));
+
+ items = _myDataCache.Find(prefix, SeekDirection.Backward);
Assert.AreEqual(4, items.Count());
- Assert.AreEqual(key4, items.ElementAt(0).Key);
- Assert.IsTrue(items.ElementAt(0).Value.EqualsTo(value4));
- Assert.AreEqual(key3, items.ElementAt(1).Key);
- Assert.IsTrue(items.ElementAt(1).Value.EqualsTo(value3));
- Assert.AreEqual(key2, items.ElementAt(2).Key);
- Assert.AreEqual(value2, items.ElementAt(2).Value);
- Assert.AreEqual(key1, items.ElementAt(3).Key);
- Assert.AreEqual(value1, items.ElementAt(3).Value);
-
- items = myDataCache.Find(key5);
+ Assert.AreEqual(s_key4, items.ElementAt(0).Key);
+ Assert.IsTrue(items.ElementAt(0).Value.EqualsTo(s_value4));
+ Assert.AreEqual(s_key3, items.ElementAt(1).Key);
+ Assert.IsTrue(items.ElementAt(1).Value.EqualsTo(s_value3));
+ Assert.AreEqual(s_key2, items.ElementAt(2).Key);
+ Assert.AreEqual(s_value2, items.ElementAt(2).Value);
+ Assert.AreEqual(s_key1, items.ElementAt(3).Key);
+ Assert.AreEqual(s_value1, items.ElementAt(3).Value);
+
+ items = _myDataCache.Find(s_key5);
Assert.AreEqual(0, items.Count());
}
[TestMethod]
public void TestSeek()
{
- myDataCache.Add(key1, value1);
- myDataCache.Add(key2, value2);
+ _myDataCache.Add(s_key1, s_value1);
+ _myDataCache.Add(s_key2, s_value2);
- store.Put(key3.ToArray(), value3.ToArray());
- store.Put(key4.ToArray(), value4.ToArray());
+ _store.Put(s_key3.ToArray(), s_value3.ToArray());
+ _store.Put(s_key4.ToArray(), s_value4.ToArray());
- var items = myDataCache.Seek(key3.ToArray(), SeekDirection.Backward).ToArray();
- Assert.AreEqual(key3, items[0].Key);
- Assert.IsTrue(items[0].Value.EqualsTo(value3));
- Assert.AreEqual(key2, items[1].Key);
- Assert.IsTrue(items[1].Value.EqualsTo(value2));
+ var items = _myDataCache.Seek(s_key3.ToArray(), SeekDirection.Backward).ToArray();
+ Assert.AreEqual(s_key3, items[0].Key);
+ Assert.IsTrue(items[0].Value.EqualsTo(s_value3));
+ Assert.AreEqual(s_key2, items[1].Key);
+ Assert.IsTrue(items[1].Value.EqualsTo(s_value2));
Assert.AreEqual(3, items.Length);
- items = myDataCache.Seek(key5.ToArray(), SeekDirection.Forward).ToArray();
+ items = [.. _myDataCache.Seek(s_key5.ToArray(), SeekDirection.Forward)];
Assert.AreEqual(0, items.Length);
}
@@ -243,73 +266,73 @@ public void TestSeek()
public void TestFindRange()
{
var store = new MemoryStore();
- store.Put(key3.ToArray(), value3.ToArray());
- store.Put(key4.ToArray(), value4.ToArray());
+ store.Put(s_key3.ToArray(), s_value3.ToArray());
+ store.Put(s_key4.ToArray(), s_value4.ToArray());
var myDataCache = new StoreCache(store);
- myDataCache.Add(key1, value1);
- myDataCache.Add(key2, value2);
-
- var items = myDataCache.FindRange(key3.ToArray(), key5.ToArray()).ToArray();
- Assert.AreEqual(key3, items[0].Key);
- Assert.IsTrue(items[0].Value.EqualsTo(value3));
- Assert.AreEqual(key4, items[1].Key);
- Assert.IsTrue(items[1].Value.EqualsTo(value4));
+ myDataCache.Add(s_key1, s_value1);
+ myDataCache.Add(s_key2, s_value2);
+
+ var items = myDataCache.FindRange(s_key3.ToArray(), s_key5.ToArray()).ToArray();
+ Assert.AreEqual(s_key3, items[0].Key);
+ Assert.IsTrue(items[0].Value.EqualsTo(s_value3));
+ Assert.AreEqual(s_key4, items[1].Key);
+ Assert.IsTrue(items[1].Value.EqualsTo(s_value4));
Assert.AreEqual(2, items.Length);
// case 2 Need to sort the cache of myDataCache
store = new();
- store.Put(key4.ToArray(), value4.ToArray());
- store.Put(key3.ToArray(), value3.ToArray());
+ store.Put(s_key4.ToArray(), s_value4.ToArray());
+ store.Put(s_key3.ToArray(), s_value3.ToArray());
myDataCache = new(store);
- myDataCache.Add(key1, value1);
- myDataCache.Add(key2, value2);
-
- items = myDataCache.FindRange(key3.ToArray(), key5.ToArray()).ToArray();
- Assert.AreEqual(key3, items[0].Key);
- Assert.IsTrue(items[0].Value.EqualsTo(value3));
- Assert.AreEqual(key4, items[1].Key);
- Assert.IsTrue(items[1].Value.EqualsTo(value4));
+ myDataCache.Add(s_key1, s_value1);
+ myDataCache.Add(s_key2, s_value2);
+
+ items = [.. myDataCache.FindRange(s_key3.ToArray(), s_key5.ToArray())];
+ Assert.AreEqual(s_key3, items[0].Key);
+ Assert.IsTrue(items[0].Value.EqualsTo(s_value3));
+ Assert.AreEqual(s_key4, items[1].Key);
+ Assert.IsTrue(items[1].Value.EqualsTo(s_value4));
Assert.AreEqual(2, items.Length);
// case 3 FindRange by Backward
store = new();
- store.Put(key4.ToArray(), value4.ToArray());
- store.Put(key3.ToArray(), value3.ToArray());
- store.Put(key5.ToArray(), value5.ToArray());
+ store.Put(s_key4.ToArray(), s_value4.ToArray());
+ store.Put(s_key3.ToArray(), s_value3.ToArray());
+ store.Put(s_key5.ToArray(), s_value5.ToArray());
myDataCache = new(store);
- myDataCache.Add(key1, value1);
- myDataCache.Add(key2, value2);
-
- items = myDataCache.FindRange(key5.ToArray(), key3.ToArray(), SeekDirection.Backward).ToArray();
- Assert.AreEqual(key5, items[0].Key);
- Assert.IsTrue(items[0].Value.EqualsTo(value5));
- Assert.AreEqual(key4, items[1].Key);
- Assert.IsTrue(items[1].Value.EqualsTo(value4));
+ myDataCache.Add(s_key1, s_value1);
+ myDataCache.Add(s_key2, s_value2);
+
+ items = [.. myDataCache.FindRange(s_key5.ToArray(), s_key3.ToArray(), SeekDirection.Backward)];
+ Assert.AreEqual(s_key5, items[0].Key);
+ Assert.IsTrue(items[0].Value.EqualsTo(s_value5));
+ Assert.AreEqual(s_key4, items[1].Key);
+ Assert.IsTrue(items[1].Value.EqualsTo(s_value4));
Assert.AreEqual(2, items.Length);
}
[TestMethod]
public void TestGetChangeSet()
{
- myDataCache.Add(key1, value1);
- Assert.AreEqual(TrackState.Added, myDataCache.GetChangeSet().Where(u => u.Key.Equals(key1)).Select(u => u.Value.State).FirstOrDefault());
- myDataCache.Add(key2, value2);
- Assert.AreEqual(TrackState.Added, myDataCache.GetChangeSet().Where(u => u.Key.Equals(key2)).Select(u => u.Value.State).FirstOrDefault());
-
- store.Put(key3.ToArray(), value3.ToArray());
- store.Put(key4.ToArray(), value4.ToArray());
- myDataCache.Delete(key3);
- Assert.AreEqual(TrackState.Deleted, myDataCache.GetChangeSet().Where(u => u.Key.Equals(key3)).Select(u => u.Value.State).FirstOrDefault());
- myDataCache.Delete(key4);
- Assert.AreEqual(TrackState.Deleted, myDataCache.GetChangeSet().Where(u => u.Key.Equals(key4)).Select(u => u.Value.State).FirstOrDefault());
-
- var items = myDataCache.GetChangeSet();
- int i = 0;
+ _myDataCache.Add(s_key1, s_value1);
+ Assert.AreEqual(TrackState.Added, _myDataCache.GetChangeSet().Where(u => u.Key.Equals(s_key1)).Select(u => u.Value.State).FirstOrDefault());
+ _myDataCache.Add(s_key2, s_value2);
+ Assert.AreEqual(TrackState.Added, _myDataCache.GetChangeSet().Where(u => u.Key.Equals(s_key2)).Select(u => u.Value.State).FirstOrDefault());
+
+ _store.Put(s_key3.ToArray(), s_value3.ToArray());
+ _store.Put(s_key4.ToArray(), s_value4.ToArray());
+ _myDataCache.Delete(s_key3);
+ Assert.AreEqual(TrackState.Deleted, _myDataCache.GetChangeSet().Where(u => u.Key.Equals(s_key3)).Select(u => u.Value.State).FirstOrDefault());
+ _myDataCache.Delete(s_key4);
+ Assert.AreEqual(TrackState.Deleted, _myDataCache.GetChangeSet().Where(u => u.Key.Equals(s_key4)).Select(u => u.Value.State).FirstOrDefault());
+
+ var items = _myDataCache.GetChangeSet();
+ var i = 0;
foreach (var item in items)
{
i++;
@@ -324,58 +347,58 @@ public void TestGetChangeSet()
[TestMethod]
public void TestGetAndChange()
{
- myDataCache.Add(key1, value1);
- Assert.AreEqual(TrackState.Added, myDataCache.GetChangeSet().Where(u => u.Key.Equals(key1)).Select(u => u.Value.State).FirstOrDefault());
- store.Put(key2.ToArray(), value2.ToArray());
- store.Put(key3.ToArray(), value3.ToArray());
- myDataCache.Delete(key3);
- Assert.AreEqual(TrackState.Deleted, myDataCache.GetChangeSet().Where(u => u.Key.Equals(key3)).Select(u => u.Value.State).FirstOrDefault());
+ _myDataCache.Add(s_key1, s_value1);
+ Assert.AreEqual(TrackState.Added, _myDataCache.GetChangeSet().Where(u => u.Key.Equals(s_key1)).Select(u => u.Value.State).FirstOrDefault());
+ _store.Put(s_key2.ToArray(), s_value2.ToArray());
+ _store.Put(s_key3.ToArray(), s_value3.ToArray());
+ _myDataCache.Delete(s_key3);
+ Assert.AreEqual(TrackState.Deleted, _myDataCache.GetChangeSet().Where(u => u.Key.Equals(s_key3)).Select(u => u.Value.State).FirstOrDefault());
StorageItem value_bk_1 = new(Encoding.UTF8.GetBytes("value_bk_1"));
StorageItem value_bk_2 = new(Encoding.UTF8.GetBytes("value_bk_2"));
StorageItem value_bk_3 = new(Encoding.UTF8.GetBytes("value_bk_3"));
StorageItem value_bk_4 = new(Encoding.UTF8.GetBytes("value_bk_4"));
- Assert.IsTrue(myDataCache.GetAndChange(key1, () => value_bk_1).EqualsTo(value1));
- Assert.IsTrue(myDataCache.GetAndChange(key2, () => value_bk_2).EqualsTo(value2));
- Assert.IsTrue(myDataCache.GetAndChange(key3, () => value_bk_3).EqualsTo(value_bk_3));
- Assert.IsTrue(myDataCache.GetAndChange(key4, () => value_bk_4).EqualsTo(value_bk_4));
+ Assert.IsTrue(_myDataCache.GetAndChange(s_key1, () => value_bk_1).EqualsTo(s_value1));
+ Assert.IsTrue(_myDataCache.GetAndChange(s_key2, () => value_bk_2).EqualsTo(s_value2));
+ Assert.IsTrue(_myDataCache.GetAndChange(s_key3, () => value_bk_3).EqualsTo(value_bk_3));
+ Assert.IsTrue(_myDataCache.GetAndChange(s_key4, () => value_bk_4).EqualsTo(value_bk_4));
}
[TestMethod]
public void TestGetOrAdd()
{
- myDataCache.Add(key1, value1);
- Assert.AreEqual(TrackState.Added, myDataCache.GetChangeSet().Where(u => u.Key.Equals(key1)).Select(u => u.Value.State).FirstOrDefault());
- store.Put(key2.ToArray(), value2.ToArray());
- store.Put(key3.ToArray(), value3.ToArray());
- myDataCache.Delete(key3);
- Assert.AreEqual(TrackState.Deleted, myDataCache.GetChangeSet().Where(u => u.Key.Equals(key3)).Select(u => u.Value.State).FirstOrDefault());
+ _myDataCache.Add(s_key1, s_value1);
+ Assert.AreEqual(TrackState.Added, _myDataCache.GetChangeSet().Where(u => u.Key.Equals(s_key1)).Select(u => u.Value.State).FirstOrDefault());
+ _store.Put(s_key2.ToArray(), s_value2.ToArray());
+ _store.Put(s_key3.ToArray(), s_value3.ToArray());
+ _myDataCache.Delete(s_key3);
+ Assert.AreEqual(TrackState.Deleted, _myDataCache.GetChangeSet().Where(u => u.Key.Equals(s_key3)).Select(u => u.Value.State).FirstOrDefault());
StorageItem value_bk_1 = new(Encoding.UTF8.GetBytes("value_bk_1"));
StorageItem value_bk_2 = new(Encoding.UTF8.GetBytes("value_bk_2"));
StorageItem value_bk_3 = new(Encoding.UTF8.GetBytes("value_bk_3"));
StorageItem value_bk_4 = new(Encoding.UTF8.GetBytes("value_bk_4"));
- Assert.IsTrue(myDataCache.GetOrAdd(key1, () => value_bk_1).EqualsTo(value1));
- Assert.IsTrue(myDataCache.GetOrAdd(key2, () => value_bk_2).EqualsTo(value2));
- Assert.IsTrue(myDataCache.GetOrAdd(key3, () => value_bk_3).EqualsTo(value_bk_3));
- Assert.IsTrue(myDataCache.GetOrAdd(key4, () => value_bk_4).EqualsTo(value_bk_4));
+ Assert.IsTrue(_myDataCache.GetOrAdd(s_key1, () => value_bk_1).EqualsTo(s_value1));
+ Assert.IsTrue(_myDataCache.GetOrAdd(s_key2, () => value_bk_2).EqualsTo(s_value2));
+ Assert.IsTrue(_myDataCache.GetOrAdd(s_key3, () => value_bk_3).EqualsTo(value_bk_3));
+ Assert.IsTrue(_myDataCache.GetOrAdd(s_key4, () => value_bk_4).EqualsTo(value_bk_4));
}
[TestMethod]
public void TestTryGet()
{
- myDataCache.Add(key1, value1);
- Assert.AreEqual(TrackState.Added, myDataCache.GetChangeSet().Where(u => u.Key.Equals(key1)).Select(u => u.Value.State).FirstOrDefault());
- store.Put(key2.ToArray(), value2.ToArray());
- store.Put(key3.ToArray(), value3.ToArray());
- myDataCache.Delete(key3);
- Assert.AreEqual(TrackState.Deleted, myDataCache.GetChangeSet().Where(u => u.Key.Equals(key3)).Select(u => u.Value.State).FirstOrDefault());
-
- Assert.IsTrue(myDataCache.TryGet(key1).EqualsTo(value1));
- Assert.IsTrue(myDataCache.TryGet(key2).EqualsTo(value2));
- Assert.IsNull(myDataCache.TryGet(key3));
+ _myDataCache.Add(s_key1, s_value1);
+ Assert.AreEqual(TrackState.Added, _myDataCache.GetChangeSet().Where(u => u.Key.Equals(s_key1)).Select(u => u.Value.State).FirstOrDefault());
+ _store.Put(s_key2.ToArray(), s_value2.ToArray());
+ _store.Put(s_key3.ToArray(), s_value3.ToArray());
+ _myDataCache.Delete(s_key3);
+ Assert.AreEqual(TrackState.Deleted, _myDataCache.GetChangeSet().Where(u => u.Key.Equals(s_key3)).Select(u => u.Value.State).FirstOrDefault());
+
+ Assert.IsTrue(_myDataCache.TryGet(s_key1).EqualsTo(s_value1));
+ Assert.IsTrue(_myDataCache.TryGet(s_key2).EqualsTo(s_value2));
+ Assert.IsNull(_myDataCache.TryGet(s_key3));
}
[TestMethod]
@@ -383,24 +406,24 @@ public void TestFindInvalid()
{
using var store = new MemoryStore();
using var myDataCache = new StoreCache(store);
- myDataCache.Add(key1, value1);
+ myDataCache.Add(s_key1, s_value1);
- store.Put(key2.ToArray(), value2.ToArray());
- store.Put(key3.ToArray(), value3.ToArray());
- store.Put(key4.ToArray(), value3.ToArray());
+ store.Put(s_key2.ToArray(), s_value2.ToArray());
+ store.Put(s_key3.ToArray(), s_value3.ToArray());
+ store.Put(s_key4.ToArray(), s_value3.ToArray());
var items = myDataCache.Find(SeekDirection.Forward).GetEnumerator();
items.MoveNext();
- Assert.AreEqual(key1, items.Current.Key);
+ Assert.AreEqual(s_key1, items.Current.Key);
- myDataCache.TryGet(key3); // GETLINE
+ myDataCache.TryGet(s_key3); // GETLINE
items.MoveNext();
- Assert.AreEqual(key2, items.Current.Key);
+ Assert.AreEqual(s_key2, items.Current.Key);
items.MoveNext();
- Assert.AreEqual(key3, items.Current.Key);
+ Assert.AreEqual(s_key3, items.Current.Key);
items.MoveNext();
- Assert.AreEqual(key4, items.Current.Key);
+ Assert.AreEqual(s_key4, items.Current.Key);
Assert.IsFalse(items.MoveNext());
}
}