Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add canonical TryGet style in IReadOnlyStore #3533

Merged
merged 1 commit into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/Neo/Persistence/IReadOnlyStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using System;
using System.Collections.Generic;

namespace Neo.Persistence
Expand All @@ -31,8 +32,17 @@ public interface IReadOnlyStore
/// </summary>
/// <param name="key">The key of the entry.</param>
/// <returns>The data of the entry. Or <see langword="null"/> if it doesn't exist.</returns>
/// <seealso cref="TryGet(byte[], out byte[])"/>. Obsolete it later for avoiding complier warning.
byte[] TryGet(byte[] key);

/// <summary>
/// Reads a specified entry from the database.
/// </summary>
/// <param name="key">The key of the entry.</param>
/// <param name="value">The data of the entry.</param>
/// <returns><see langword="true"/> if the entry exists; otherwise, <see langword="false"/>.</returns>
bool TryGet(byte[] key, out byte[] value);

/// <summary>
/// Determines whether the database contains the specified entry.
/// </summary>
Expand Down
5 changes: 5 additions & 0 deletions src/Neo/Persistence/MemorySnapshot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ public byte[] TryGet(byte[] key)
return value?[..];
}

public bool TryGet(byte[] key, out byte[] value)
{
return immutableData.TryGetValue(key, out value);
}

public bool Contains(byte[] key)
{
return immutableData.ContainsKey(key);
Expand Down
6 changes: 6 additions & 0 deletions src/Neo/Persistence/MemoryStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ public byte[] TryGet(byte[] key)
return value[..];
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool TryGet(byte[] key, out byte[] value)
{
return _innerData.TryGetValue(key, out value);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Contains(byte[] key)
{
Expand Down
6 changes: 6 additions & 0 deletions src/Plugins/LevelDBStore/Plugins/Storage/Snapshot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,11 @@ public byte[] TryGet(byte[] key)
{
return db.Get(options, key);
}

public bool TryGet(byte[] key, out byte[] value)
{
value = db.Get(options, key);
return value != null;
}
}
}
6 changes: 6 additions & 0 deletions src/Plugins/LevelDBStore/Plugins/Storage/Store.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,11 @@ public byte[] TryGet(byte[] key)
{
return db.Get(ReadOptions.Default, key);
}

public bool TryGet(byte[] key, out byte[] value)
{
value = db.Get(ReadOptions.Default, key);
return value != null;
}
}
}
6 changes: 6 additions & 0 deletions src/Plugins/RocksDBStore/Plugins/Storage/Snapshot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ public byte[] TryGet(byte[] key)
return db.Get(key, readOptions: options);
}

public bool TryGet(byte[] key, out byte[] value)
{
value = db.Get(key, readOptions: options);
return value != null;
}

public void Dispose()
{
snapshot.Dispose();
Expand Down
6 changes: 6 additions & 0 deletions src/Plugins/RocksDBStore/Plugins/Storage/Store.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ public byte[] TryGet(byte[] key)
return db.Get(key);
}

public bool TryGet(byte[] key, out byte[] value)
{
value = db.Get(key);
return value != null;
}

public void Delete(byte[] key)
{
db.Remove(key);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ public byte[] TryGet(byte[] key)
return null;
}

public bool TryGet(byte[] key, out byte[] value)
{
return store.TryGetValue(StoreKey(key), out value);
}

public void Dispose() { throw new System.NotImplementedException(); }

public int Size => store.Count;
Expand Down
19 changes: 19 additions & 0 deletions tests/Neo.Plugins.Storage.Tests/StoreTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ public void TestLevelDbSnapshot()
snapshot.Put(testKey, testValue);
// Data saved to the leveldb snapshot shall not be visible to the store
Assert.IsNull(snapshot.TryGet(testKey));
Assert.IsFalse(snapshot.TryGet(testKey, out var got));
Assert.IsNull(got);

// Value is in the write batch, not visible to the store and snapshot
Assert.AreEqual(false, snapshot.Contains(testKey));
Expand All @@ -94,7 +96,13 @@ public void TestLevelDbSnapshot()

