This is an automated email from the ASF dual-hosted git repository.

dschneider pushed a commit to branch more-string-work
in repository https://gitbox.apache.org/repos/asf/geode.git

commit a9a3573e20baf4135056778557ce0b12ad039568
Author: Darrel Schneider <[email protected]>
AuthorDate: Thu May 28 22:55:14 2020 -0700

    added getrange to CommandFunction
---
 .../redis/internal/executor/CommandFunction.java   |  7 ++++
 .../internal/executor/string/GetRangeExecutor.java | 36 ++++---------------
 .../internal/executor/string/RedisString.java      | 40 ++++++++++++++++++++++
 .../executor/string/RedisStringCommands.java       |  2 ++
 .../RedisStringCommandsFunctionExecutor.java       |  6 ++++
 .../executor/string/RedisStringInRegion.java       | 10 ++++++
 6 files changed, 71 insertions(+), 30 deletions(-)

diff --git 
a/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/CommandFunction.java
 
b/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/CommandFunction.java
index fc3072b..9be9e19 100644
--- 
a/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/CommandFunction.java
+++ 
b/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/CommandFunction.java
@@ -119,6 +119,13 @@ public class CommandFunction extends 
SingleResultRedisFunction {
         callable = () -> new RedisStringInRegion(localRegion).getset(key, 
value);
         break;
       }
+      case GETRANGE: {
+        Object[] argArgs = (Object[]) args[1];
+        long start = (long) argArgs[0];
+        long end = (long) argArgs[1];
+        callable = () -> new RedisStringInRegion(localRegion).getrange(key, 
start, end);
+        break;
+      }
       case INCR:
         callable = () -> new RedisStringInRegion(localRegion).incr(key);
         break;
diff --git 
a/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/string/GetRangeExecutor.java
 
b/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/string/GetRangeExecutor.java
index 123d558..bf81ae2 100755
--- 
a/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/string/GetRangeExecutor.java
+++ 
b/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/string/GetRangeExecutor.java
@@ -14,7 +14,6 @@
  */
 package org.apache.geode.redis.internal.executor.string;
 
-import java.util.Arrays;
 import java.util.List;
 
 import org.apache.geode.redis.internal.ByteArrayWrapper;
@@ -53,38 +52,15 @@ public class GetRangeExecutor extends StringExecutor {
 
     RedisStringCommands stringCommands = getRedisStringCommands(context);
     ByteArrayWrapper key = command.getKey();
-    ByteArrayWrapper valueWrapper = stringCommands.get(key);
 
-    if (valueWrapper == null) {
-      
command.setResponse(Coder.getEmptyStringResponse(context.getByteBufAllocator()));
-      return;
-    }
+    ByteArrayWrapper returnRange = stringCommands.getrange(key, start, end);
 
-    byte[] value = valueWrapper.toBytes();
-    int length = value.length;
-
-    start = getBoundedStartIndex(start, length);
-    end = getBoundedEndIndex(end, length);
-
-    /*
-     * Can't 'start' at end of value
-     */
-    if (start > end || start == length) {
-      
command.setResponse(Coder.getEmptyStringResponse(context.getByteBufAllocator()));
-      return;
-    }
-    /*
-     * 1 is added to end because the end in copyOfRange is exclusive but in 
Redis it is inclusive
-     */
-    if (end != length) {
-      end++;
-    }
-    byte[] returnRange = Arrays.copyOfRange(value, (int) start, (int) end);
-    if (returnRange == null || returnRange.length == 0) {
+    if (returnRange == null) {
       command.setResponse(Coder.getNilResponse(context.getByteBufAllocator()));
-      return;
+    } else if (returnRange.length() == 0) {
+      
command.setResponse(Coder.getEmptyStringResponse(context.getByteBufAllocator()));
+    } else {
+      respondBulkStrings(command, context, returnRange);
     }
-
-    respondBulkStrings(command, context, returnRange);
   }
 }
diff --git 
a/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/string/RedisString.java
 
b/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/string/RedisString.java
index 234efae..687d401 100644
--- 
a/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/string/RedisString.java
+++ 
b/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/string/RedisString.java
@@ -18,6 +18,7 @@ package org.apache.geode.redis.internal.executor.string;
 import java.io.DataInput;
 import java.io.DataOutput;
 import java.io.IOException;
+import java.util.Arrays;
 
 import org.apache.geode.DataSerializer;
 import org.apache.geode.cache.Region;
