Skip to content

Commit

Permalink
feat: Add sortedSetRemoveElement and sortedSetRemoveElements (#237)
Browse files Browse the repository at this point in the history
Add methods to remove an element from a sorted set.

Add methods to remove multiple elements from a sorted set.
  • Loading branch information
nand4011 authored Apr 13, 2023
1 parent c628b8b commit be8cdb1
Show file tree
Hide file tree
Showing 5 changed files with 475 additions and 0 deletions.
256 changes: 256 additions & 0 deletions momento-sdk/src/intTest/java/momento/sdk/SortedSetTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import static momento.sdk.TestUtils.randomString;
import static org.assertj.core.api.Assertions.assertThat;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import java.time.Duration;
import java.util.Collections;
import java.util.HashMap;
Expand All @@ -22,6 +24,8 @@
import momento.sdk.messages.CacheSortedSetIncrementScoreResponse;
import momento.sdk.messages.CacheSortedSetPutElementResponse;
import momento.sdk.messages.CacheSortedSetPutElementsResponse;
import momento.sdk.messages.CacheSortedSetRemoveElementResponse;
import momento.sdk.messages.CacheSortedSetRemoveElementsResponse;
import momento.sdk.messages.ScoredElement;
import momento.sdk.messages.SortOrder;
import momento.sdk.requests.CollectionTtl;
Expand Down Expand Up @@ -985,4 +989,256 @@ public void sortedSetIncrementScoreReturnsErrorWithNullElement() {
InstanceOfAssertFactories.type(CacheSortedSetIncrementScoreResponse.Error.class))
.satisfies(error -> assertThat(error).hasCauseInstanceOf(InvalidArgumentException.class));
}

// sortedSetRemoveElement

@Test
public void sortedSetRemoveElementStringHappyPath() {
final String one = "1";
final String two = "2";
final String three = "3";
final Map<String, Double> elements = ImmutableMap.of(one, 1.0, two, 2.0, three, 3.0);

assertThat(client.sortedSetRemoveElement(cacheName, sortedSetName, one))
.succeedsWithin(FIVE_SECONDS)
.isInstanceOf(CacheSortedSetRemoveElementResponse.Success.class);

assertThat(client.sortedSetPutElements(cacheName, sortedSetName, elements))
.succeedsWithin(FIVE_SECONDS)
.isInstanceOf(CacheSortedSetPutElementsResponse.Success.class);

assertThat(client.sortedSetRemoveElement(cacheName, sortedSetName, one))
.succeedsWithin(FIVE_SECONDS)
.isInstanceOf(CacheSortedSetRemoveElementResponse.Success.class);

assertThat(client.sortedSetFetchByRank(cacheName, sortedSetName))
.succeedsWithin(FIVE_SECONDS)
.asInstanceOf(InstanceOfAssertFactories.type(CacheSortedSetFetchResponse.Hit.class))
.satisfies(
hit ->
assertThat(hit.elementsList())
.hasSize(2)
.map(ScoredElement::getElement)
.containsOnly(two, three));
}

@Test
public void sortedSetRemoveElementBytesHappyPath() {
final byte[] one = "1".getBytes();
final byte[] two = "2".getBytes();
final byte[] three = "3".getBytes();
final Map<byte[], Double> elements = ImmutableMap.of(one, 1.0, two, 2.0, three, 3.0);

assertThat(client.sortedSetRemoveElement(cacheName, sortedSetName, one))
.succeedsWithin(FIVE_SECONDS)
.isInstanceOf(CacheSortedSetRemoveElementResponse.Success.class);

assertThat(client.sortedSetPutElementsByteArray(cacheName, sortedSetName, elements))
.succeedsWithin(FIVE_SECONDS)
.isInstanceOf(CacheSortedSetPutElementsResponse.Success.class);

assertThat(client.sortedSetRemoveElement(cacheName, sortedSetName, one))
.succeedsWithin(FIVE_SECONDS)
.isInstanceOf(CacheSortedSetRemoveElementResponse.Success.class);

assertThat(client.sortedSetFetchByRank(cacheName, sortedSetName))
.succeedsWithin(FIVE_SECONDS)
.asInstanceOf(InstanceOfAssertFactories.type(CacheSortedSetFetchResponse.Hit.class))
.satisfies(
hit ->
assertThat(hit.elementsList())
.hasSize(2)
.map(ScoredElement::getElementByteArray)
.containsOnly(two, three));
}

