Skip to content

Commit

Permalink
support hset, hget, lindex, linsert, blmove, incr, hlen and lmove wit… (
Browse files Browse the repository at this point in the history
  • Loading branch information
alon-arenberg authored Jun 30, 2024
1 parent dae4606 commit fb9fe86
Show file tree
Hide file tree
Showing 8 changed files with 759 additions and 7 deletions.
75 changes: 75 additions & 0 deletions java/client/src/main/java/glide/api/BaseClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import static glide.utils.ArrayTransformUtils.castMapOf2DArray;
import static glide.utils.ArrayTransformUtils.castMapOfArrays;
import static glide.utils.ArrayTransformUtils.concatenateArrays;
import static glide.utils.ArrayTransformUtils.convertMapToKeyValueGlideStringArray;
import static glide.utils.ArrayTransformUtils.convertMapToKeyValueStringArray;
import static glide.utils.ArrayTransformUtils.convertMapToValueKeyStringArray;
import static glide.utils.ArrayTransformUtils.mapGeoDataToArray;
Expand Down Expand Up @@ -728,6 +729,11 @@ public CompletableFuture<Long> incr(@NonNull String key) {
return commandManager.submitNewCommand(Incr, new String[] {key}, this::handleLongResponse);
}

@Override
public CompletableFuture<Long> incr(@NonNull GlideString key) {
return commandManager.submitNewCommand(Incr, new GlideString[] {key}, this::handleLongResponse);
}

@Override
public CompletableFuture<Long> incrBy(@NonNull String key, long amount) {
return commandManager.submitNewCommand(
Expand Down Expand Up @@ -796,13 +802,27 @@ public CompletableFuture<String> hget(@NonNull String key, @NonNull String field
HGet, new String[] {key, field}, this::handleStringOrNullResponse);
}

@Override
public CompletableFuture<GlideString> hget(@NonNull GlideString key, @NonNull GlideString field) {
return commandManager.submitNewCommand(
HGet, new GlideString[] {key, field}, this::handleGlideStringOrNullResponse);
}

@Override
public CompletableFuture<Long> hset(
@NonNull String key, @NonNull Map<String, String> fieldValueMap) {
String[] args = ArrayUtils.addFirst(convertMapToKeyValueStringArray(fieldValueMap), key);
return commandManager.submitNewCommand(HSet, args, this::handleLongResponse);
}

@Override
public CompletableFuture<Long> hset(
@NonNull GlideString key, @NonNull Map<GlideString, GlideString> fieldValueMap) {
GlideString[] args =
ArrayUtils.addFirst(convertMapToKeyValueGlideStringArray(fieldValueMap), key);
return commandManager.submitNewCommand(HSet, args, this::handleLongResponse);
}

@Override
public CompletableFuture<Boolean> hsetnx(
@NonNull String key, @NonNull String field, @NonNull String value) {
Expand All @@ -828,6 +848,11 @@ public CompletableFuture<Long> hlen(@NonNull String key) {
return commandManager.submitNewCommand(HLen, new String[] {key}, this::handleLongResponse);
}

@Override
public CompletableFuture<Long> hlen(@NonNull GlideString key) {
return commandManager.submitNewCommand(HLen, new GlideString[] {key}, this::handleLongResponse);
}

@Override
public CompletableFuture<String[]> hvals(@NonNull String key) {
return commandManager.submitNewCommand(
Expand Down Expand Up @@ -1015,6 +1040,14 @@ public CompletableFuture<String> lindex(@NonNull String key, long index) {
LIndex, new String[] {key, Long.toString(index)}, this::handleStringOrNullResponse);
}

@Override
public CompletableFuture<GlideString> lindex(@NonNull GlideString key, long index) {
return commandManager.submitNewCommand(
LIndex,
new GlideString[] {key, gs(Long.toString(index))},
this::handleGlideStringOrNullResponse);
}

@Override
public CompletableFuture<String> ltrim(@NonNull String key, long start, long end) {
return commandManager.submitNewCommand(
Expand Down Expand Up @@ -2077,6 +2110,18 @@ public CompletableFuture<Long> linsert(
LInsert, new String[] {key, position.toString(), pivot, element}, this::handleLongResponse);
}

@Override
public CompletableFuture<Long> linsert(
@NonNull GlideString key,
@NonNull InsertPosition position,
@NonNull GlideString pivot,
@NonNull GlideString element) {
return commandManager.submitNewCommand(
LInsert,
new GlideString[] {key, gs(position.toString()), pivot, element},
this::handleLongResponse);
}

@Override
public CompletableFuture<String[]> blpop(@NonNull String[] keys, double timeout) {
String[] arguments = ArrayUtils.add(keys, Double.toString(timeout));
Expand Down Expand Up @@ -2530,6 +2575,17 @@ public CompletableFuture<String> lmove(
return commandManager.submitNewCommand(LMove, arguments, this::handleStringOrNullResponse);
}

@Override
public CompletableFuture<GlideString> lmove(
@NonNull GlideString source,
@NonNull GlideString destination,
@NonNull ListDirection wherefrom,
@NonNull ListDirection whereto) {
GlideString[] arguments =
new GlideString[] {source, destination, gs(wherefrom.toString()), gs(whereto.toString())};
return commandManager.submitNewCommand(LMove, arguments, this::handleGlideStringOrNullResponse);
}

@Override
public CompletableFuture<String> blmove(
@NonNull String source,
Expand All @@ -2544,6 +2600,25 @@ public CompletableFuture<String> blmove(
return commandManager.submitNewCommand(BLMove, arguments, this::handleStringOrNullResponse);
}

@Override
public CompletableFuture<GlideString> blmove(
@NonNull GlideString source,
@NonNull GlideString destination,
@NonNull ListDirection wherefrom,
@NonNull ListDirection whereto,
double timeout) {
GlideString[] arguments =
new GlideString[] {
source,
destination,
gs(wherefrom.toString()),
gs(whereto.toString()),
gs(Double.toString(timeout))
};
return commandManager.submitNewCommand(
BLMove, arguments, this::handleGlideStringOrNullResponse);
}

@Override
public CompletableFuture<String> srandmember(@NonNull String key) {
String[] arguments = new String[] {key};
Expand Down
53 changes: 53 additions & 0 deletions java/client/src/main/java/glide/api/commands/HashBaseCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,25 @@ public interface HashBaseCommands {
*/
CompletableFuture<String> hget(String key, String field);

/**
* Retrieves the value associated with <code>field</code> in the hash stored at <code>key</code>.
*
* @see <a href="https://redis.io/commands/hget/">redis.io</a> for details.
* @param key The key of the hash.
* @param field The field in the hash stored at <code>key</code> to retrieve from the database.
* @return The value associated with <code>field</code>, or <code>null</code> when <code>field
* </code> is not present in the hash or <code>key</code> does not exist.
* @example
* <pre>{@code
* String payload = client.hget(gs("my_hash"), gs("field1")).get();
* assert payload.equals(gs("value"));
*
* String payload = client.hget(gs("my_hash"), gs("nonexistent_field")).get();
* assert payload.equals(null);
* }</pre>
*/
CompletableFuture<GlideString> hget(GlideString key, GlideString field);

/**
* Sets the specified fields to their respective values in the hash stored at <code>key</code>.
*
Expand All @@ -51,6 +70,22 @@ public interface HashBaseCommands {
*/
CompletableFuture<Long> hset(String key, Map<String, String> fieldValueMap);

/**
* Sets the specified fields to their respective values in the hash stored at <code>key</code>.
*
* @see <a href="https://redis.io/commands/hset/">redis.io</a> for details.
* @param key The key of the hash.
* @param fieldValueMap A field-value map consisting of fields and their corresponding values to
* be set in the hash stored at the specified key.
* @return The number of fields that were added.
* @example
* <pre>{@code
* Long num = client.hset(gs("my_hash"), Map.of(gs("field"), gs("value"), gs("field2"), gs("value2"))).get();
* assert num == 2L;
* }</pre>
*/
CompletableFuture<Long> hset(GlideString key, Map<GlideString, GlideString> fieldValueMap);

/**
* Sets <code>field</code> in the hash stored at <code>key</code> to <code>value</code>, only if
* <code>field</code> does not yet exist.<br>
Expand Down Expand Up @@ -133,6 +168,24 @@ public interface HashBaseCommands {
*/
CompletableFuture<Long> hlen(String key);

/**
* Returns the number of fields contained in the hash stored at <code>key</code>.
*
* @see <a href="https://redis.io/commands/hlen/">redis.io</a> for details.
* @param key The key of the hash.
* @return The number of fields in the hash, or <code>0</code> when the key does not exist.<br>
* If <code>key</code> holds a value that is not a hash, an error is returned.
* @example
* <pre>{@code
* Long num1 = client.hlen(gs("myHash")).get();
* assert num1 == 3L;
*
* Long num2 = client.hlen(gs("nonExistingKey")).get();
* assert num2 == 0L;
* }</pre>
*/
CompletableFuture<Long> hlen(GlideString key);

/**
* Returns all values in the hash stored at <code>key</code>.
*
Expand Down
125 changes: 123 additions & 2 deletions java/client/src/main/java/glide/api/commands/ListBaseCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -243,14 +243,38 @@ CompletableFuture<Long[]> lposCount(
* @example
* <pre>{@code
* String payload1 = client.lindex("myList", 0).get();
* assert payload1.equals('value1'); // Returns the first element in the list stored at 'myList'.
* assert payload1.equals("value1"); // Returns the first element in the list stored at 'myList'.
*
* String payload2 = client.lindex("myList", -1).get();
* assert payload2.equals('value3'); // Returns the last element in the list stored at 'myList'.
* assert payload2.equals("value3"); // Returns the last element in the list stored at 'myList'.
* }</pre>
*/
CompletableFuture<String> lindex(String key, long index);

/**
* Returns the element at <code>index</code> from the list stored at <code>key</code>.<br>
* The index is zero-based, so <code>0</code> means the first element, <code>1</code> the second
* element and so on. Negative indices can be used to designate elements starting at the tail of
* the list. Here, <code>-1</code> means the last element, <code>-2</code> means the penultimate
* and so forth.
*
* @see <a href="https://redis.io/commands/lindex/">redis.io</a> for details.
* @param key The key of the list.
* @param index The index of the element in the list to retrieve.
* @return The element at <code>index</code> in the list stored at <code>key</code>.<br>
* If <code>index</code> is out of range or if <code>key</code> does not exist, <code>null
* </code> is returned.
* @example
* <pre>{@code
* String payload1 = client.lindex(gs("myList"), 0).get();
* assert payload1.equals(gs("value1")); // Returns the first element in the list stored at 'myList'.
*
* String payload2 = client.lindex(gs("myList"), -1).get();
* assert payload2.equals(gs("value3")); // Returns the last element in the list stored at 'myList'.
* }</pre>
*/
CompletableFuture<GlideString> lindex(GlideString key, long index);

/**
* Trims an existing list so that it will contain only the specified range of elements specified.
* <br>
Expand Down Expand Up @@ -486,6 +510,28 @@ CompletableFuture<Long[]> lposCount(
CompletableFuture<Long> linsert(
String key, InsertPosition position, String pivot, String element);

/**
* Inserts <code>element</code> in the list at <code>key</code> either before or after the <code>
* pivot</code>.
*
* @see <a href="https://redis.io/commands/linsert/">redis.io</a> for details.
* @param key The key of the list.
* @param position The relative position to insert into - either {@link InsertPosition#BEFORE} or
* {@link InsertPosition#AFTER} the <code>pivot</code>.
* @param pivot An element of the list.
* @param element The new element to insert.
* @return The list length after a successful insert operation.<br>
* If the <code>key</code> doesn't exist returns <code>-1</code>.<br>
* If the <code>pivot</code> wasn't found, returns <code>0</code>.
* @example
* <pre>{@code
* Long length = client.linsert(gs("my_list"), BEFORE, gs("World"), gs("There")).get();
* assert length > 0L;
* }</pre>
*/
CompletableFuture<Long> linsert(
GlideString key, InsertPosition position, GlideString pivot, GlideString element);

/**
* Pops an element from the head of the first list that is non-empty, with the given <code>keys
* </code> being checked in the order that they are given.<br>
Expand Down Expand Up @@ -791,6 +837,35 @@ CompletableFuture<Map<String, String[]>> blmpop(
CompletableFuture<String> lmove(
String source, String destination, ListDirection wherefrom, ListDirection whereto);

/**
* Atomically pops and removes the left/right-most element to the list stored at <code>source
* </code> depending on <code>wherefrom</code>, and pushes the element at the first/last element
* of the list stored at <code>destination</code> depending on <code>wherefrom</code>.
*
* @since Redis 6.2.0 and above.
* @apiNote When in cluster mode, <code>source</code> and <code>destination</code> must map to the
* same hash slot.
* @see <a href="https://valkey.io/commands/lmove/">valkey.io</a> for details.
* @param source The key to the source list.
* @param destination The key to the destination list.
* @param wherefrom The {@link ListDirection} the element should be removed from.
* @param whereto The {@link ListDirection} the element should be added to.
* @return The popped element or <code>null</code> if <code>source</code> does not exist.
* @example
* <pre>{@code
* client.lpush(gs("testKey1"), new GlideString[] {gs("two"), gs("one")}).get();
* client.lpush(gs("testKey2"), new GlideString[] {gs("four"), gs("three")}).get();
* var result = client.lmove(gs("testKey1"), gs("testKey2"), ListDirection.LEFT, ListDirection.LEFT).get();
* assertEquals(result, gs("one"));
* GlideString[] upratedArray1 = client.lrange(gs("testKey1"), 0, -1).get();
* GlideString[] upratedArray2 = client.lrange(gs("testKey2"), 0, -1).get();
* assertArrayEquals(new GlideString[] {gs("two")}, updatedArray1);
* assertArrayEquals(new GlideString[] {gs("one"), gs("three"), gs("four)"}, updatedArray2);
* }</pre>
*/
CompletableFuture<GlideString> lmove(
GlideString source, GlideString destination, ListDirection wherefrom, ListDirection whereto);

/**
* Blocks the connection until it pops atomically and removes the left/right-most element to the
* list stored at <code>source</code> depending on <code>wherefrom</code>, and pushes the element
Expand Down Expand Up @@ -836,4 +911,50 @@ CompletableFuture<String> blmove(
ListDirection wherefrom,
ListDirection whereto,
double timeout);

/**
* Blocks the connection until it pops atomically and removes the left/right-most element to the
* list stored at <code>source</code> depending on <code>wherefrom</code>, and pushes the element
* at the first/last element of the list stored at <code>destination</code> depending on <code>
* wherefrom</code>.<br>
* <code>BLMove</code> is the blocking variant of {@link #lmove(String, String, ListDirection,
* ListDirection)}.
*
* @since Redis 6.2.0 and above.
* @apiNote
* <ol>
* <li>When in cluster mode, all <code>source</code> and <code>destination</code> must map
* to the same hash slot.
* <li><code>BLMove</code> is a client blocking command, see <a
* href="https://github.com/aws/glide-for-redis/wiki/General-Concepts#blocking-commands">Blocking
* Commands</a> for more details and best practices.
* </ol>
*
* @see <a href="https://valkey.io/commands/blmove/">valkey.io</a> for details.
* @param source The key to the source list.
* @param destination The key to the destination list.
* @param wherefrom The {@link ListDirection} the element should be removed from.
* @param whereto The {@link ListDirection} the element should be added to.
* @param timeout The number of seconds to wait for a blocking operation to complete. A value of
* <code>0</code> will block indefinitely.
* @return The popped element or <code>null</code> if <code>source</code> does not exist or if the
* operation timed-out.
* @example
* <pre>{@code
* client.lpush(gs("testKey1"), new GlideString[] {gs("two"), gs("one")}).get();
* client.lpush(gs("testKey2"), new GlideString[] {gs("four"), gs("three")}).get();
* var result = client.blmove(gs("testKey1"), gs("testKey2"), ListDirection.LEFT, ListDirection.LEFT, 0.1).get();
* assertEquals(result, gs("one"));
* GlideString[] upratedArray1 = client.lrange(gs("testKey1"), 0, -1).get();
* GlideString[] upratedArray2 = client.lrange(gs("testKey2"), 0, -1).get();
* assertArrayEquals(new GlideString[] {gs("two")}, updatedArray1);
* assertArrayEquals(new GlideString[] {gs("one"), gs("three"), gs("four")}, updatedArray2);
* }</pre>
*/
CompletableFuture<GlideString> blmove(
GlideString source,
GlideString destination,
ListDirection wherefrom,
ListDirection whereto,
double timeout);
}
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,21 @@ public interface StringBaseCommands {
*/
CompletableFuture<Long> incr(String key);

/**
* Increments the number stored at <code>key</code> by one. If <code>key</code> does not exist, it
* is set to 0 before performing the operation.
*
* @see <a href="https://redis.io/commands/incr/">redis.io</a> for details.
* @param key The key to increment its value.
* @return The value of <code>key</code> after the increment.
* @example
* <pre>{@code
* Long num = client.incr(gs("key")).get();
* assert num == 5L;
* }</pre>
*/
CompletableFuture<Long> incr(GlideString key);

/**
* Increments the number stored at <code>key</code> by <code>amount</code>. If <code>key</code>
* does not exist, it is set to 0 before performing the operation.
Expand Down
Loading

0 comments on commit fb9fe86

Please sign in to comment.