diff --git a/src/RocksDb.Extensions/IRocksDbAccessor.cs b/src/RocksDb.Extensions/IRocksDbAccessor.cs index 62617ae..f1e81f5 100644 --- a/src/RocksDb.Extensions/IRocksDbAccessor.cs +++ b/src/RocksDb.Extensions/IRocksDbAccessor.cs @@ -17,6 +17,7 @@ public interface IRocksDbAccessor bool TryGet(TKey key, [MaybeNullWhen(false)] out TValue value); void PutRange(ReadOnlySpan keys, ReadOnlySpan values); void PutRange(ReadOnlySpan values, Func keySelector); + void PutRange(IReadOnlyList<(TKey key, TValue value)> items); IEnumerable GetAll(); bool HasKey(TKey key); } diff --git a/src/RocksDb.Extensions/IRocksDbStore.cs b/src/RocksDb.Extensions/IRocksDbStore.cs index 7c0637e..92998c0 100644 --- a/src/RocksDb.Extensions/IRocksDbStore.cs +++ b/src/RocksDb.Extensions/IRocksDbStore.cs @@ -51,6 +51,12 @@ public abstract class RocksDbStore /// The values to put in the store. /// The function to use to generate keys for the values. public void PutRange(ReadOnlySpan values, Func keySelector) => _rocksDbAccessor.PutRange(values, keySelector); + + /// + /// Adds or updates a collection of key-value pairs in the store. + /// + /// The collection of key-value pairs to add or update. + public void PutRange(IReadOnlyList<(TKey key, TValue value)> items) => _rocksDbAccessor.PutRange(items); /// /// Gets all the values in the store. diff --git a/src/RocksDb.Extensions/RocksDbAccessor.cs b/src/RocksDb.Extensions/RocksDbAccessor.cs index 796a11e..867926d 100644 --- a/src/RocksDb.Extensions/RocksDbAccessor.cs +++ b/src/RocksDb.Extensions/RocksDbAccessor.cs @@ -218,6 +218,18 @@ public void PutRange(ReadOnlySpan values, Func keySelector _rocksDb.Write(batch); } + public void PutRange(IReadOnlyList<(TKey key, TValue value)> items) + { + using var batch = new WriteBatch(); + for (var index = 0; index < items.Count; index++) + { + var (key, value) = items[index]; + AddToBatch(key, value, batch); + } + + _rocksDb.Write(batch); + } + private void AddToBatch(TKey key, TValue value, WriteBatch batch) { byte[]? rentedKeyBuffer = null; diff --git a/test/RocksDb.Extensions.Tests/PutRangeTests.cs b/test/RocksDb.Extensions.Tests/PutRangeTests.cs new file mode 100644 index 0000000..75c7e97 --- /dev/null +++ b/test/RocksDb.Extensions.Tests/PutRangeTests.cs @@ -0,0 +1,40 @@ +using NUnit.Framework; +using RocksDb.Extensions.Tests.Utils; +using Shouldly; + +namespace RocksDb.Extensions.Tests; + +public class PutRangeTests +{ + [Test] + public void should_put_range_data_to_store() + { + // Arrange + using var testFixture = CreateTestFixture(); + + var store = testFixture.GetStore>(); + var cacheKeys = Enumerable.Range(0, 100) + .Select(x => (key: x, value: x.ToString())) + .ToList(); + + // Act + store.PutRange(cacheKeys); + + // Assert + foreach (var (key, expectedValue) in cacheKeys) + { + store.HasKey(key).ShouldBeTrue(); + store.TryGet(key, out var value).ShouldBeTrue(); + value.ShouldBe(expectedValue); + } + } + + private static TestFixture CreateTestFixture() + { + var testFixture = TestFixture.Create(rockDb => + { + _ = rockDb.AddStore>("my-store"); + }); + return testFixture; + } +} \ No newline at end of file