@Test
public void sortedSetRemoveElementReturnsErrorWithNullCacheName() {
assertThat(client.sortedSetRemoveElement(null, sortedSetName, "element"))
.succeedsWithin(FIVE_SECONDS)
.asInstanceOf(
InstanceOfAssertFactories.type(CacheSortedSetRemoveElementResponse.Error.class))
.satisfies(error -> assertThat(error).hasCauseInstanceOf(InvalidArgumentException.class));

assertThat(client.sortedSetRemoveElement(null, sortedSetName, "element".getBytes()))
.succeedsWithin(FIVE_SECONDS)
.asInstanceOf(
InstanceOfAssertFactories.type(CacheSortedSetRemoveElementResponse.Error.class))
.satisfies(error -> assertThat(error).hasCauseInstanceOf(InvalidArgumentException.class));
}

@Test
public void sortedSetRemoveElementReturnsErrorWithNonexistentCacheName() {
assertThat(client.sortedSetRemoveElement(randomString("cache"), sortedSetName, "element"))
.succeedsWithin(FIVE_SECONDS)
.asInstanceOf(
InstanceOfAssertFactories.type(CacheSortedSetRemoveElementResponse.Error.class))
.satisfies(error -> assertThat(error).hasCauseInstanceOf(NotFoundException.class));

assertThat(
client.sortedSetRemoveElement(
randomString("cache"), sortedSetName, "element".getBytes()))
.succeedsWithin(FIVE_SECONDS)
.asInstanceOf(
InstanceOfAssertFactories.type(CacheSortedSetRemoveElementResponse.Error.class))
.satisfies(error -> assertThat(error).hasCauseInstanceOf(NotFoundException.class));
}

@Test
public void sortedSetRemoveElementReturnsErrorWithNullSetName() {
assertThat(client.sortedSetRemoveElement(cacheName, null, "element"))
.succeedsWithin(FIVE_SECONDS)
.asInstanceOf(
InstanceOfAssertFactories.type(CacheSortedSetRemoveElementResponse.Error.class))
.satisfies(error -> assertThat(error).hasCauseInstanceOf(InvalidArgumentException.class));

assertThat(client.sortedSetRemoveElement(cacheName, null, "element".getBytes()))
.succeedsWithin(FIVE_SECONDS)
.asInstanceOf(
InstanceOfAssertFactories.type(CacheSortedSetRemoveElementResponse.Error.class))
.satisfies(error -> assertThat(error).hasCauseInstanceOf(InvalidArgumentException.class));
}

@Test
public void sortedSetRemoveElementReturnsErrorWithNullElement() {
assertThat(client.sortedSetRemoveElement(cacheName, sortedSetName, (String) null))
.succeedsWithin(FIVE_SECONDS)
.asInstanceOf(
InstanceOfAssertFactories.type(CacheSortedSetRemoveElementResponse.Error.class))
.satisfies(error -> assertThat(error).hasCauseInstanceOf(InvalidArgumentException.class));

assertThat(client.sortedSetRemoveElement(cacheName, sortedSetName, (byte[]) null))
.succeedsWithin(FIVE_SECONDS)
.asInstanceOf(
InstanceOfAssertFactories.type(CacheSortedSetRemoveElementResponse.Error.class))
.satisfies(error -> assertThat(error).hasCauseInstanceOf(InvalidArgumentException.class));
}

// sortedSetRemoveElements

@Test
public void sortedSetRemoveElementsStringHappyPath() {
final String one = "1";
final String two = "2";
final String three = "3";
final Map<String, Double> elements = ImmutableMap.of(one, 1.0, two, 2.0, three, 3.0);

assertThat(client.sortedSetRemoveElements(cacheName, sortedSetName, elements.keySet()))
.succeedsWithin(FIVE_SECONDS)
.isInstanceOf(CacheSortedSetRemoveElementsResponse.Success.class);

assertThat(client.sortedSetPutElements(cacheName, sortedSetName, elements))
.succeedsWithin(FIVE_SECONDS)
.isInstanceOf(CacheSortedSetPutElementsResponse.Success.class);

assertThat(client.sortedSetRemoveElements(cacheName, sortedSetName, Sets.newHashSet(one, two)))
.succeedsWithin(FIVE_SECONDS)
.isInstanceOf(CacheSortedSetRemoveElementsResponse.Success.class);

assertThat(client.sortedSetFetchByRank(cacheName, sortedSetName))
.succeedsWithin(FIVE_SECONDS)
.asInstanceOf(InstanceOfAssertFactories.type(CacheSortedSetFetchResponse.Hit.class))
.satisfies(
hit ->
assertThat(hit.elementsList())
.hasSize(1)
.map(ScoredElement::getElement)
.containsOnly(three));
}

