diff --git a/src/LevelDBStore/IO/Data/LevelDB/Helper.cs b/src/LevelDBStore/IO/Data/LevelDB/Helper.cs index a2c28e769..0ed2f9543 100644 --- a/src/LevelDBStore/IO/Data/LevelDB/Helper.cs +++ b/src/LevelDBStore/IO/Data/LevelDB/Helper.cs @@ -7,11 +7,13 @@ namespace Neo.IO.Data.LevelDB { public static class Helper { - public static IEnumerable Seek(this DB db, ReadOptions options, byte[] keyOrPrefix, SeekDirection direction, Func resultSelector) + public static IEnumerable Seek(this DB db, ReadOptions options, byte table, byte[] prefix, SeekDirection direction, Func resultSelector) { using Iterator it = db.NewIterator(options); - for (it.Seek(keyOrPrefix); it.Valid();) + for (it.Seek(CreateKey(table, prefix)); it.Valid();) { + var key = it.Key(); + if (key.Length < 1 || key[0] != table) break; yield return resultSelector(it.Key(), it.Value()); if (direction == SeekDirection.Forward) @@ -39,5 +41,14 @@ internal static byte[] ToByteArray(this IntPtr data, UIntPtr length) Marshal.Copy(data, buffer, 0, (int)length); return buffer; } + + public static byte[] CreateKey(byte table, byte[] key = null) + { + if (key is null || key.Length == 0) return new[] { table }; + byte[] buffer = new byte[1 + key.Length]; + buffer[0] = table; + Buffer.BlockCopy(key, 0, buffer, 1, key.Length); + return buffer; + } } } diff --git a/src/LevelDBStore/Plugins/Storage/Helper.cs b/src/LevelDBStore/Plugins/Storage/Helper.cs deleted file mode 100644 index ff54faebe..000000000 --- a/src/LevelDBStore/Plugins/Storage/Helper.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; - -namespace Neo.Plugins.Storage -{ - internal static class Helper - { - public static byte[] CreateKey(byte table, byte[] key = null) - { - if (key is null) return new[] { table }; - byte[] buffer = new byte[1 + key.Length]; - buffer[0] = table; - Buffer.BlockCopy(key, 0, buffer, 1, key.Length); - return buffer; - } - } -} diff --git a/src/LevelDBStore/Plugins/Storage/Snapshot.cs b/src/LevelDBStore/Plugins/Storage/Snapshot.cs index ae15be6f8..46d70d6fb 100644 --- a/src/LevelDBStore/Plugins/Storage/Snapshot.cs +++ b/src/LevelDBStore/Plugins/Storage/Snapshot.cs @@ -3,6 +3,7 @@ using Neo.Persistence; using System.Collections.Generic; using LSnapshot = Neo.IO.Data.LevelDB.Snapshot; +using LHelper = Neo.IO.Data.LevelDB.Helper; namespace Neo.Plugins.Storage { @@ -28,7 +29,7 @@ public void Commit() public void Delete(byte table, byte[] key) { - batch.Delete(Helper.CreateKey(table, key)); + batch.Delete(LHelper.CreateKey(table, key)); } public void Dispose() @@ -36,19 +37,19 @@ public void Dispose() snapshot.Dispose(); } - public IEnumerable<(byte[] Key, byte[] Value)> Seek(byte table, byte[] keyOrPrefix, SeekDirection direction = SeekDirection.Forward) + public IEnumerable<(byte[] Key, byte[] Value)> Seek(byte table, byte[] prefix, SeekDirection direction = SeekDirection.Forward) { - return db.Seek(options, Helper.CreateKey(table, keyOrPrefix), direction, (k, v) => (k[1..], v)); + return db.Seek(options, table, prefix, direction, (k, v) => (k[1..], v)); } public void Put(byte table, byte[] key, byte[] value) { - batch.Put(Helper.CreateKey(table, key), value); + batch.Put(LHelper.CreateKey(table, key), value); } public byte[] TryGet(byte table, byte[] key) { - return db.Get(options, Helper.CreateKey(table, key)); + return db.Get(options, LHelper.CreateKey(table, key)); } } } diff --git a/src/LevelDBStore/Plugins/Storage/Store.cs b/src/LevelDBStore/Plugins/Storage/Store.cs index e1e7b2b93..5a6503e3d 100644 --- a/src/LevelDBStore/Plugins/Storage/Store.cs +++ b/src/LevelDBStore/Plugins/Storage/Store.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Reflection; using System.Text; +using LHelper = Neo.IO.Data.LevelDB.Helper; namespace Neo.Plugins.Storage { @@ -16,7 +17,7 @@ internal class Store : IStore public Store(string path) { this.db = DB.Open(path, new Options { CreateIfMissing = true }); - byte[] value = db.Get(ReadOptions.Default, Helper.CreateKey(SYS_Version)); + byte[] value = db.Get(ReadOptions.Default, LHelper.CreateKey(SYS_Version)); if (value != null && Version.TryParse(Encoding.ASCII.GetString(value), out Version version) && version >= Version.Parse("3.0.0")) return; @@ -36,13 +37,13 @@ public Store(string path) } } - db.Put(WriteOptions.Default, Helper.CreateKey(SYS_Version), Encoding.ASCII.GetBytes(Assembly.GetExecutingAssembly().GetName().Version.ToString())); + db.Put(WriteOptions.Default, LHelper.CreateKey(SYS_Version), Encoding.ASCII.GetBytes(Assembly.GetExecutingAssembly().GetName().Version.ToString())); db.Write(WriteOptions.Default, batch); } public void Delete(byte table, byte[] key) { - db.Delete(WriteOptions.Default, Helper.CreateKey(table, key)); + db.Delete(WriteOptions.Default, LHelper.CreateKey(table, key)); } public void Dispose() @@ -52,7 +53,7 @@ public void Dispose() public IEnumerable<(byte[], byte[])> Seek(byte table, byte[] prefix, SeekDirection direction = SeekDirection.Forward) { - return db.Seek(ReadOptions.Default, Helper.CreateKey(table, prefix), direction, (k, v) => (k[1..], v)); + return db.Seek(ReadOptions.Default, table, prefix, direction, (k, v) => (k[1..], v)); } public ISnapshot GetSnapshot() @@ -62,17 +63,17 @@ public ISnapshot GetSnapshot() public void Put(byte table, byte[] key, byte[] value) { - db.Put(WriteOptions.Default, Helper.CreateKey(table, key), value); + db.Put(WriteOptions.Default, LHelper.CreateKey(table, key), value); } public void PutSync(byte table, byte[] key, byte[] value) { - db.Put(WriteOptions.SyncWrite, Helper.CreateKey(table, key), value); + db.Put(WriteOptions.SyncWrite, LHelper.CreateKey(table, key), value); } public byte[] TryGet(byte table, byte[] key) { - return db.Get(ReadOptions.Default, Helper.CreateKey(table, key)); + return db.Get(ReadOptions.Default, LHelper.CreateKey(table, key)); } } } diff --git a/src/RocksDBStore/Plugins/Storage/Snapshot.cs b/src/RocksDBStore/Plugins/Storage/Snapshot.cs index c61bf460e..fba384598 100644 --- a/src/RocksDBStore/Plugins/Storage/Snapshot.cs +++ b/src/RocksDBStore/Plugins/Storage/Snapshot.cs @@ -1,7 +1,6 @@ using Neo.IO.Caching; using Neo.Persistence; using RocksDbSharp; -using System; using System.Collections.Generic; namespace Neo.Plugins.Storage diff --git a/src/RocksDBStore/Plugins/Storage/Store.cs b/src/RocksDBStore/Plugins/Storage/Store.cs index f0959a596..3cad88249 100644 --- a/src/RocksDBStore/Plugins/Storage/Store.cs +++ b/src/RocksDBStore/Plugins/Storage/Store.cs @@ -82,16 +82,17 @@ public ISnapshot GetSnapshot() return new Snapshot(this, db); } - public IEnumerable<(byte[] Key, byte[] Value)> Seek(byte table, byte[] prefix, SeekDirection direction) + public IEnumerable<(byte[] Key, byte[] Value)> Seek(byte table, byte[] prefix, SeekDirection direction = SeekDirection.Forward) { using var it = db.NewIterator(GetFamily(table), Options.ReadDefault); - for (it.Seek(prefix); it.Valid(); it.Next()) + for (it.Seek(prefix); it.Valid();) { - var key = it.Key(); - byte[] y = prefix; - if (key.Length < y.Length) break; - if (!key.AsSpan().StartsWith(y)) break; - yield return (key, it.Value()); + yield return (it.Key(), it.Value()); + + if (direction == SeekDirection.Forward) + it.Next(); + else + it.Prev(); } } diff --git a/src/RpcNep5Tracker/DbCache.cs b/src/RpcNep5Tracker/DbCache.cs index bd2ff3cba..9cfd27e35 100644 --- a/src/RpcNep5Tracker/DbCache.cs +++ b/src/RpcNep5Tracker/DbCache.cs @@ -49,7 +49,7 @@ protected override void DeleteInternal(TKey key) protected override IEnumerable<(TKey, TValue)> SeekInternal(byte[] key_prefix, SeekDirection direction) { - return db.Seek(options, CreateKey(prefix, key_prefix), direction, (k, v) => (k.AsSerializable(1), v.AsSerializable())); + return db.Seek(options, prefix, key_prefix, direction, (k, v) => (k.AsSerializable(1), v.AsSerializable())); } protected override TValue GetInternal(TKey key)