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

ringles pushed a commit to branch 
GEODE-9892-Create-Infrastructure-for-Redis-Lists
in repository https://gitbox.apache.org/repos/asf/geode.git


The following commit(s) were added to 
refs/heads/GEODE-9892-Create-Infrastructure-for-Redis-Lists by this push:
     new ec96801  Many radish tests working
ec96801 is described below

commit ec968015835ab98c3247cad58c3a4381654f9995
Author: Ray Ingles <[email protected]>
AuthorDate: Thu Jan 6 17:17:24 2022 -0500

    Many radish tests working
---
 .../redis/internal/commands/RedisCommandType.java  |  8 +++
 .../commands/executor/list/LPopExecutor.java       | 70 ++++++++++++++++++++++
 .../commands/executor/list/LPushExecutor.java      | 43 +++++++++++++
 .../geode/redis/internal/data/NullRedisList.java   |  2 +-
 .../internal/netty/ExecutionHandlerContext.java    | 11 +++-
 5 files changed, 132 insertions(+), 2 deletions(-)

diff --git 
a/geode-for-redis/src/main/java/org/apache/geode/redis/internal/commands/RedisCommandType.java
 
b/geode-for-redis/src/main/java/org/apache/geode/redis/internal/commands/RedisCommandType.java
index fa53a4d..b2cd57e 100755
--- 
a/geode-for-redis/src/main/java/org/apache/geode/redis/internal/commands/RedisCommandType.java
+++ 
b/geode-for-redis/src/main/java/org/apache/geode/redis/internal/commands/RedisCommandType.java
@@ -76,6 +76,8 @@ import 
org.apache.geode.redis.internal.commands.executor.key.RestoreExecutor;
 import org.apache.geode.redis.internal.commands.executor.key.ScanExecutor;
 import org.apache.geode.redis.internal.commands.executor.key.TTLExecutor;
 import org.apache.geode.redis.internal.commands.executor.key.TypeExecutor;
+import org.apache.geode.redis.internal.commands.executor.list.LPopExecutor;
+import org.apache.geode.redis.internal.commands.executor.list.LPushExecutor;
 import 
org.apache.geode.redis.internal.commands.executor.pubsub.PsubscribeExecutor;
 import org.apache.geode.redis.internal.commands.executor.pubsub.PubSubExecutor;
 import 