@Test
public void sortedSetRemoveElementsBytesHappyPath() {
final byte[] one = "1".getBytes();
final byte[] two = "2".getBytes();
final byte[] three = "3".getBytes();
final Map<byte[], Double> elements = ImmutableMap.of(one, 1.0, two, 2.0, three, 3.0);

assertThat(client.sortedSetRemoveElementsByteArray(cacheName, sortedSetName, elements.keySet()))
.succeedsWithin(FIVE_SECONDS)
.isInstanceOf(CacheSortedSetRemoveElementsResponse.Success.class);

assertThat(client.sortedSetPutElementsByteArray(cacheName, sortedSetName, elements))
.succeedsWithin(FIVE_SECONDS)
.isInstanceOf(CacheSortedSetPutElementsResponse.Success.class);

assertThat(
client.sortedSetRemoveElementsByteArray(
cacheName, sortedSetName, Sets.newHashSet(one, two)))
.succeedsWithin(FIVE_SECONDS)
.isInstanceOf(CacheSortedSetRemoveElementsResponse.Success.class);

assertThat(client.sortedSetFetchByRank(cacheName, sortedSetName))
.succeedsWithin(FIVE_SECONDS)
.asInstanceOf(InstanceOfAssertFactories.type(CacheSortedSetFetchResponse.Hit.class))
.satisfies(
hit ->
assertThat(hit.elementsList())
.hasSize(1)
.map(ScoredElement::getElementByteArray)
.containsOnly(three));
}

@Test
public void sortedSetRemoveElementsReturnsErrorWithNullCacheName() {
assertThat(client.sortedSetRemoveElements(null, sortedSetName, Collections.emptySet()))
.succeedsWithin(FIVE_SECONDS)
.asInstanceOf(
InstanceOfAssertFactories.type(CacheSortedSetRemoveElementsResponse.Error.class))
.satisfies(error -> assertThat(error).hasCauseInstanceOf(InvalidArgumentException.class));

assertThat(client.sortedSetRemoveElementsByteArray(null, sortedSetName, Collections.emptySet()))
.succeedsWithin(FIVE_SECONDS)
.asInstanceOf(
InstanceOfAssertFactories.type(CacheSortedSetRemoveElementsResponse.Error.class))
.satisfies(error -> assertThat(error).hasCauseInstanceOf(InvalidArgumentException.class));
}

@Test
public void sortedSetRemoveElementsReturnsErrorWithNonexistentCacheName() {
assertThat(
client.sortedSetRemoveElements(
randomString("cache"), sortedSetName, Collections.emptySet()))
.succeedsWithin(FIVE_SECONDS)
.asInstanceOf(
InstanceOfAssertFactories.type(CacheSortedSetRemoveElementsResponse.Error.class))
.satisfies(error -> assertThat(error).hasCauseInstanceOf(NotFoundException.class));

assertThat(
client.sortedSetRemoveElementsByteArray(
randomString("cache"), sortedSetName, Collections.emptySet()))
.succeedsWithin(FIVE_SECONDS)
.asInstanceOf(
InstanceOfAssertFactories.type(CacheSortedSetRemoveElementsResponse.Error.class))
.satisfies(error -> assertThat(error).hasCauseInstanceOf(NotFoundException.class));
}

@Test
public void sortedSetRemoveElementsReturnsErrorWithNullSetName() {
assertThat(client.sortedSetRemoveElements(cacheName, null, Collections.emptySet()))
.succeedsWithin(FIVE_SECONDS)
.asInstanceOf(
InstanceOfAssertFactories.type(CacheSortedSetRemoveElementsResponse.Error.class))
.satisfies(error -> assertThat(error).hasCauseInstanceOf(InvalidArgumentException.class));

assertThat(client.sortedSetRemoveElementsByteArray(cacheName, null, Collections.emptySet()))
.succeedsWithin(FIVE_SECONDS)
.asInstanceOf(
InstanceOfAssertFactories.type(CacheSortedSetRemoveElementsResponse.Error.class))
.satisfies(error -> assertThat(error).hasCauseInstanceOf(InvalidArgumentException.class));
}

