diff --git a/src/Neo/Persistence/IReadOnlyStore.cs b/src/Neo/Persistence/IReadOnlyStore.cs index 015a35a0a3..79ff9099be 100644 --- a/src/Neo/Persistence/IReadOnlyStore.cs +++ b/src/Neo/Persistence/IReadOnlyStore.cs @@ -9,8 +9,11 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. +#nullable enable + using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace Neo.Persistence { @@ -25,7 +28,7 @@ public interface IReadOnlyStore /// The key(i.e. start key) or prefix to be sought. /// The direction of seek. /// An enumerator containing all the entries after (Forward) or before(Backward) seeking. - IEnumerable<(byte[] Key, byte[] Value)> Seek(byte[] keyOrPrefix, SeekDirection direction); + IEnumerable<(byte[] Key, byte[] Value)> Seek(byte[]? keyOrPrefix, SeekDirection direction); /// /// Reads a specified entry from the database. @@ -33,7 +36,7 @@ public interface IReadOnlyStore /// The key of the entry. /// The data of the entry. Or if it doesn't exist. [Obsolete("use TryGet(byte[] key, [NotNullWhen(true)] out byte[]? value) instead.")] - byte[] TryGet(byte[] key); + byte[]? TryGet(byte[] key); /// /// Reads a specified entry from the database. @@ -41,7 +44,7 @@ public interface IReadOnlyStore /// The key of the entry. /// The data of the entry. /// if the entry exists; otherwise, . - bool TryGet(byte[] key, out byte[] value); + bool TryGet(byte[] key, [NotNullWhen(true)] out byte[]? value); /// /// Determines whether the database contains the specified entry. diff --git a/src/Neo/Persistence/MemoryStore.cs b/src/Neo/Persistence/MemoryStore.cs index 7a2a028d5d..05a08e30d9 100644 --- a/src/Neo/Persistence/MemoryStore.cs +++ b/src/Neo/Persistence/MemoryStore.cs @@ -33,9 +33,7 @@ public void Delete(byte[] key) _innerData.TryRemove(key, out _); } - public void Dispose() - { - } + public void Dispose() { } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ISnapshot GetSnapshot() @@ -50,13 +48,14 @@ public void Put(byte[] key, byte[] value) } /// - public IEnumerable<(byte[] Key, byte[] Value)> Seek(byte[] keyOrPrefix, SeekDirection direction = SeekDirection.Forward) + public IEnumerable<(byte[] Key, byte[] Value)> Seek(byte[]? keyOrPrefix, SeekDirection direction = SeekDirection.Forward) { - if (direction == SeekDirection.Backward && keyOrPrefix?.Length == 0) yield break; + keyOrPrefix ??= []; + if (direction == SeekDirection.Backward && keyOrPrefix.Length == 0) yield break; var comparer = direction == SeekDirection.Forward ? ByteArrayComparer.Default : ByteArrayComparer.Reverse; IEnumerable> records = _innerData; - if (keyOrPrefix?.Length > 0) + if (keyOrPrefix.Length > 0) records = records.Where(p => comparer.Compare(p.Key, keyOrPrefix) >= 0); records = records.OrderBy(p => p.Key, comparer); foreach (var pair in records) diff --git a/src/Plugins/LevelDBStore/IO/Data/LevelDB/DB.cs b/src/Plugins/LevelDBStore/IO/Data/LevelDB/DB.cs index 56dfa86431..c1d7a400fb 100644 --- a/src/Plugins/LevelDBStore/IO/Data/LevelDB/DB.cs +++ b/src/Plugins/LevelDBStore/IO/Data/LevelDB/DB.cs @@ -9,8 +9,6 @@ // Redistribution and use in source and binary forms with or without // modifications are permitted. -#nullable enable - using System.Collections; using System.Collections.Generic; using System.IO; @@ -49,7 +47,7 @@ public void Delete(WriteOptions options, byte[] key) /// If the database contains an entry for "key" return the value, /// otherwise return null. /// - public byte[] Get(ReadOptions options, byte[] key) + public byte[]? Get(ReadOptions options, byte[] key) { var value = Native.leveldb_get(Handle, options.Handle, key, (nuint)key.Length, out var length, out var error); try @@ -131,7 +129,7 @@ public IEnumerator> GetEnumerator() { using var iterator = CreateIterator(ReadOptions.Default); for (iterator.SeekToFirst(); iterator.Valid(); iterator.Next()) - yield return new KeyValuePair(iterator.Key(), iterator.Value()); + yield return new KeyValuePair(iterator.Key()!, iterator.Value()!); } IEnumerator IEnumerable.GetEnumerator() => diff --git a/src/Plugins/LevelDBStore/IO/Data/LevelDB/Helper.cs b/src/Plugins/LevelDBStore/IO/Data/LevelDB/Helper.cs index de3e744750..26b4e8b433 100644 --- a/src/Plugins/LevelDBStore/IO/Data/LevelDB/Helper.cs +++ b/src/Plugins/LevelDBStore/IO/Data/LevelDB/Helper.cs @@ -18,15 +18,15 @@ namespace Neo.IO.Storage.LevelDB { public static class Helper { - public static IEnumerable<(byte[], byte[])> Seek(this DB db, ReadOptions options, byte[] keyOrPrefix, SeekDirection direction) + public static IEnumerable<(byte[], byte[])> Seek(this DB db, ReadOptions options, byte[]? keyOrPrefix, SeekDirection direction) { - if (keyOrPrefix == null) keyOrPrefix = []; + keyOrPrefix ??= []; - using Iterator it = db.CreateIterator(options); + using var it = db.CreateIterator(options); if (direction == SeekDirection.Forward) { for (it.Seek(keyOrPrefix); it.Valid(); it.Next()) - yield return new(it.Key(), it.Value()); + yield return new(it.Key()!, it.Value()!); } else { @@ -38,14 +38,14 @@ public static class Helper it.Prev(); for (; it.Valid(); it.Prev()) - yield return new(it.Key(), it.Value()); + yield return new(it.Key()!, it.Value()!); } } - internal static byte[] ToByteArray(this IntPtr data, UIntPtr length) + internal static byte[]? ToByteArray(this IntPtr data, UIntPtr length) { if (data == IntPtr.Zero) return null; - byte[] buffer = new byte[(int)length]; + var buffer = new byte[(int)length]; Marshal.Copy(data, buffer, 0, (int)length); return buffer; } diff --git a/src/Plugins/LevelDBStore/IO/Data/LevelDB/Iterator.cs b/src/Plugins/LevelDBStore/IO/Data/LevelDB/Iterator.cs index 0d4ccaa571..1456669aa0 100644 --- a/src/Plugins/LevelDBStore/IO/Data/LevelDB/Iterator.cs +++ b/src/Plugins/LevelDBStore/IO/Data/LevelDB/Iterator.cs @@ -36,7 +36,7 @@ protected override void FreeUnManagedObjects() /// Return the key for the current entry. /// REQUIRES: Valid() /// - public byte[] Key() + public byte[]? Key() { var key = Native.leveldb_iter_key(Handle, out var length); CheckError(); @@ -89,7 +89,7 @@ public bool Valid() return Native.leveldb_iter_valid(Handle); } - public byte[] Value() + public byte[]? Value() { var value = Native.leveldb_iter_value(Handle, out var length); CheckError(); diff --git a/src/Plugins/LevelDBStore/IO/Data/LevelDB/Native.cs b/src/Plugins/LevelDBStore/IO/Data/LevelDB/Native.cs index f489e50a60..63668975bf 100644 --- a/src/Plugins/LevelDBStore/IO/Data/LevelDB/Native.cs +++ b/src/Plugins/LevelDBStore/IO/Data/LevelDB/Native.cs @@ -24,14 +24,17 @@ public enum CompressionType : byte public static class Native { #region Logger + [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern nint leveldb_logger_create(nint /* Action */ logger); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern void leveldb_logger_destroy(nint /* logger*/ option); + #endregion #region DB + [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern nint leveldb_open(nint /* Options*/ options, string name, out nint error); @@ -77,19 +80,20 @@ public static class Native public static extern void leveldb_free(nint /* void */ ptr); #endregion - - #endregion #region Env + [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern nint leveldb_create_default_env(); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern void leveldb_env_destroy(nint /*Env*/ cache); + #endregion #region Iterator + [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern void leveldb_iter_destroy(nint /*Iterator*/ iterator); @@ -120,9 +124,11 @@ public static class Native [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern void leveldb_iter_get_error(nint /*Iterator*/ iterator, out nint error); + #endregion #region Options + [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern nint leveldb_options_create(); @@ -170,9 +176,11 @@ public static class Native [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern nint leveldb_filterpolicy_create_bloom(int bits_per_key); + #endregion #region ReadOptions + [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern nint leveldb_readoptions_create(); @@ -187,9 +195,11 @@ public static class Native [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern void leveldb_readoptions_set_snapshot(nint /*ReadOptions*/ options, nint /*SnapShot*/ snapshot); + #endregion #region WriteBatch + [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern nint leveldb_writebatch_create(); @@ -207,9 +217,11 @@ public static class Native [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern void leveldb_writebatch_iterate(nint /* WriteBatch */ batch, object state, Action put, Action deleted); + #endregion #region WriteOptions + [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern nint leveldb_writeoptions_create(); @@ -218,14 +230,17 @@ public static class Native [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern void leveldb_writeoptions_set_sync(nint /*WriteOptions*/ options, [MarshalAs(UnmanagedType.U1)] bool o); + #endregion #region Cache + [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern nint leveldb_cache_create_lru(int capacity); [DllImport("libleveldb", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] public static extern void leveldb_cache_destroy(nint /*Cache*/ cache); + #endregion #region Comparator @@ -255,9 +270,9 @@ public static void CheckError(nint error) { if (error != nint.Zero) { - string message = Marshal.PtrToStringAnsi(error); + var message = Marshal.PtrToStringAnsi(error); Native.leveldb_free(error); - throw new LevelDBException(message); + throw new LevelDBException(message ?? string.Empty); } } } diff --git a/src/Plugins/LevelDBStore/LevelDBStore.csproj b/src/Plugins/LevelDBStore/LevelDBStore.csproj index 09e4abb7bd..8f84bed91f 100644 --- a/src/Plugins/LevelDBStore/LevelDBStore.csproj +++ b/src/Plugins/LevelDBStore/LevelDBStore.csproj @@ -5,6 +5,7 @@ Neo.Plugins.Storage.LevelDBStore Neo.Plugins.Storage true + enable ../../../bin/$(PackageId) diff --git a/src/Plugins/LevelDBStore/Plugins/Storage/Snapshot.cs b/src/Plugins/LevelDBStore/Plugins/Storage/Snapshot.cs index cfe9d0ca8b..2742a0f612 100644 --- a/src/Plugins/LevelDBStore/Plugins/Storage/Snapshot.cs +++ b/src/Plugins/LevelDBStore/Plugins/Storage/Snapshot.cs @@ -13,6 +13,7 @@ using Neo.Persistence; using System.Collections; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using LSnapshot = Neo.IO.Storage.LevelDB.Snapshot; namespace Neo.Plugins.Storage @@ -70,7 +71,7 @@ public void Dispose() } /// - public IEnumerable<(byte[] Key, byte[] Value)> Seek(byte[] keyOrPrefix, SeekDirection direction = SeekDirection.Forward) + public IEnumerable<(byte[] Key, byte[] Value)> Seek(byte[]? keyOrPrefix, SeekDirection direction = SeekDirection.Forward) { return _db.Seek(_readOptions, keyOrPrefix, direction); } @@ -80,12 +81,12 @@ public bool Contains(byte[] key) return _db.Contains(_readOptions, key); } - public byte[] TryGet(byte[] key) + public byte[]? TryGet(byte[] key) { return _db.Get(_readOptions, key); } - public bool TryGet(byte[] key, out byte[] value) + public bool TryGet(byte[] key, [NotNullWhen(true)] out byte[]? value) { value = _db.Get(_readOptions, key); return value != null; @@ -95,7 +96,7 @@ public IEnumerator> GetEnumerator() { using var iterator = _db.CreateIterator(_readOptions); for (iterator.SeekToFirst(); iterator.Valid(); iterator.Next()) - yield return new KeyValuePair(iterator.Key(), iterator.Value()); + yield return new KeyValuePair(iterator.Key()!, iterator.Value()!); } IEnumerator IEnumerable.GetEnumerator() => diff --git a/src/Plugins/LevelDBStore/Plugins/Storage/Store.cs b/src/Plugins/LevelDBStore/Plugins/Storage/Store.cs index c06f2ae07f..db32a92a43 100644 --- a/src/Plugins/LevelDBStore/Plugins/Storage/Store.cs +++ b/src/Plugins/LevelDBStore/Plugins/Storage/Store.cs @@ -13,6 +13,7 @@ using Neo.Persistence; using System.Collections; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace Neo.Plugins.Storage { @@ -58,17 +59,17 @@ public void PutSync(byte[] key, byte[] value) => public bool Contains(byte[] key) => _db.Contains(ReadOptions.Default, key); - public byte[] TryGet(byte[] key) => + public byte[]? TryGet(byte[] key) => _db.Get(ReadOptions.Default, key); - public bool TryGet(byte[] key, out byte[] value) + public bool TryGet(byte[] key, [NotNullWhen(true)] out byte[]? value) { value = _db.Get(ReadOptions.Default, key); return value != null; } /// - public IEnumerable<(byte[], byte[])> Seek(byte[] keyOrPrefix, SeekDirection direction = SeekDirection.Forward) => + public IEnumerable<(byte[], byte[])> Seek(byte[]? keyOrPrefix, SeekDirection direction = SeekDirection.Forward) => _db.Seek(ReadOptions.Default, keyOrPrefix, direction); public IEnumerator> GetEnumerator() =>