From 009c7d0164c92a67ba1f6726fda95041a95e5c8a Mon Sep 17 00:00:00 2001 From: Michael Landis Date: Thu, 1 Sep 2022 14:06:25 -0700 Subject: [PATCH] feat: implement `ListLength` Implements, tests, and documents `ListLengthAsync`. A list not in the cache is interpreted to have length 0. Closes #133 --- .../Incubating/Internal/ScsDataClient.cs | 19 +++++++++++++ .../Responses/CacheListLengthResponse.cs | 16 +++++++++++ .../Incubating/SimpleCacheClient.cs | 17 +++++++++++ .../Momento.Sdk.Incubating.Tests/ListTest.cs | 28 +++++++++++++++++++ 4 files changed, 80 insertions(+) create mode 100644 src/Momento.Sdk/Incubating/Responses/CacheListLengthResponse.cs diff --git a/src/Momento.Sdk/Incubating/Internal/ScsDataClient.cs b/src/Momento.Sdk/Incubating/Internal/ScsDataClient.cs index 175c831b..834ae8b9 100644 --- a/src/Momento.Sdk/Incubating/Internal/ScsDataClient.cs +++ b/src/Momento.Sdk/Incubating/Internal/ScsDataClient.cs @@ -473,4 +473,23 @@ public async Task ListRemoveAllAsync(string cacheNam } return new CacheListRemoveAllResponse(); } + + public async Task ListLengthAsync(string cacheName, string listName) + { + _ListLengthRequest request = new() + { + ListName = listName.ToByteString(), + }; + _ListLengthResponse response; + + try + { + response = await this.grpcManager.Client.ListLengthAsync(request, MetadataWithCache(cacheName), deadline: CalculateDeadline()); + } + catch (Exception e) + { + throw CacheExceptionMapper.Convert(e); + } + return new CacheListLengthResponse(response); + } } diff --git a/src/Momento.Sdk/Incubating/Responses/CacheListLengthResponse.cs b/src/Momento.Sdk/Incubating/Responses/CacheListLengthResponse.cs new file mode 100644 index 00000000..6489ad1e --- /dev/null +++ b/src/Momento.Sdk/Incubating/Responses/CacheListLengthResponse.cs @@ -0,0 +1,16 @@ +using Momento.Protos.CacheClient; + +namespace Momento.Sdk.Incubating.Responses; + +public class CacheListLengthResponse +{ + public int Length { get; private set; } = 0; + + public CacheListLengthResponse(_ListLengthResponse response) + { + if (response.ListCase == _ListLengthResponse.ListOneofCase.Found) + { + Length = checked((int)response.Found.Length); + } + } +} diff --git a/src/Momento.Sdk/Incubating/SimpleCacheClient.cs b/src/Momento.Sdk/Incubating/SimpleCacheClient.cs index 927880f6..fba5156a 100644 --- a/src/Momento.Sdk/Incubating/SimpleCacheClient.cs +++ b/src/Momento.Sdk/Incubating/SimpleCacheClient.cs @@ -658,6 +658,23 @@ public async Task ListRemoveAllAsync(string cacheNam return await this.dataClient.ListRemoveAllAsync(cacheName, listName, value); } + /// + /// Calculate the length of a list in the cache. + /// + /// A list that does not exist is interpreted to have length 0. + /// + /// Name of the cache to perform the lookup in. + /// The list to calculate length. + /// Task representing the length of the list. + /// Any of or is . + public async Task ListLengthAsync(string cacheName, string listName) + { + Utils.ArgumentNotNull(cacheName, nameof(cacheName)); + Utils.ArgumentNotNull(listName, nameof(listName)); + + return await this.dataClient.ListLengthAsync(cacheName, listName); + } + /// public void Dispose() { diff --git a/tests/Integration/Momento.Sdk.Incubating.Tests/ListTest.cs b/tests/Integration/Momento.Sdk.Incubating.Tests/ListTest.cs index ca0c5189..ff8651d7 100644 --- a/tests/Integration/Momento.Sdk.Incubating.Tests/ListTest.cs +++ b/tests/Integration/Momento.Sdk.Incubating.Tests/ListTest.cs @@ -562,4 +562,32 @@ public async Task ListRemoveAllAsync_ValueIsString_ListNotThereNoop() await client.ListRemoveAllAsync(cacheName, listName, Utils.NewGuidString()); Assert.Equal(CacheGetStatus.MISS, (await client.ListFetchAsync(cacheName, listName)).Status); } + + [Theory] + [InlineData(null, "my-list")] + [InlineData("cache", null)] + public async Task ListLengthAsync_NullChecks_ThrowsException(string cacheName, string listName) + { + await Assert.ThrowsAsync(async () => await client.ListLengthAsync(cacheName, listName)); + } + + [Fact] + public async Task ListLengthAsync_ListIsMissing_HappyPath() + { + var lengthResponse = await client.ListLengthAsync(cacheName, Utils.NewGuidString()); + Assert.Equal(0, lengthResponse.Length); + } + + [Fact] + public async Task ListLengthAsync_ListIsFound_HappyPath() + { + var listName = Utils.NewGuidString(); + foreach (var i in Enumerable.Range(0, 10)) + { + await client.ListPushBackAsync(cacheName, listName, Utils.NewGuidByteArray(), false); + } + + var lengthResponse = await client.ListLengthAsync(cacheName, listName); + Assert.Equal(10, lengthResponse.Length); + } }