@Test
public void sortedSetRemoveElementsReturnsErrorWithNullElements() {
assertThat(client.sortedSetRemoveElements(cacheName, sortedSetName, null))
.succeedsWithin(FIVE_SECONDS)
.asInstanceOf(
InstanceOfAssertFactories.type(CacheSortedSetRemoveElementsResponse.Error.class))
.satisfies(error -> assertThat(error).hasCauseInstanceOf(InvalidArgumentException.class));

assertThat(client.sortedSetRemoveElementsByteArray(cacheName, sortedSetName, null))
.succeedsWithin(FIVE_SECONDS)
.asInstanceOf(
InstanceOfAssertFactories.type(CacheSortedSetRemoveElementsResponse.Error.class))
.satisfies(error -> assertThat(error).hasCauseInstanceOf(InvalidArgumentException.class));
}
}
54 changes: 54 additions & 0 deletions momento-sdk/src/main/java/momento/sdk/CacheClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
import momento.sdk.messages.CacheSortedSetIncrementScoreResponse;
import momento.sdk.messages.CacheSortedSetPutElementResponse;
import momento.sdk.messages.CacheSortedSetPutElementsResponse;
import momento.sdk.messages.CacheSortedSetRemoveElementResponse;
import momento.sdk.messages.CacheSortedSetRemoveElementsResponse;
import momento.sdk.messages.CreateCacheResponse;
import momento.sdk.messages.CreateSigningKeyResponse;
import momento.sdk.messages.DeleteCacheResponse;
Expand Down Expand Up @@ -1052,6 +1054,58 @@ public CompletableFuture<CacheSortedSetIncrementScoreResponse> sortedSetIncremen
return scsDataClient.sortedSetIncrementScore(cacheName, sortedSetName, element, amount, null);
}

/**
* Remove an element from a sorted set
*
* @param cacheName - The cache containing the sorted set.
* @param sortedSetName - The sorted set to remove from.
* @param element - The element to remove from the set.
* @return Future containing the result of the remove operation.
*/
public CompletableFuture<CacheSortedSetRemoveElementResponse> sortedSetRemoveElement(
String cacheName, String sortedSetName, String element) {
return scsDataClient.sortedSetRemoveElement(cacheName, sortedSetName, element);
}

/**
* Remove an element from a sorted set
*
* @param cacheName - The cache containing the sorted set.
* @param sortedSetName - The sorted set to remove from.
* @param element - The element to remove from the set.
* @return Future containing the result of the remove operation.
*/
public CompletableFuture<CacheSortedSetRemoveElementResponse> sortedSetRemoveElement(
String cacheName, String sortedSetName, byte[] element) {
return scsDataClient.sortedSetRemoveElement(cacheName, sortedSetName, element);
}

/**
* Remove elements from a sorted set
*
* @param cacheName - The cache containing the sorted set.
* @param sortedSetName - The sorted set to remove from.
* @param elements - The elements to remove from the set.
* @return Future containing the result of the remove operation.
*/
public CompletableFuture<CacheSortedSetRemoveElementsResponse> sortedSetRemoveElements(
String cacheName, String sortedSetName, Set<String> elements) {
return scsDataClient.sortedSetRemoveElements(cacheName, sortedSetName, elements);
}

/**
* Remove elements from a sorted set
*
* @param cacheName - The cache containing the sorted set.
* @param sortedSetName - The sorted set to remove from.
* @param elements - The elements to remove from the set.
* @return Future containing the result of the remove operation.
*/
public CompletableFuture<CacheSortedSetRemoveElementsResponse> sortedSetRemoveElementsByteArray(
String cacheName, String sortedSetName, Set<byte[]> elements) {
return scsDataClient.sortedSetRemoveElementsByteArray(cacheName, sortedSetName, elements);
}

/**
* Concatenates values to the back of the list.
*
Expand Down
Loading

0 comments on commit be8cdb1

Please sign in to comment.