@@ -121,6 +122,45 @@ public class RedisString extends AbstractRedisData {
     }
   }
 
+  public ByteArrayWrapper getrange(long start, long end) {
+    int length = value.length();
+    int boundedStart = getBoundedStartIndex(start, length);
+    int boundedEnd = getBoundedEndIndex(end, length);
+
+    /*
+     * Can't 'start' at end of value
+     */
+    if (boundedStart > boundedEnd || boundedStart == length) {
+      return new ByteArrayWrapper(new byte[0]);
+    }
+    /*
+     * 1 is added to end because the end in copyOfRange is exclusive but in 
Redis it is inclusive
+     */
+    if (boundedEnd != length) {
+      boundedEnd++;
+    }
+    byte[] returnRange = Arrays.copyOfRange(value.toBytes(), boundedStart, 
boundedEnd);
+    return new ByteArrayWrapper(returnRange);
+  }
+
+  private int getBoundedStartIndex(long index, int size) {
+    if (index >= 0L) {
+      return (int) Math.min(index, size);
+    } else {
+      return (int) Math.max(index + size, 0);
+    }
+  }
+
+  private int getBoundedEndIndex(long index, int size) {
+    if (index >= 0L) {
+      return (int) Math.min(index, size);
+    } else {
+      return (int) Math.max(index + size, -1);
+    }
+  }
+
+
+
   @Override
   public void toData(DataOutput out) throws IOException {
     super.toData(out);
diff --git 
a/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/string/RedisStringCommands.java
 
b/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/string/RedisStringCommands.java
index bfbf2ce..6266cb0 100644
--- 
a/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/string/RedisStringCommands.java
+++ 
b/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/string/RedisStringCommands.java
@@ -32,4 +32,6 @@ public interface RedisStringCommands {
   long incrby(ByteArrayWrapper key, long increment);
 
   long decrby(ByteArrayWrapper key, long decrement);
+
+  ByteArrayWrapper getrange(ByteArrayWrapper key, long start, long end);
 }
diff --git 
a/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/string/RedisStringCommandsFunctionExecutor.java
 
b/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/string/RedisStringCommandsFunctionExecutor.java
index 4c1fdf9..426f40c 100644
--- 
a/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/string/RedisStringCommandsFunctionExecutor.java
+++ 
b/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/string/RedisStringCommandsFunctionExecutor.java
@@ -18,6 +18,7 @@ import static 
org.apache.geode.redis.internal.RedisCommandType.APPEND;
 import static org.apache.geode.redis.internal.RedisCommandType.DECR;
 import static org.apache.geode.redis.internal.RedisCommandType.DECRBY;
 import static org.apache.geode.redis.internal.RedisCommandType.GET;
+import static org.apache.geode.redis.internal.RedisCommandType.GETRANGE;
 import static org.apache.geode.redis.internal.RedisCommandType.GETSET;
 import static org.apache.geode.redis.internal.RedisCommandType.INCR;
 import static org.apache.geode.redis.internal.RedisCommandType.INCRBY;
@@ -74,4 +75,9 @@ public class RedisStringCommandsFunctionExecutor implements 
RedisStringCommands
   public long decrby(ByteArrayWrapper key, long decrement) {
     return CommandFunction.execute(DECRBY, key, decrement, region);
   }
+
+  @Override
+  public ByteArrayWrapper getrange(ByteArrayWrapper key, long start, long end) 
{
+    return CommandFunction.execute(GETRANGE, key, new Object[] {start, end}, 
region);
+  }
 }
diff --git 
a/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/string/RedisStringInRegion.java
 
b/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/string/RedisStringInRegion.java
index 49b40f7..d6e1375 100644
--- 
a/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/string/RedisStringInRegion.java
+++ 
b/geode-redis/src/main/java/org/apache/geode/redis/internal/executor/string/RedisStringInRegion.java
@@ -147,6 +147,16 @@ public class RedisStringInRegion extends RedisKeyInRegion 
implements RedisString
     return redisString.decrby(region, key, decrement);
   }
 
+  @Override
+  public ByteArrayWrapper getrange(ByteArrayWrapper key, long start, long end) 
{
+    RedisString redisString = getRedisString(key);
+
+    if (redisString == null) {
+      return new ByteArrayWrapper(new byte[0]);
+    }
+    return redisString.getrange(start, end);
+  }
+
   private boolean setnx(ByteArrayWrapper key, ByteArrayWrapper value, 
SetOptions options) {
     if (getRedisData(key) != null) {
       return false;

Reply via email to