diff --git a/src/RocksDb.Extensions/IRocksDbAccessor.cs b/src/RocksDb.Extensions/IRocksDbAccessor.cs index a1c5cb4..c3ddc88 100644 --- a/src/RocksDb.Extensions/IRocksDbAccessor.cs +++ b/src/RocksDb.Extensions/IRocksDbAccessor.cs @@ -21,6 +21,7 @@ public interface IRocksDbAccessor IEnumerable GetAll(); bool HasKey(TKey key); void Clear(); + int Count(); } #pragma warning restore CS1591 \ No newline at end of file diff --git a/src/RocksDb.Extensions/IRocksDbStore.cs b/src/RocksDb.Extensions/IRocksDbStore.cs index aa9ca79..cc8df45 100644 --- a/src/RocksDb.Extensions/IRocksDbStore.cs +++ b/src/RocksDb.Extensions/IRocksDbStore.cs @@ -81,4 +81,17 @@ public abstract class RocksDbStore /// can impact performance during execution. Use with caution in high-frequency workflows. /// public void Clear() => _rocksDbAccessor.Clear(); + + /// + /// Gets the number of key-value pairs currently stored. + /// + /// + /// This method is not a constant-time operation. Internally, it iterates over all entries in the store + /// to compute the count. While the keys and values are not deserialized during iteration, this process may still + /// be expensive for large datasets. + /// + /// Use this method with caution in performance-critical paths, especially if the store contains a high number of entries. + /// + /// The total count of items in the store. + public int Count() => _rocksDbAccessor.Count(); } diff --git a/src/RocksDb.Extensions/RocksDbAccessor.cs b/src/RocksDb.Extensions/RocksDbAccessor.cs index 52c27ad..02c4199 100644 --- a/src/RocksDb.Extensions/RocksDbAccessor.cs +++ b/src/RocksDb.Extensions/RocksDbAccessor.cs @@ -309,6 +309,20 @@ public IEnumerable GetAll() _ = iterator.Next(); } } + + public int Count() + { + using var iterator = _rocksDbContext.Db.NewIterator(_columnFamily.Handle); + _ = iterator.SeekToFirst(); + var count = 0; + while (iterator.Valid()) + { + count++; + _ = iterator.Next(); + } + + return count; + } public bool HasKey(TKey key) { diff --git a/test/RocksDb.Extensions.Tests/ClearStoreTests.cs b/test/RocksDb.Extensions.Tests/ClearStoreTests.cs index 1fe594f..1cf0b4d 100644 --- a/test/RocksDb.Extensions.Tests/ClearStoreTests.cs +++ b/test/RocksDb.Extensions.Tests/ClearStoreTests.cs @@ -7,7 +7,7 @@ namespace RocksDb.Extensions.Tests; public class ClearStoreTests { [Test] - public void should_reset_store_range_data_to_store() + public void should_clear_and_repopulate_store_data() { // Setup RocksDbStore using var testFixture = CreateTestFixture(); @@ -27,6 +27,7 @@ public void should_reset_store_range_data_to_store() store.TryGet(key, out var value).ShouldBeTrue(); value.ShouldBe(expectedValue); } + Assert.That(store.Count(), Is.EqualTo(100)); // Clear the store store.Clear(); @@ -37,6 +38,7 @@ public void should_reset_store_range_data_to_store() store.HasKey(key).ShouldBeFalse(); store.TryGet(key, out _).ShouldBeFalse(); } + Assert.That(store.Count(), Is.EqualTo(0)); // Try to put the data again store.PutRange(cacheKeys); @@ -48,6 +50,7 @@ public void should_reset_store_range_data_to_store() store.TryGet(key, out var value).ShouldBeTrue(); value.ShouldBe(expectedValue); } + Assert.That(store.Count(), Is.EqualTo(100)); } private static TestFixture CreateTestFixture()