org.apache.geode.redis.internal.commands.executor.pubsub.PublishExecutor;
@@ -285,6 +287,12 @@ public enum RedisCommandType {
   ZUNIONSTORE(new ZUnionStoreExecutor(), SUPPORTED,
       new Parameter().min(4).flags(WRITE, DENYOOM, MOVABLEKEYS)),
 
+  /************** Lists *****************/
+
+  LPUSH(new LPushExecutor(), SUPPORTED, new Parameter().min(3).flags(WRITE, 
DENYOOM, FAST)),
+  LPOP(new LPopExecutor(), SUPPORTED,
+      new Parameter().min(2).max(3, ERROR_SYNTAX).flags(WRITE, FAST)),
+
   /************* Server *****************/
   COMMAND(new COMMANDCommandExecutor(), SUPPORTED, new 
Parameter().min(1).firstKey(0).flags(RANDOM,
       LOADING, STALE)),
diff --git 
a/geode-for-redis/src/main/java/org/apache/geode/redis/internal/commands/executor/list/LPopExecutor.java
 
b/geode-for-redis/src/main/java/org/apache/geode/redis/internal/commands/executor/list/LPopExecutor.java
new file mode 100755
index 0000000..447ae32
--- /dev/null
+++ 
b/geode-for-redis/src/main/java/org/apache/geode/redis/internal/commands/executor/list/LPopExecutor.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional 
information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache 
License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the 
License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+package org.apache.geode.redis.internal.commands.executor.list;
+
+
+import static 
org.apache.geode.redis.internal.RedisConstants.ERROR_VALUE_MUST_BE_POSITIVE;
+import static org.apache.geode.redis.internal.netty.Coder.bytesToLong;
+import static org.apache.geode.redis.internal.netty.Coder.narrowLongToInt;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.geode.cache.Region;
+import org.apache.geode.redis.internal.commands.Command;
+import org.apache.geode.redis.internal.commands.executor.CommandExecutor;
+import org.apache.geode.redis.internal.commands.executor.RedisResponse;
+import org.apache.geode.redis.internal.data.RedisData;
+import org.apache.geode.redis.internal.data.RedisKey;
+import org.apache.geode.redis.internal.netty.ExecutionHandlerContext;
+
+public class LPopExecutor implements CommandExecutor {
+
+  @Override
+  public RedisResponse executeCommand(Command command, ExecutionHandlerContext 
context) {
+    List<byte[]> commandElems = command.getProcessedCommand();
+    boolean isCountPassed = false;
+    int popCount;
+
+    if (commandElems.size() == 3) {
+      isCountPassed = true;
+      try {
+        popCount = narrowLongToInt(bytesToLong(commandElems.get(2)));
+      } catch (NumberFormatException nex) {
+        return RedisResponse.error(ERROR_VALUE_MUST_BE_POSITIVE);
+      }
+      if (popCount < 0) {
+        return RedisResponse.error(ERROR_VALUE_MUST_BE_POSITIVE);
+      }
+    } else {
+      popCount = 1;
+    }
+
+    Region<RedisKey, RedisData> region = context.getRegion();
+    RedisKey key = command.getKey();
+    Collection<byte[]> popped = context.listLockedExecute(key, false,
+        list -> list.lpop(region, key, popCount));
+
+    if (popped.isEmpty() && !isCountPassed) {
+      return RedisResponse.nil();
+    }
+
+    if (!isCountPassed) {
+      return RedisResponse.bulkString(popped.iterator().next());
+    }
+
+    return RedisResponse.array(popped, true);
+  }
+}
diff --git 
a/geode-for-redis/src/main/java/org/apache/geode/redis/internal/commands/executor/list/LPushExecutor.java
 
b/geode-for-redis/src/main/java/org/apache/geode/redis/internal/commands/executor/list/LPushExecutor.java
new file mode 100755
index 0000000..2449c2b
--- /dev/null
+++ 
b/geode-for-redis/src/main/java/org/apache/geode/redis/internal/commands/executor/list/LPushExecutor.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license
+ * agreements. See the NOTICE file distributed with this work for additional 
information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache 
License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the 
License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software 
distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
KIND, either express
+ * or implied. See the License for the specific language governing permissions 
and limitations under
+ * the License.
+ */
+package org.apache.geode.redis.internal.commands.executor.list;
+
+import org.apache.geode.cache.Region;
+import org.apache.geode.redis.internal.commands.Command;
+import org.apache.geode.redis.internal.commands.executor.CommandExecutor;
+import org.apache.geode.redis.internal.commands.executor.RedisResponse;
+import org.apache.geode.redis.internal.data.RedisData;
+import org.apache.geode.redis.internal.data.RedisKey;
+import org.apache.geode.redis.internal.netty.ExecutionHandlerContext;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LPushExecutor implements CommandExecutor {
+
+  @Override
+  public RedisResponse executeCommand(Command command, ExecutionHandlerContext 
context) {
+    List<byte[]> commandElements = command.getProcessedCommand();
+    Region<RedisKey, RedisData> region = context.getRegion();
+    RedisKey key = command.getKey();
+
+    List<byte[]> elementsToAdd = new ArrayList<>(commandElements.subList(2, 
commandElements.size()));
+
+    long entriesAdded = context.listLockedExecute(key, false,
+        list -> list.lpush(elementsToAdd, region, key));
+
+    return RedisResponse.integer(entriesAdded);
+  }
+}
diff --git 
a/geode-for-redis/src/main/java/org/apache/geode/redis/internal/data/NullRedisList.java
 
b/geode-for-redis/src/main/java/org/apache/geode/redis/internal/data/NullRedisList.java
index 55a4b74..306b019 100644
--- 
a/geode-for-redis/src/main/java/org/apache/geode/redis/internal/data/NullRedisList.java
+++ 
b/geode-for-redis/src/main/java/org/apache/geode/redis/internal/data/NullRedisList.java
@@ -43,7 +43,7 @@ class NullRedisList extends RedisList {
 
   @Override
   public Collection<byte[]> lpop(Region<RedisKey, RedisData> region, RedisKey 
key, int popCount) {
-    return emptyList();
+    return null;
   }
 
   @Override
diff --git 
a/geode-for-redis/src/main/java/org/apache/geode/redis/internal/netty/ExecutionHandlerContext.java
 
b/geode-for-redis/src/main/java/org/apache/geode/redis/internal/netty/ExecutionHandlerContext.java
index 1011eb7..7c2de2c 100644
--- 
a/geode-for-redis/src/main/java/org/apache/geode/redis/internal/netty/ExecutionHandlerContext.java
+++ 
b/geode-for-redis/src/main/java/org/apache/geode/redis/internal/netty/ExecutionHandlerContext.java
@@ -57,6 +57,7 @@ import org.apache.geode.redis.internal.data.RedisDataType;
 import org.apache.geode.redis.internal.data.RedisDataTypeMismatchException;
 import org.apache.geode.redis.internal.data.RedisHash;
 import org.apache.geode.redis.internal.data.RedisKey;
+import org.apache.geode.redis.internal.data.RedisList;
 import org.apache.geode.redis.internal.data.RedisSet;
 import org.apache.geode.redis.internal.data.RedisSortedSet;
 import org.apache.geode.redis.internal.data.RedisString;
@@ -483,17 +484,25 @@ public class ExecutionHandlerContext extends 
ChannelInboundHandlerAdapter {
     return 
getRegionProvider().getTypedRedisData(RedisDataType.REDIS_SORTED_SET, key, 
updateStats);
   }
 
-
   public <R> R setLockedExecute(RedisKey key, boolean updateStats,
       FailableFunction<RedisSet, R> function) {
     return getRegionProvider().lockedExecute(key,
         () -> function.apply(getRedisSet(key, updateStats)));
   }
 
+  public <R> R listLockedExecute(RedisKey key, boolean updateStats,
+                                FailableFunction<RedisList, R> function) {
+    return getRegionProvider().lockedExecute(key,
+        () -> function.apply(getRedisList(key, updateStats)));
+  }
+
   public RedisSet getRedisSet(RedisKey key, boolean updateStats) {
     return getRegionProvider().getTypedRedisData(RedisDataType.REDIS_SET, key, 
updateStats);
   }
 
+  public RedisList getRedisList(RedisKey key, boolean updateStats) {
+    return getRegionProvider().getTypedRedisData(RedisDataType.REDIS_LIST, 
key, updateStats);
+  }
 
   public <R> R dataLockedExecute(RedisKey key, boolean updateStats,
       FailableFunction<RedisData, R> function) {

Reply via email to