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

Create SnapshotCacheReadOnly for read only snapshots #3729

Closed
wants to merge 3 commits into from
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public void ReadOnlyStoreView_LevelDB()
[Benchmark]
public void SnapshotCache_LevelDB()
{
var snapshot = new SnapshotCache(levelDbStore);
var snapshot = new SnapshotCacheReadOnly(levelDbStore);
var ok = snapshot.TryGet(key1, out var _);
Debug.Assert(ok);

Expand Down
2 changes: 1 addition & 1 deletion src/Neo/Ledger/Blockchain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ private void OnTransaction(Transaction tx)

private void Persist(Block block)
{
using (SnapshotCache snapshot = system.GetSnapshotCache())
using (var snapshot = system.GetSnapshotCache())
{
List<ApplicationExecuted> all_application_executed = new();
TransactionState[] transactionStates;
Expand Down
2 changes: 1 addition & 1 deletion src/Neo/NeoSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public class NeoSystem : IDisposable
/// <remarks>
/// It doesn't need to be disposed because the <see cref="ISnapshot"/> inside it is null.
/// </remarks>
public DataCache StoreView => new SnapshotCache(store);
public DataCache StoreView => new SnapshotCacheReadOnly(store);

/// <summary>
/// The memory pool of the <see cref="NeoSystem"/>.
Expand Down
57 changes: 17 additions & 40 deletions src/Neo/Persistence/SnapshotCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,77 +14,54 @@
using Neo.Extensions;
using Neo.SmartContract;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Neo.Persistence
{
/// <summary>
/// Represents a cache for the snapshot or database of the NEO blockchain.
/// </summary>
public class SnapshotCache : DataCache, IDisposable
public class SnapshotCache : SnapshotCacheReadOnly, IDisposable
{
private readonly IReadOnlyStore _store;
private readonly ISnapshot? _snapshot;
private readonly ISnapshot _snapshot;

/// <summary>
/// Initializes a new instance of the <see cref="SnapshotCache"/> class.
/// </summary>
/// <param name="store">An <see cref="IReadOnlyStore"/> to create a readonly cache; or an <see cref="ISnapshot"/> to create a snapshot cache.</param>
public SnapshotCache(IReadOnlyStore store)
/// <param name="snapshot">An <see cref="ISnapshot"/> to create a write cache.</param>
public SnapshotCache(ISnapshot snapshot) : base(snapshot)
{
_store = store;
_snapshot = store as ISnapshot;
_snapshot = snapshot;
}

#region Write

protected override void UpdateInternal(StorageKey key, StorageItem value)
{
_snapshot.Put(key.ToArray(), value.ToArray());
}

protected override void AddInternal(StorageKey key, StorageItem value)
{
_snapshot?.Put(key.ToArray(), value.ToArray());
_snapshot.Put(key.ToArray(), value.ToArray());
}

protected override void DeleteInternal(StorageKey key)
{
_snapshot?.Delete(key.ToArray());
_snapshot.Delete(key.ToArray());
}

public override void Commit()
{
base.Commit();
_snapshot?.Commit();
_snapshot.Commit();
}

protected override bool ContainsInternal(StorageKey key)
{
return _store.Contains(key.ToArray());
}
#endregion

public void Dispose()
{
_snapshot?.Dispose();
}

/// <inheritdoc/>
protected override StorageItem GetInternal(StorageKey key)
{
if (_store.TryGet(key.ToArray(), out var value))
return new(value);
throw new KeyNotFoundException();
}

protected override IEnumerable<(StorageKey, StorageItem)> SeekInternal(byte[] keyOrPrefix, SeekDirection direction)
{
return _store.Seek(keyOrPrefix, direction).Select(p => (new StorageKey(p.Key), new StorageItem(p.Value)));
}

/// <inheritdoc/>
protected override StorageItem? TryGetInternal(StorageKey key)
{
return _store.TryGet(key.ToArray(), out var value) ? new(value) : null;
}

protected override void UpdateInternal(StorageKey key, StorageItem value)
{
_snapshot?.Put(key.ToArray(), value.ToArray());
_snapshot.Dispose();
}
}
}
72 changes: 72 additions & 0 deletions src/Neo/Persistence/SnapshotCacheReadOnly.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright (C) 2015-2025 The Neo Project.
//
// SnapshotCacheReadOnly.cs file belongs to the neo project and is free
// software distributed under the MIT software license, see the
// accompanying file LICENSE in the main directory of the
// repository or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

#nullable enable

using Neo.SmartContract;
using System.Collections.Generic;
using System.Linq;

namespace Neo.Persistence
{
/// <summary>
/// Represents a cache for the snapshot or database of the NEO blockchain.
/// </summary>
public class SnapshotCacheReadOnly : DataCache
{
private readonly IReadOnlyStore _store;

/// <summary>
/// Initializes a new instance of the <see cref="SnapshotCacheReadOnly"/> class.
/// </summary>
/// <param name="store">An <see cref="IReadOnlyStore"/> to create a readonly cache.</param>
public SnapshotCacheReadOnly(IReadOnlyStore store)
{
_store = store;
}

#region Write

protected override void UpdateInternal(StorageKey key, StorageItem value) { }
protected override void AddInternal(StorageKey key, StorageItem value) { }
protected override void DeleteInternal(StorageKey key) { }

#endregion

#region Read

protected override bool ContainsInternal(StorageKey key)
{
return _store.Contains(key.ToArray());
}

/// <inheritdoc/>
protected override StorageItem GetInternal(StorageKey key)
{
if (_store.TryGet(key.ToArray(), out var value))
return new(value);
throw new KeyNotFoundException();
}

protected override IEnumerable<(StorageKey, StorageItem)> SeekInternal(byte[] keyOrPrefix, SeekDirection direction)
{
return _store.Seek(keyOrPrefix, direction).Select(p => (new StorageKey(p.Key), new StorageItem(p.Value)));
}

/// <inheritdoc/>
protected override StorageItem? TryGetInternal(StorageKey key)
{
return _store.TryGet(key.ToArray(), out var value) ? new(value) : null;
}

#endregion
}
}
2 changes: 1 addition & 1 deletion tests/Neo.UnitTests/Persistence/UT_CloneCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace Neo.UnitTests.IO.Caching
public class UT_CloneCache
{
private readonly MemoryStore store = new();
private SnapshotCache myDataCache;
private SnapshotCacheReadOnly myDataCache;
private ClonedCache clonedCache;

private static readonly StorageKey key1 = new() { Id = 0, Key = Encoding.UTF8.GetBytes("key1") };
Expand Down
6 changes: 3 additions & 3 deletions tests/Neo.UnitTests/Persistence/UT_DataCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace Neo.UnitTests.IO.Caching
public class UT_DataCache
{
private readonly MemoryStore store = new();
private SnapshotCache myDataCache;
private SnapshotCacheReadOnly 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") };
Expand Down Expand Up @@ -245,7 +245,7 @@ public void TestFindRange()
store.Put(key3.ToArray(), value3.ToArray());
store.Put(key4.ToArray(), value4.ToArray());

var myDataCache = new SnapshotCache(store);
var myDataCache = new SnapshotCacheReadOnly(store);
myDataCache.Add(key1, value1);
myDataCache.Add(key2, value2);

Expand Down Expand Up @@ -381,7 +381,7 @@ public void TestTryGet()
public void TestFindInvalid()
{
using var store = new MemoryStore();
using var myDataCache = new SnapshotCache(store);
var myDataCache = new SnapshotCacheReadOnly(store);
myDataCache.Add(key1, value1);

store.Put(key2.ToArray(), value2.ToArray());
Expand Down