// After commit, the data shall be visible to the store but not to the snapshot
Assert.IsNull(snapshot.TryGet(testKey));
Assert.IsFalse(snapshot.TryGet(testKey, out got));
Assert.IsNull(got);

CollectionAssert.AreEqual(testValue, store.TryGet(testKey));
Assert.IsTrue(store.TryGet(testKey, out got));
CollectionAssert.AreEqual(testValue, got);

Assert.AreEqual(false, snapshot.Contains(testKey));
Assert.AreEqual(true, store.Contains(testKey));

Expand Down Expand Up @@ -154,7 +162,12 @@ public void TestRocksDbSnapshot()
snapshot.Put(testKey, testValue);
// Data saved to the leveldb snapshot shall not be visible
Assert.IsNull(snapshot.TryGet(testKey));
Assert.IsFalse(snapshot.TryGet(testKey, out var got));
Assert.IsNull(got);

Assert.IsNull(store.TryGet(testKey));
Assert.IsFalse(store.TryGet(testKey, out got));
Assert.IsNull(got);

// Value is in the write batch, not visible to the store and snapshot
Assert.AreEqual(false, snapshot.Contains(testKey));
Expand All @@ -164,7 +177,13 @@ public void TestRocksDbSnapshot()

// After commit, the data shall be visible to the store but not to the snapshot
Assert.IsNull(snapshot.TryGet(testKey));
Assert.IsFalse(snapshot.TryGet(testKey, out got));
Assert.IsNull(got);

CollectionAssert.AreEqual(testValue, store.TryGet(testKey));
Assert.IsTrue(store.TryGet(testKey, out got));
CollectionAssert.AreEqual(testValue, got);

Assert.AreEqual(false, snapshot.Contains(testKey));
Assert.AreEqual(true, store.Contains(testKey));

Expand Down
8 changes: 8 additions & 0 deletions tests/Neo.UnitTests/Persistence/UT_MemorySnapshot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,14 @@ public void MultiSnapshotTest()
Assert.IsNull(_snapshot.TryGet(key1));
CollectionAssert.AreEqual(value1, snapshot2.TryGet(key1));

Assert.IsFalse(_snapshot.TryGet(key1, out var value2));

Assert.IsTrue(snapshot2.TryGet(key1, out value2));
CollectionAssert.AreEqual(value1, value2);

Assert.IsTrue(_memoryStore.TryGet(key1, out value2));
CollectionAssert.AreEqual(value1, value2);

_snapshot.Delete(key1);

// Deleted value can not being found from the snapshot but can still get from the store and snapshot2
Expand Down
10 changes: 9 additions & 1 deletion tests/Neo.UnitTests/Persistence/UT_MemoryStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ public void StoreTest()

store.Delete([1]);
Assert.AreEqual(null, store.TryGet([1]));
Assert.IsFalse(store.TryGet([1], out var got));
Assert.AreEqual(null, got);

store.Put([1], [1, 2, 3]);
CollectionAssert.AreEqual(new byte[] { 1, 2, 3 }, store.TryGet([1]));

Expand Down Expand Up @@ -79,13 +82,18 @@ public void NeoSystemStoreViewTest()
var store = _neoSystem.StoreView;
var key = new StorageKey(Encoding.UTF8.GetBytes("testKey"));
var value = new StorageItem(Encoding.UTF8.GetBytes("testValue"));

store.Add(key, value);
store.Commit();

var result = store.TryGet(key);
// The StoreView is a readonly view of the store, here it will have value in the cache
Assert.AreEqual("testValue", Encoding.UTF8.GetString(result.Value.ToArray()));
// But the value will not be written to the underlying store even its committed.

// But the value will not be written to the underlying store even its committed.
Assert.IsNull(_memoryStore.TryGet(key.ToArray()));
Assert.IsFalse(_memoryStore.TryGet(key.ToArray(), out var got));
Assert.AreEqual(null, got);
}

[TestMethod]
Expand Down
Loading