geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kl...@apache.org
Subject [09/21] incubator-geode git commit: GEODE-1566: rename GeodeRedisServer and repackage redis code into org.apache.geode
Date Fri, 08 Jul 2016 18:21:17 GMT
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfd481e0/geode-core/src/main/java/org/apache/geode/redis/internal/executor/SortedSetQuery.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/redis/internal/executor/SortedSetQuery.java b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/SortedSetQuery.java
new file mode 100644
index 0000000..9981ac3
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/SortedSetQuery.java
@@ -0,0 +1,204 @@
+/*
+ * 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.executor;
+
+public enum SortedSetQuery {
+
+  ZCOUNTNINFI {
+    public String getQueryString(String fullpath) {
+      return "SELECT COUNT(*) FROM " + fullpath + ".values value WHERE value.score <= $1";
+    }
+  }, ZCOUNTNINF {
+    public String getQueryString(String fullpath) {
+      return "SELECT COUNT(*) FROM " + fullpath + ".values value WHERE value.score < $1";
+    }
+  }, ZCOUNTPINFI {
+    public String getQueryString(String fullpath) {
+      return "SELECT COUNT(*) FROM " + fullpath + ".values value WHERE value.score >= $1";
+    }
+  }, ZCOUNTPINF {
+    public String getQueryString(String fullpath) {
+      return "SELECT COUNT(*) FROM " + fullpath + ".values value WHERE value.score > $1";
+    }
+  }, ZCOUNTSTI {
+    public String getQueryString(String fullpath) {
+      return "SELECT COUNT(*) FROM " + fullpath + ".values value WHERE value.score >= $1 AND value.score < $2";
+    }
+  }, ZCOUNTSTISI {
+    public String getQueryString(String fullpath) {
+      return "SELECT COUNT(*) FROM " + fullpath + ".values value WHERE value.score >= $1 AND value.score <= $2";
+    }
+  }, ZCOUNTSI {
+    public String getQueryString(String fullpath) {
+      return "SELECT COUNT(*) FROM " + fullpath + ".values value WHERE value.score > $1 AND value.score <= $2";
+    }
+  }, ZCOUNT {
+    public String getQueryString(String fullpath) {
+      return "SELECT COUNT(*) FROM " + fullpath + ".values value WHERE value.score > $1 AND value.score < $2";
+    }
+  }, ZLEXCOUNTNINFI {
+    public String getQueryString(String fullpath) {
+      return "SELECT COUNT(*) FROM " + fullpath + ".keySet key WHERE key.compareTo($1) <= 0";
+    }
+  }, ZLEXCOUNTNINF {
+    public String getQueryString(String fullpath) {
+      return "SELECT COUNT(*) FROM " + fullpath + ".keySet key WHERE key.compareTo($1) < 0";
+    }
+  }, ZLEXCOUNTPINFI {
+    public String getQueryString(String fullpath) {
+      return "SELECT COUNT(*) FROM " + fullpath + ".keySet key WHERE key.compareTo($1) >= 0";
+    }
+  }, ZLEXCOUNTPINF {
+    public String getQueryString(String fullpath) {
+      return "SELECT COUNT(*) FROM " + fullpath + ".keySet key WHERE key.compareTo($1) > 0";
+    }
+  }, ZLEXCOUNTSTI {
+    public String getQueryString(String fullpath) {
+      return "SELECT COUNT(*) FROM " + fullpath + ".keySet key WHERE key.compareTo($1) >= 0 AND key.compareTo($2) < 0";
+    }
+  }, ZLEXCOUNTSTISI {
+    public String getQueryString(String fullpath) {
+      return "SELECT COUNT(*) FROM " + fullpath + ".keySet key WHERE key.compareTo($1) >= 0 AND key.compareTo($2) <= 0";
+    }
+  }, ZLEXCOUNTSI {
+    public String getQueryString(String fullpath) {
+      return "SELECT COUNT(*) FROM " + fullpath + ".keySet key WHERE key.compareTo($1) > 0 AND key.compareTo($2) <= 0";
+    }
+  }, ZLEXCOUNT {
+    public String getQueryString(String fullpath) {
+      return "SELECT COUNT(*) FROM " + fullpath + ".keySet key WHERE key.compareTo($1) > 0 AND key.compareTo($2) < 0";
+    }
+  }, ZRANGEBYLEXNINFI {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT * FROM " + fullpath + ".keySet key WHERE key.compareTo($1) <= 0 ORDER BY key asc LIMIT $2";
+    }
+  }, ZRANGEBYLEXNINF {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT * FROM " + fullpath + ".keySet key WHERE key.compareTo($1) < 0 ORDER BY key asc LIMIT $2";
+    }
+  }, ZRANGEBYLEXPINFI {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT * FROM " + fullpath + ".keySet key WHERE key.compareTo($1) >= 0 ORDER BY key asc LIMIT $2";
+    }
+  }, ZRANGEBYLEXPINF {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT * FROM " + fullpath + ".keySet key WHERE key.compareTo($1) > 0 ORDER BY key asc LIMIT $2";
+    }
+  }, ZRANGEBYLEXSTI {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT * FROM " + fullpath + ".keySet key WHERE key.compareTo($1) >= 0 AND key.compareTo($2) < 0 ORDER BY key asc LIMIT $3";
+    }
+  }, ZRANGEBYLEXSTISI {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT * FROM " + fullpath + ".keySet key WHERE key.compareTo($1) >= 0 AND key.compareTo($2) <= 0 ORDER BY key asc LIMIT $3";
+    }
+  }, ZRANGEBYLEXSI {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT * FROM " + fullpath + ".keySet key WHERE key.compareTo($1) > 0 AND key.compareTo($2) <= 0 ORDER BY key asc LIMIT $3";
+    }
+  }, ZRANGEBYLEX {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT * FROM " + fullpath + ".keySet key WHERE key.compareTo($1) > 0 AND key.compareTo($2) < 0 ORDER BY key asc LIMIT $3";
+    }
+  }, ZREMRANGEBYRANK {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT entry.key, entry.value FROM " + fullpath + ".entrySet entry ORDER BY entry.value asc LIMIT $1";
+    }
+  }, ZRBSNINFI {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT entry.key, entry.value FROM " + fullpath + ".entrySet entry WHERE value.score <= $1 ORDER BY entry.value asc LIMIT $2";
+    }
+  }, ZRBSNINF {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT entry.key, entry.value FROM " + fullpath + ".entrySet entry WHERE entry.value.score < $1 ORDER BY entry.value asc LIMIT $2";
+    }
+  }, ZRBSPINFI {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT entry.key, entry.value FROM " + fullpath + ".entrySet entry WHERE entry.value.score >= $1 ORDER BY entry.value asc LIMIT $2";
+    }
+  }, ZRBSPINF {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT entry.key, entry.value FROM " + fullpath + ".entrySet entry WHERE entry.value.score > $1 ORDER BY entry.value asc LIMIT $2";
+    }
+  }, ZRBSSTISI {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT entry.key, entry.value FROM " + fullpath + ".entrySet entry WHERE entry.value.score >= $1 AND entry.value.score <= $2 ORDER BY entry.value asc LIMIT $3";
+    }
+  }, ZRBSSTI {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT entry.key, entry.value FROM " + fullpath + ".entrySet entry WHERE entry.value.score >= $1 AND entry.value.score < $2 ORDER BY entry.value asc LIMIT $3";
+    }
+  }, ZRBSSI {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT entry.key, entry.value FROM " + fullpath + ".entrySet entry WHERE entry.value.score > $1 AND entry.value.score <= $2 ORDER BY entry.value asc LIMIT $3";
+    }
+  }, ZRBS {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT entry.key, entry.value FROM " + fullpath + ".entrySet entry WHERE entry.value.score > $1 AND entry.value.score < $2 ORDER BY entry.value asc LIMIT $3";
+    }
+  }, ZREVRBSNINFI {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT entry.key, entry.value FROM " + fullpath + ".entrySet entry WHERE value <= $1 ORDER BY entry.value desc, entry.key desc LIMIT $2";
+    }
+  }, ZREVRBSNINF {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT entry.key, entry.value FROM " + fullpath + ".entrySet entry WHERE entry.value.score < $1 ORDER BY entry.value desc, entry.key desc LIMIT $2";
+    }
+  }, ZREVRBSPINFI {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT entry.key, entry.value FROM " + fullpath + ".entrySet entry WHERE entry.value.score >= $1 ORDER BY entry.value desc, entry.key desc LIMIT $2";
+    }
+  }, ZREVRBSPINF {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT entry.key, entry.value FROM " + fullpath + ".entrySet entry WHERE entry.value.score > $1 ORDER BY entry.value desc, entry.key desc LIMIT $2";
+    }
+  }, ZREVRBSSTISI {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT entry.key, entry.value FROM " + fullpath + ".entrySet entry WHERE entry.value.score >= $1 AND entry.value.score <= $2 ORDER BY entry.value desc, entry.key desc LIMIT $3";
+    }
+  }, ZREVRBSSTI {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT entry.key, entry.value FROM " + fullpath + ".entrySet entry WHERE entry.value.score >= $1 AND entry.value.score < $2 ORDER BY entry.value desc, entry.key desc LIMIT $3";
+    }
+  }, ZREVRBSSI {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT entry.key, entry.value FROM " + fullpath + ".entrySet entry WHERE entry.value.score > $1 AND entry.value.score <= $2 ORDER BY entry.value desc, entry.key desc LIMIT $3";
+    }
+  }, ZREVRBS {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT entry.key, entry.value FROM " + fullpath + ".entrySet entry WHERE entry.value.score > $1 AND entry.value.score < $2 ORDER BY entry.value desc, entry.key desc LIMIT $3";
+    }
+  }, ZREVRANGE {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT entry.key, entry.value FROM " + fullpath + ".entrySet entry ORDER BY entry.value asc, entry.key asc LIMIT $1";
+    }
+  }, ZRANGE {
+    public String getQueryString(String fullpath) {
+      return "SELECT DISTINCT entry.key, entry.value FROM " + fullpath + ".entrySet entry ORDER BY entry.value desc, entry.key desc LIMIT $1";
+    }
+  }, ZRANK {
+    public String getQueryString(String fullpath) {
+      return "SELECT COUNT(*) FROM " + fullpath + ".entrySet entry WHERE entry.value < $1 OR (entry.value = $2 AND entry.key.compareTo($3) < 0)";
+    }
+  }, ZREVRANK {
+    public String getQueryString(String fullpath) {
+      return "SELECT COUNT(*) FROM " + fullpath + ".entrySet entry WHERE entry.value > $1 OR (entry.value = $2 AND entry.key.compareTo($3) > 0)";
+    }
+  };
+
+  public abstract String getQueryString(String fullpath);
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfd481e0/geode-core/src/main/java/org/apache/geode/redis/internal/executor/TTLExecutor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/redis/internal/executor/TTLExecutor.java b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/TTLExecutor.java
new file mode 100755
index 0000000..a271a56
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/TTLExecutor.java
@@ -0,0 +1,77 @@
+/*
+ * 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.executor;
+
+import java.util.List;
+
+import org.apache.geode.redis.internal.ByteArrayWrapper;
+import org.apache.geode.redis.internal.Coder;
+import org.apache.geode.redis.internal.Command;
+import org.apache.geode.redis.internal.ExecutionHandlerContext;
+import org.apache.geode.redis.internal.Extendable;
+import org.apache.geode.redis.internal.RedisConstants.ArityDef;
+import org.apache.geode.redis.internal.RedisDataType;
+import org.apache.geode.redis.internal.RegionProvider;
+
+public class TTLExecutor extends AbstractExecutor implements Extendable {
+
+  private final int NOT_EXISTS = -2;
+  
+  private final int NO_TIMEOUT = -1;
+
+  @Override
+  public void executeCommand(Command command, ExecutionHandlerContext context) {
+    List<byte[]> commandElems = command.getProcessedCommand();
+
+    if (commandElems.size() < 2) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), getArgsError()));
+      return;
+    }
+
+    ByteArrayWrapper key = command.getKey();
+    RegionProvider rC = context.getRegionProvider();
+    boolean exists = false;
+    RedisDataType val = rC.getRedisDataType(key);
+    if (val != null)
+      exists = true;
+
+    if (!exists) {
+      command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), NOT_EXISTS));
+      return;
+    }
+    long ttl = rC.getExpirationDelayMillis(key);
+    
+    if (ttl == 0L) {
+      command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), NO_TIMEOUT));
+      return;
+    }
+    
+    if(!timeUnitMillis())
+      ttl = ttl / millisInSecond;
+
+    command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), ttl));
+  }
+
+  protected boolean timeUnitMillis() {
+    return false;
+  }
+
+  @Override
+  public String getArgsError() {
+    return ArityDef.TTL;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfd481e0/geode-core/src/main/java/org/apache/geode/redis/internal/executor/TimeExecutor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/redis/internal/executor/TimeExecutor.java b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/TimeExecutor.java
new file mode 100755
index 0000000..f1cdb3f
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/TimeExecutor.java
@@ -0,0 +1,51 @@
+/*
+ * 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.executor;
+
+import io.netty.buffer.ByteBuf;
+
+import org.apache.geode.redis.internal.Coder;
+import org.apache.geode.redis.internal.Command;
+import org.apache.geode.redis.internal.ExecutionHandlerContext;
+
+public class TimeExecutor extends AbstractExecutor {
+
+  @Override
+  public void executeCommand(Command command, ExecutionHandlerContext context) {
+    long timeStamp = System.currentTimeMillis();
+    long seconds = timeStamp / 1000;
+    long microSeconds = (timeStamp - (seconds * 1000)) * 1000;
+    byte[] secAr = Coder.longToBytes(seconds);
+    byte[] micAr = Coder.longToBytes(microSeconds);
+
+    ByteBuf response = context.getByteBufAllocator().buffer(50);
+    response.writeByte(Coder.ARRAY_ID);
+    response.writeByte(50); // #2
+    response.writeBytes(Coder.CRLFar);
+    response.writeByte(Coder.BULK_STRING_ID);
+    response.writeBytes(Coder.intToBytes(secAr.length));
+    response.writeBytes(Coder.CRLFar);
+    response.writeBytes(secAr);
+    response.writeBytes(Coder.CRLFar);
+    response.writeByte(Coder.BULK_STRING_ID);
+    response.writeBytes(Coder.intToBytes(micAr.length));
+    response.writeBytes(Coder.CRLFar);
+    response.writeBytes(micAr);
+    response.writeBytes(Coder.CRLFar);
+    command.setResponse(response);    
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfd481e0/geode-core/src/main/java/org/apache/geode/redis/internal/executor/TypeExecutor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/redis/internal/executor/TypeExecutor.java b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/TypeExecutor.java
new file mode 100755
index 0000000..04e924b
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/TypeExecutor.java
@@ -0,0 +1,48 @@
+/*
+ * 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.executor;
+
+import java.util.List;
+
+import org.apache.geode.redis.internal.ByteArrayWrapper;
+import org.apache.geode.redis.internal.Coder;
+import org.apache.geode.redis.internal.Command;
+import org.apache.geode.redis.internal.ExecutionHandlerContext;
+import org.apache.geode.redis.internal.RedisConstants.ArityDef;
+import org.apache.geode.redis.internal.RedisDataType;
+
+public class TypeExecutor extends AbstractExecutor {
+
+  @Override
+  public void executeCommand(Command command, ExecutionHandlerContext context) {
+    List<byte[]> commandElems = command.getProcessedCommand();
+    if (commandElems.size() < 2) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ArityDef.TYPE));
+      return;
+    }
+
+    ByteArrayWrapper key = command.getKey();
+
+    RedisDataType type = context.getRegionProvider().getRedisDataType(key);
+
+    if (type == null)
+      command.setResponse(Coder.getBulkStringResponse(context.getByteBufAllocator(), "none"));
+    else 
+      command.setResponse(Coder.getBulkStringResponse(context.getByteBufAllocator(), type.toString()));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfd481e0/geode-core/src/main/java/org/apache/geode/redis/internal/executor/UnkownExecutor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/redis/internal/executor/UnkownExecutor.java b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/UnkownExecutor.java
new file mode 100755
index 0000000..0322922
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/UnkownExecutor.java
@@ -0,0 +1,31 @@
+/*
+ * 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.executor;
+
+import org.apache.geode.redis.internal.Coder;
+import org.apache.geode.redis.internal.Command;
+import org.apache.geode.redis.internal.ExecutionHandlerContext;
+import org.apache.geode.redis.internal.RedisConstants;
+
+public class UnkownExecutor extends AbstractExecutor {
+  
+  @Override
+  public void executeCommand(Command command, ExecutionHandlerContext context) {
+    command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), RedisConstants.ERROR_UNKOWN_COMMAND));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfd481e0/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HDelExecutor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HDelExecutor.java b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HDelExecutor.java
new file mode 100755
index 0000000..e64d90b
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HDelExecutor.java
@@ -0,0 +1,67 @@
+/*
+ * 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.executor.hash;
+
+import java.util.List;
+
+import com.gemstone.gemfire.cache.Region;
+import org.apache.geode.redis.internal.ByteArrayWrapper;
+import org.apache.geode.redis.internal.Command;
+import org.apache.geode.redis.internal.ExecutionHandlerContext;
+import org.apache.geode.redis.internal.RedisDataType;
+import org.apache.geode.redis.internal.Coder;
+import org.apache.geode.redis.internal.RedisConstants.ArityDef;
+
+public class HDelExecutor extends HashExecutor {
+
+  private final int START_FIELDS_INDEX = 2;
+
+  @Override
+  public void executeCommand(Command command, ExecutionHandlerContext context) {
+    List<byte[]> commandElems = command.getProcessedCommand();
+
+    if (commandElems.size() < 3) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ArityDef.HDEL));
+      return;
+    }
+
+    int numDeleted = 0;
+    
+    ByteArrayWrapper key = command.getKey();
+
+    checkDataType(key, RedisDataType.REDIS_HASH, context);
+    Region<ByteArrayWrapper, ByteArrayWrapper> keyRegion = getRegion(context, key);
+
+    if (keyRegion == null) {
+      command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), numDeleted));
+      return;
+    }
+
+    
+    for (int i = START_FIELDS_INDEX; i < commandElems.size(); i++) {
+      ByteArrayWrapper field = new ByteArrayWrapper(commandElems.get(i));
+      Object oldValue = keyRegion.remove(field);
+      if (oldValue != null)
+        numDeleted++;
+    }
+    if (keyRegion.isEmpty()) {
+      context.getRegionProvider().removeKey(key, RedisDataType.REDIS_HASH);
+    }
+    command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), numDeleted));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfd481e0/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HExistsExecutor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HExistsExecutor.java b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HExistsExecutor.java
new file mode 100755
index 0000000..55016c5
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HExistsExecutor.java
@@ -0,0 +1,66 @@
+/*
+ * 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.executor.hash;
+
+import java.util.List;
+
+import com.gemstone.gemfire.cache.Region;
+import org.apache.geode.redis.internal.ByteArrayWrapper;
+import org.apache.geode.redis.internal.Command;
+import org.apache.geode.redis.internal.ExecutionHandlerContext;
+import org.apache.geode.redis.internal.RedisDataType;
+import org.apache.geode.redis.internal.Coder;
+import org.apache.geode.redis.internal.RedisConstants.ArityDef;
+
+public class HExistsExecutor extends HashExecutor {
+
+  private final int NOT_EXISTS = 0;
+
+  private final int EXISTS = 1;
+
+  @Override
+  public void executeCommand(Command command, ExecutionHandlerContext context) {
+    List<byte[]> commandElems = command.getProcessedCommand();
+
+    if (commandElems.size() < 3) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ArityDef.HEXISTS));
+      return;
+    }
+
+    ByteArrayWrapper key = command.getKey();
+
+    checkDataType(key, RedisDataType.REDIS_HASH, context);
+    Region<ByteArrayWrapper, ByteArrayWrapper> keyRegion = getRegion(context, key);
+
+    if (keyRegion == null) {
+      command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), NOT_EXISTS));
+      return;
+    }
+    
+    byte[] byteField = commandElems.get(FIELD_INDEX);
+    ByteArrayWrapper field = new ByteArrayWrapper(byteField);
+    
+    boolean hasField = keyRegion.containsKey(field);
+
+    if (hasField)
+      command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), EXISTS));
+    else
+      command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), NOT_EXISTS));
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfd481e0/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HGetAllExecutor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HGetAllExecutor.java b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HGetAllExecutor.java
new file mode 100755
index 0000000..b4cc6e2
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HGetAllExecutor.java
@@ -0,0 +1,63 @@
+/*
+ * 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.executor.hash;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import com.gemstone.gemfire.cache.Region;
+import org.apache.geode.redis.internal.ByteArrayWrapper;
+import org.apache.geode.redis.internal.Coder;
+import org.apache.geode.redis.internal.Command;
+import org.apache.geode.redis.internal.ExecutionHandlerContext;
+import org.apache.geode.redis.internal.RedisConstants.ArityDef;
+import org.apache.geode.redis.internal.RedisDataType;
+
+public class HGetAllExecutor extends HashExecutor {
+
+  @Override
+  public void executeCommand(Command command, ExecutionHandlerContext context) {
+    List<byte[]> commandElems = command.getProcessedCommand();
+
+    if (commandElems.size() < 2) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ArityDef.HGETALL));
+      return;
+    }
+
+    ByteArrayWrapper key = command.getKey();
+
+    checkDataType(key, RedisDataType.REDIS_HASH, context);
+    Region<ByteArrayWrapper, ByteArrayWrapper> keyRegion = getRegion(context, key);
+
+    if (keyRegion == null) {
+      command.setResponse(Coder.getEmptyArrayResponse(context.getByteBufAllocator()));
+      return;
+    }
+
+    Collection<Map.Entry<ByteArrayWrapper,ByteArrayWrapper>> entries = new ArrayList(keyRegion.entrySet()); // This creates a CopyOnRead behavior
+   
+   if (entries.isEmpty()) {
+     command.setResponse(Coder.getEmptyArrayResponse(context.getByteBufAllocator()));
+     return;
+   }
+
+   command.setResponse(Coder.getKeyValArrayResponse(context.getByteBufAllocator(), entries));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfd481e0/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HGetExecutor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HGetExecutor.java b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HGetExecutor.java
new file mode 100755
index 0000000..ca245f0
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HGetExecutor.java
@@ -0,0 +1,62 @@
+/*
+ * 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.executor.hash;
+
+import java.util.List;
+
+import com.gemstone.gemfire.cache.Region;
+import org.apache.geode.redis.internal.ByteArrayWrapper;
+import org.apache.geode.redis.internal.Command;
+import org.apache.geode.redis.internal.ExecutionHandlerContext;
+import org.apache.geode.redis.internal.RedisDataType;
+import org.apache.geode.redis.internal.Coder;
+import org.apache.geode.redis.internal.RedisConstants.ArityDef;
+
+public class HGetExecutor extends HashExecutor {
+
+  @Override
+  public void executeCommand(Command command, ExecutionHandlerContext context) {
+    List<byte[]> commandElems = command.getProcessedCommand();
+
+    if (commandElems.size() < 3) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ArityDef.HGET));
+      return;
+    }
+
+    ByteArrayWrapper key = command.getKey();
+
+    checkDataType(key, RedisDataType.REDIS_HASH, context);
+    Region<ByteArrayWrapper, ByteArrayWrapper> keyRegion = getRegion(context, key);
+
+    if (keyRegion == null) {
+      command.setResponse(Coder.getNilResponse(context.getByteBufAllocator()));
+      return;
+    }
+
+    byte[] byteField = commandElems.get(FIELD_INDEX);
+    ByteArrayWrapper field = new ByteArrayWrapper(byteField);
+
+    ByteArrayWrapper valueWrapper = keyRegion.get(field);
+
+    if (valueWrapper != null) {
+      command.setResponse(Coder.getBulkStringResponse(context.getByteBufAllocator(), valueWrapper.toBytes()));
+    } else
+      command.setResponse(Coder.getNilResponse(context.getByteBufAllocator()));
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfd481e0/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HIncrByExecutor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HIncrByExecutor.java b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HIncrByExecutor.java
new file mode 100755
index 0000000..5d3d7b7
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HIncrByExecutor.java
@@ -0,0 +1,109 @@
+/*
+ * 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.executor.hash;
+
+import java.util.List;
+
+import com.gemstone.gemfire.cache.Region;
+import org.apache.geode.redis.internal.ByteArrayWrapper;
+import org.apache.geode.redis.internal.Coder;
+import org.apache.geode.redis.internal.Command;
+import org.apache.geode.redis.internal.ExecutionHandlerContext;
+import org.apache.geode.redis.internal.RedisDataType;
+import org.apache.geode.redis.internal.RedisConstants.ArityDef;
+
+public class HIncrByExecutor extends HashExecutor {
+
+  private final String ERROR_FIELD_NOT_USABLE = "The value at this field is not an integer";
+
+  private final String ERROR_INCREMENT_NOT_USABLE = "The increment on this key must be numeric";
+
+  private final String ERROR_OVERFLOW = "This incrementation cannot be performed due to overflow";
+
+  private final int FIELD_INDEX = 2;
+
+  private final int INCREMENT_INDEX = 3;
+
+  @Override
+  public void executeCommand(Command command, ExecutionHandlerContext context) {
+    List<byte[]> commandElems = command.getProcessedCommand();
+
+    if (commandElems.size() < 4) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ArityDef.HINCRBY));
+      return;
+    }
+
+    byte[] incrArray = commandElems.get(INCREMENT_INDEX);
+    long increment;
+
+    try {
+      increment = Coder.bytesToLong(incrArray);
+    } catch (NumberFormatException e) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ERROR_INCREMENT_NOT_USABLE));
+      return;
+    }
+
+    ByteArrayWrapper key = command.getKey();
+
+    Region<ByteArrayWrapper, ByteArrayWrapper> keyRegion = getOrCreateRegion(context, key, RedisDataType.REDIS_HASH);
+
+    byte[] byteField = commandElems.get(FIELD_INDEX);
+    ByteArrayWrapper field = new ByteArrayWrapper(byteField);
+
+    /*
+     * Put incrememnt as value if field doesn't exist
+     */
+
+    ByteArrayWrapper oldValue = keyRegion.get(field);
+
+    if (oldValue == null) {
+      keyRegion.put(field, new ByteArrayWrapper(incrArray));
+      command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), increment));
+      return;
+    }
+
+    /*
+     * If the field did exist then increment the field
+     */
+
+    long value;
+
+    try {
+      value = Long.parseLong(oldValue.toString());
+    } catch (NumberFormatException e) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ERROR_FIELD_NOT_USABLE));
+      return;
+    }
+
+    /*
+     * Check for overflow
+     */
+    if ((value >= 0 && increment > (Long.MAX_VALUE - value)) || (value <= 0 && increment < (Long.MIN_VALUE - value))) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ERROR_OVERFLOW));
+      return;
+    }
+
+    value += increment;
+    //String newValue = String.valueOf(value);
+
+    keyRegion.put(field, new ByteArrayWrapper(Coder.longToBytes(value)));
+
+    command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), value));
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfd481e0/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HIncrByFloatExecutor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HIncrByFloatExecutor.java b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HIncrByFloatExecutor.java
new file mode 100755
index 0000000..b652434
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HIncrByFloatExecutor.java
@@ -0,0 +1,99 @@
+/*
+ * 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.executor.hash;
+
+import java.util.List;
+
+import com.gemstone.gemfire.cache.Region;
+import org.apache.geode.redis.internal.ByteArrayWrapper;
+import org.apache.geode.redis.internal.Command;
+import org.apache.geode.redis.internal.ExecutionHandlerContext;
+import org.apache.geode.redis.internal.RedisDataType;
+import org.apache.geode.redis.internal.Coder;
+import org.apache.geode.redis.internal.RedisConstants.ArityDef;
+
+public class HIncrByFloatExecutor extends HashExecutor {
+
+  private final String ERROR_FIELD_NOT_USABLE = "The value at this field cannot be incremented numerically because it is not a float";
+
+  private final String ERROR_INCREMENT_NOT_USABLE = "The increment on this key must be floating point numeric";
+
+  private final int FIELD_INDEX = 2;
+
+  private final int INCREMENT_INDEX = 3;
+
+  @Override
+  public void executeCommand(Command command, ExecutionHandlerContext context) {
+    List<byte[]> commandElems = command.getProcessedCommand();
+
+    if (commandElems.size() < 4) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ArityDef.HINCRBYFLOAT));
+      return;
+    }
+
+    byte[] incrArray = commandElems.get(INCREMENT_INDEX);
+    Double increment;
+
+    try {
+      increment = Coder.bytesToDouble(incrArray);
+    } catch (NumberFormatException e) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ERROR_INCREMENT_NOT_USABLE));
+      return;
+    }
+
+    ByteArrayWrapper key = command.getKey();
+
+    Region<ByteArrayWrapper, ByteArrayWrapper> keyRegion = getOrCreateRegion(context, key, RedisDataType.REDIS_HASH);
+
+    byte[] byteField = commandElems.get(FIELD_INDEX);
+    ByteArrayWrapper field = new ByteArrayWrapper(byteField);
+
+    /*
+     * Put incrememnt as value if field doesn't exist
+     */
+
+    ByteArrayWrapper oldValue = keyRegion.get(field);
+
+    if (oldValue == null) {
+      keyRegion.put(field, new ByteArrayWrapper(incrArray));
+      command.setResponse(Coder.getBulkStringResponse(context.getByteBufAllocator(), increment));
+      return;
+    }
+
+    /*
+     * If the field did exist then increment the field
+     */
+    String valueS = oldValue.toString();
+    if (valueS.contains(" ")) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ERROR_FIELD_NOT_USABLE));
+      return;
+    }
+    Double value;
+
+    try {
+      value = Coder.stringToDouble(valueS);
+    } catch (NumberFormatException e) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ERROR_FIELD_NOT_USABLE));
+      return;
+    }
+
+    value += increment;
+    keyRegion.put(field, new ByteArrayWrapper(Coder.doubleToBytes(value)));
+    command.setResponse(Coder.getBulkStringResponse(context.getByteBufAllocator(), value));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfd481e0/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HKeysExecutor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HKeysExecutor.java b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HKeysExecutor.java
new file mode 100755
index 0000000..54c3519
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HKeysExecutor.java
@@ -0,0 +1,63 @@
+/*
+ * 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.executor.hash;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import com.gemstone.gemfire.cache.Region;
+import org.apache.geode.redis.internal.ByteArrayWrapper;
+import org.apache.geode.redis.internal.Coder;
+import org.apache.geode.redis.internal.Command;
+import org.apache.geode.redis.internal.ExecutionHandlerContext;
+import org.apache.geode.redis.internal.RedisConstants.ArityDef;
+import org.apache.geode.redis.internal.RedisDataType;
+
+public class HKeysExecutor extends HashExecutor {
+
+  @Override
+  public void executeCommand(Command command, ExecutionHandlerContext context) {
+    List<byte[]> commandElems = command.getProcessedCommand();
+
+    if (commandElems.size() < 2) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ArityDef.HKEYS));
+      return;
+    }
+
+    ByteArrayWrapper key = command.getKey();
+
+    checkDataType(key, RedisDataType.REDIS_HASH, context);
+    Region<ByteArrayWrapper, ByteArrayWrapper> keyRegion = getRegion(context, key);
+
+    if (keyRegion == null) {
+      command.setResponse(Coder.getEmptyArrayResponse(context.getByteBufAllocator()));
+      return;
+    }
+
+   Set<ByteArrayWrapper> keys = new HashSet(keyRegion.keySet());
+   
+   if (keys.isEmpty()) {
+     command.setResponse(Coder.getEmptyArrayResponse(context.getByteBufAllocator()));
+     return;
+   }
+   
+   // String response = getBulkStringArrayResponse(keys);
+
+   command.setResponse(Coder.getBulkStringArrayResponse(context.getByteBufAllocator(), keys));
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfd481e0/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HLenExecutor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HLenExecutor.java b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HLenExecutor.java
new file mode 100755
index 0000000..2601091
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HLenExecutor.java
@@ -0,0 +1,57 @@
+/*
+ * 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.executor.hash;
+
+import java.util.List;
+
+import com.gemstone.gemfire.cache.Region;
+import org.apache.geode.redis.internal.ByteArrayWrapper;
+import org.apache.geode.redis.internal.Command;
+import org.apache.geode.redis.internal.ExecutionHandlerContext;
+import org.apache.geode.redis.internal.RedisDataType;
+import org.apache.geode.redis.internal.Coder;
+import org.apache.geode.redis.internal.RedisConstants.ArityDef;
+
+public class HLenExecutor extends HashExecutor {
+
+  private final int NOT_EXISTS = 0;
+
+  @Override
+  public void executeCommand(Command command, ExecutionHandlerContext context) {
+    List<byte[]> commandElems = command.getProcessedCommand();
+
+    if (commandElems.size() < 2) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ArityDef.HLEN));
+      return;
+    }
+
+    ByteArrayWrapper key = command.getKey();
+    checkDataType(key, RedisDataType.REDIS_HASH, context);
+
+    Region<ByteArrayWrapper, ByteArrayWrapper> keyRegion = getRegion(context, key);
+
+    if (keyRegion == null) {
+      command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), NOT_EXISTS));
+      return;
+    }
+
+    final int regionSize = keyRegion.size();
+
+    command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), regionSize));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfd481e0/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HMGetExecutor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HMGetExecutor.java b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HMGetExecutor.java
new file mode 100755
index 0000000..702ac13
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HMGetExecutor.java
@@ -0,0 +1,72 @@
+/*
+ * 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.executor.hash;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import com.gemstone.gemfire.cache.Region;
+import org.apache.geode.redis.internal.ByteArrayWrapper;
+import org.apache.geode.redis.internal.Coder;
+import org.apache.geode.redis.internal.Command;
+import org.apache.geode.redis.internal.ExecutionHandlerContext;
+import org.apache.geode.redis.internal.RedisDataType;
+import org.apache.geode.redis.internal.RedisConstants.ArityDef;
+
+public class HMGetExecutor extends HashExecutor {
+
+  @Override
+  public void executeCommand(Command command, ExecutionHandlerContext context) {
+    List<byte[]> commandElems = command.getProcessedCommand();
+
+    if (commandElems.size() < 3) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ArityDef.HMGET));
+      return;
+    }
+
+    ByteArrayWrapper key = command.getKey();
+
+    Region<ByteArrayWrapper, ByteArrayWrapper> keyRegion = getRegion(context, key);
+    checkDataType(key, RedisDataType.REDIS_HASH, context);
+
+    if (keyRegion == null) {
+      command.setResponse(Coder.getArrayOfNils(context.getByteBufAllocator(), commandElems.size() - 2));
+      return;
+    }
+
+    ArrayList<ByteArrayWrapper> fields = new ArrayList<ByteArrayWrapper>();
+    for (int i = 2; i < commandElems.size(); i++) {
+      byte[] fieldArray = commandElems.get(i);
+      ByteArrayWrapper field = new ByteArrayWrapper(fieldArray);
+      fields.add(field);
+    }
+
+    Map<ByteArrayWrapper, ByteArrayWrapper> results = keyRegion.getAll(fields);
+
+    ArrayList<ByteArrayWrapper> values = new ArrayList<ByteArrayWrapper>();
+
+    /*
+     * This is done to preserve order in the output
+     */
+    for (ByteArrayWrapper field : fields)
+      values.add(results.get(field));
+
+    command.setResponse(Coder.getBulkStringArrayResponse(context.getByteBufAllocator(), values));
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfd481e0/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HMSetExecutor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HMSetExecutor.java b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HMSetExecutor.java
new file mode 100755
index 0000000..a7cdffd
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HMSetExecutor.java
@@ -0,0 +1,62 @@
+/*
+ * 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.executor.hash;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.gemstone.gemfire.cache.Region;
+import org.apache.geode.redis.internal.ByteArrayWrapper;
+import org.apache.geode.redis.internal.Command;
+import org.apache.geode.redis.internal.ExecutionHandlerContext;
+import org.apache.geode.redis.internal.RedisDataType;
+import org.apache.geode.redis.internal.Coder;
+import org.apache.geode.redis.internal.RedisConstants.ArityDef;
+
+public class HMSetExecutor extends HashExecutor {
+
+  private final String SUCCESS = "OK";
+  
+  @Override
+  public void executeCommand(Command command, ExecutionHandlerContext context) {
+    List<byte[]> commandElems = command.getProcessedCommand();
+
+    if (commandElems.size() < 3 || commandElems.size() % 2 == 1) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ArityDef.HMSET));
+      return;
+    }
+
+    ByteArrayWrapper key = command.getKey();
+
+    Region<ByteArrayWrapper, ByteArrayWrapper> keyRegion = getOrCreateRegion(context, key, RedisDataType.REDIS_HASH);
+    
+    Map<ByteArrayWrapper, ByteArrayWrapper> map = new HashMap<ByteArrayWrapper, ByteArrayWrapper>();
+    for (int i = 2; i < commandElems.size(); i += 2) {
+      byte[] fieldArray = commandElems.get(i);
+      ByteArrayWrapper field = new ByteArrayWrapper(fieldArray);
+      byte[] value = commandElems.get(i +1);
+      map.put(field, new ByteArrayWrapper(value));
+    }
+    
+    keyRegion.putAll(map);
+
+    command.setResponse(Coder.getSimpleStringResponse(context.getByteBufAllocator(), SUCCESS));
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfd481e0/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HScanExecutor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HScanExecutor.java b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HScanExecutor.java
new file mode 100755
index 0000000..2e6f2bc
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HScanExecutor.java
@@ -0,0 +1,163 @@
+/*
+ * 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.executor.hash;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import com.gemstone.gemfire.cache.Region;
+import org.apache.geode.redis.internal.ByteArrayWrapper;
+import org.apache.geode.redis.internal.Coder;
+import org.apache.geode.redis.internal.Command;
+import org.apache.geode.redis.internal.ExecutionHandlerContext;
+import org.apache.geode.redis.internal.RedisConstants;
+import org.apache.geode.redis.internal.RedisConstants.ArityDef;
+import org.apache.geode.redis.internal.RedisDataType;
+import org.apache.geode.redis.internal.executor.AbstractScanExecutor;
+
+public class HScanExecutor extends AbstractScanExecutor {
+
+  @Override
+  public void executeCommand(Command command, ExecutionHandlerContext context) {
+    List<byte[]> commandElems = command.getProcessedCommand();
+
+    if (commandElems.size() < 3) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ArityDef.HSCAN));
+      return;
+    }
+
+    ByteArrayWrapper key = command.getKey();
+    @SuppressWarnings("unchecked")
+    Region<ByteArrayWrapper, ByteArrayWrapper> keyRegion = (Region<ByteArrayWrapper, ByteArrayWrapper>) context.getRegionProvider().getRegion(key);
+    checkDataType(key, RedisDataType.REDIS_HASH, context);
+    if (keyRegion == null) {
+      command.setResponse(Coder.getScanResponse(context.getByteBufAllocator(), new ArrayList<String>()));
+      return;
+    }
+    byte[] cAr = commandElems.get(2);
+    String cursorString = Coder.bytesToString(cAr);
+
+    int cursor = 0;
+    Pattern matchPattern = null;
+    String globMatchPattern = null;
+    int count = DEFUALT_COUNT;
+    try {
+      cursor = Integer.parseInt(cursorString);
+    } catch (NumberFormatException e) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ERROR_CURSOR));
+      return;
+    }
+    if (cursor < 0) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ERROR_CURSOR));
+      return;
+    }
+
+    if (commandElems.size() > 4) {
+      try {
+        byte[] bytes = commandElems.get(3);
+        String tmp = Coder.bytesToString(bytes);
+        if (tmp.equalsIgnoreCase("MATCH")) {
+          bytes = commandElems.get(4);
+          globMatchPattern = Coder.bytesToString(bytes);
+        } else if (tmp.equalsIgnoreCase("COUNT")) {
+          bytes = commandElems.get(4);
+          count = Coder.bytesToInt(bytes);
+        }
+      } catch (NumberFormatException e) {
+        command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ERROR_COUNT));
+        return;
+      }
+    }
+
+    if (commandElems.size() > 6) {
+      try {
+        byte[] bytes = commandElems.get(5);
+        String tmp = Coder.bytesToString(bytes);
+        if (tmp.equalsIgnoreCase("MATCH")) {
+          bytes = commandElems.get(6);
+          globMatchPattern = Coder.bytesToString(bytes);
+        } else if (tmp.equalsIgnoreCase("COUNT")) {
+          bytes = commandElems.get(6);
+          count = Coder.bytesToInt(bytes);
+        }
+      } catch (NumberFormatException e) {
+        command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ERROR_COUNT));
+        return;
+      }
+    }
+
+    if (count < 0) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ERROR_COUNT));
+      return;
+    }
+
+    try {
+      matchPattern = convertGlobToRegex(globMatchPattern);
+    } catch (PatternSyntaxException e) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), RedisConstants.ERROR_ILLEGAL_GLOB));
+      return;
+    }
+
+    List<Object> returnList = getIteration(new HashSet(keyRegion.entrySet()), matchPattern, count, cursor);
+
+    command.setResponse(Coder.getScanResponse(context.getByteBufAllocator(), returnList));
+  }
+
+  @SuppressWarnings("unchecked")
+  @Override
+  protected List<Object> getIteration(Collection<?> list, Pattern matchPattern, int count, int cursor) {
+    List<Object> returnList = new ArrayList<Object>();
+    int size = list.size();
+    int beforeCursor = 0;
+    int numElements = 0;
+    int i = -1;
+    for (Entry<ByteArrayWrapper, ByteArrayWrapper> entry: (Collection<Entry<ByteArrayWrapper, ByteArrayWrapper>>) list) {
+      ByteArrayWrapper key = entry.getKey();
+      ByteArrayWrapper value = entry.getValue();
+      i++;
+      if (beforeCursor < cursor) {
+        beforeCursor++;
+        continue;
+      } else if (numElements < count) {
+        if (matchPattern != null) {
+          if (matchPattern.matcher(key.toString()).matches()) {
+            returnList.add(key);
+            returnList.add(value);
+            numElements++;
+          }
+        } else {
+          returnList.add(key);
+          returnList.add(value);
+          numElements++;
+        }
+      } else
+        break;
+    }
+
+    if (i == size - 1)
+      returnList.add(0, String.valueOf(0));
+    else
+      returnList.add(0, String.valueOf(i));
+    return returnList;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfd481e0/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HSetExecutor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HSetExecutor.java b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HSetExecutor.java
new file mode 100755
index 0000000..871fc2e
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HSetExecutor.java
@@ -0,0 +1,78 @@
+/*
+ * 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.executor.hash;
+
+import java.util.List;
+
+import com.gemstone.gemfire.cache.Region;
+import org.apache.geode.redis.internal.ByteArrayWrapper;
+import org.apache.geode.redis.internal.Coder;
+import org.apache.geode.redis.internal.Command;
+import org.apache.geode.redis.internal.ExecutionHandlerContext;
+import org.apache.geode.redis.internal.Extendable;
+import org.apache.geode.redis.internal.RedisConstants.ArityDef;
+import org.apache.geode.redis.internal.RedisDataType;
+
+public class HSetExecutor extends HashExecutor implements Extendable {
+
+  private final int EXISTING_FIELD = 0;
+
+  private final int NEW_FIELD = 1;
+
+  private final int VALUE_INDEX = 3;
+
+  @Override
+  public void executeCommand(Command command, ExecutionHandlerContext context) {
+    List<byte[]> commandElems = command.getProcessedCommand();
+
+    if (commandElems.size() < 4) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), getArgsError()));
+      return;
+    }
+
+    ByteArrayWrapper key = command.getKey();
+
+    Region<ByteArrayWrapper, ByteArrayWrapper> keyRegion = getOrCreateRegion(context, key, RedisDataType.REDIS_HASH);
+
+    byte[] byteField = commandElems.get(FIELD_INDEX);
+    ByteArrayWrapper field = new ByteArrayWrapper(byteField);
+
+    byte[] value = commandElems.get(VALUE_INDEX);
+
+    Object oldValue;
+
+    if (onlySetOnAbsent())
+      oldValue = keyRegion.putIfAbsent(field, new ByteArrayWrapper(value));
+    else
+      oldValue = keyRegion.put(field, new ByteArrayWrapper(value));
+
+    if (oldValue == null)
+      command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), NEW_FIELD));
+    else
+      command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), EXISTING_FIELD));
+
+  }
+
+  protected boolean onlySetOnAbsent() {
+    return false;
+  }
+
+  @Override
+  public String getArgsError() {
+    return ArityDef.HSET;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfd481e0/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HSetNXExecutor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HSetNXExecutor.java b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HSetNXExecutor.java
new file mode 100755
index 0000000..9861636
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HSetNXExecutor.java
@@ -0,0 +1,33 @@
+/*
+ * 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.executor.hash;
+
+import org.apache.geode.redis.internal.RedisConstants.ArityDef;
+
+
+public class HSetNXExecutor extends HSetExecutor {
+
+  @Override
+  protected boolean onlySetOnAbsent() {
+    return true;
+  }
+
+  @Override
+  public String getArgsError() {
+    return ArityDef.HSETNX;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfd481e0/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HValsExecutor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HValsExecutor.java b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HValsExecutor.java
new file mode 100755
index 0000000..d2e208a
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HValsExecutor.java
@@ -0,0 +1,62 @@
+/*
+ * 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.executor.hash;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import com.gemstone.gemfire.cache.Region;
+import org.apache.geode.redis.internal.ByteArrayWrapper;
+import org.apache.geode.redis.internal.Coder;
+import org.apache.geode.redis.internal.Command;
+import org.apache.geode.redis.internal.ExecutionHandlerContext;
+import org.apache.geode.redis.internal.RedisConstants.ArityDef;
+import org.apache.geode.redis.internal.RedisDataType;
+
+public class HValsExecutor extends HashExecutor {
+
+  @Override
+  public void executeCommand(Command command, ExecutionHandlerContext context) {
+    List<byte[]> commandElems = command.getProcessedCommand();
+
+    if (commandElems.size() < 2) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ArityDef.HVALS));
+      return;
+    }
+
+    ByteArrayWrapper key = command.getKey();
+    checkDataType(key, RedisDataType.REDIS_HASH, context);
+
+    Region<ByteArrayWrapper, ByteArrayWrapper> keyRegion = getRegion(context, key);
+
+    if (keyRegion == null) {
+      command.setResponse(Coder.getEmptyArrayResponse(context.getByteBufAllocator()));
+      return;
+    }
+    
+    Collection<ByteArrayWrapper> vals = new ArrayList(keyRegion.values());
+
+    if (vals.isEmpty()) {
+      command.setResponse(Coder.getEmptyArrayResponse(context.getByteBufAllocator()));
+      return;
+    }
+
+    command.setResponse(Coder.getBulkStringArrayResponse(context.getByteBufAllocator(), vals));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfd481e0/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HashExecutor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HashExecutor.java b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HashExecutor.java
new file mode 100755
index 0000000..ae66de2
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hash/HashExecutor.java
@@ -0,0 +1,39 @@
+/*
+ * 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.executor.hash;
+
+import com.gemstone.gemfire.cache.Region;
+import org.apache.geode.redis.internal.ByteArrayWrapper;
+import org.apache.geode.redis.internal.ExecutionHandlerContext;
+import org.apache.geode.redis.internal.RedisDataType;
+import org.apache.geode.redis.internal.executor.AbstractExecutor;
+
+public abstract class HashExecutor extends AbstractExecutor {
+
+  protected final int FIELD_INDEX = 2;
+  
+  @SuppressWarnings("unchecked")
+  protected Region<ByteArrayWrapper, ByteArrayWrapper> getOrCreateRegion(ExecutionHandlerContext context, ByteArrayWrapper key, RedisDataType type) {
+   return (Region<ByteArrayWrapper, ByteArrayWrapper>) context.getRegionProvider().getOrCreateRegion(key, type, context);
+  }
+  
+  @SuppressWarnings("unchecked")
+  protected Region<ByteArrayWrapper, ByteArrayWrapper> getRegion(ExecutionHandlerContext context, ByteArrayWrapper key) {
+   return (Region<ByteArrayWrapper, ByteArrayWrapper>) context.getRegionProvider().getRegion(key);
+  }
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfd481e0/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hll/HllExecutor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hll/HllExecutor.java b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hll/HllExecutor.java
new file mode 100755
index 0000000..0d68363
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hll/HllExecutor.java
@@ -0,0 +1,38 @@
+/*
+ * 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.executor.hll;
+
+import org.apache.geode.redis.internal.ByteArrayWrapper;
+import org.apache.geode.redis.internal.ExecutionHandlerContext;
+import org.apache.geode.redis.internal.RedisDataType;
+import org.apache.geode.redis.internal.RedisDataTypeMismatchException;
+import org.apache.geode.redis.internal.executor.AbstractExecutor;
+
+public abstract class HllExecutor extends AbstractExecutor {
+  
+  public static final Double DEFAULT_HLL_STD_DEV = 0.081;
+  public static final Integer DEFAULT_HLL_DENSE = 18;
+  public static final Integer DEFAULT_HLL_SPARSE = 32;
+  
+  protected final void checkAndSetDataType(ByteArrayWrapper key, ExecutionHandlerContext context) {
+    Object oldVal = context.getRegionProvider().metaPutIfAbsent(key, RedisDataType.REDIS_HLL);
+    if (oldVal == RedisDataType.REDIS_PROTECTED)
+      throw new RedisDataTypeMismatchException("The key name \"" + key + "\" is protected");
+    if (oldVal != null && oldVal != RedisDataType.REDIS_HLL)
+      throw new RedisDataTypeMismatchException("The key name \"" + key + "\" is already used by a " + oldVal.toString());
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfd481e0/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hll/PFAddExecutor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hll/PFAddExecutor.java b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hll/PFAddExecutor.java
new file mode 100755
index 0000000..5a3550a
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hll/PFAddExecutor.java
@@ -0,0 +1,66 @@
+/*
+ * 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.executor.hll;
+
+import java.util.List;
+
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.internal.hll.HyperLogLogPlus;
+import org.apache.geode.redis.internal.ByteArrayWrapper;
+import org.apache.geode.redis.internal.Command;
+import org.apache.geode.redis.internal.Coder;
+import org.apache.geode.redis.internal.ExecutionHandlerContext;
+import org.apache.geode.redis.internal.RedisConstants.ArityDef;
+
+public class PFAddExecutor extends HllExecutor {
+
+  @Override
+  public void executeCommand(Command command, ExecutionHandlerContext context) {
+    List<byte[]> commandElems = command.getProcessedCommand();
+
+    if (commandElems.size() < 2) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ArityDef.PFADD));
+      return;
+    }
+
+    ByteArrayWrapper key = command.getKey();
+    checkAndSetDataType(key, context);
+    Region<ByteArrayWrapper, HyperLogLogPlus> keyRegion = context.getRegionProvider().gethLLRegion();
+
+    HyperLogLogPlus hll = keyRegion.get(key);
+
+    boolean changed = false;
+
+    if (hll == null)
+      hll = new HyperLogLogPlus(DEFAULT_HLL_DENSE);
+
+    for (int i = 2; i < commandElems.size(); i++) {
+      byte[] bytes = commandElems.get(i);
+      boolean offerChange = hll.offer(bytes);
+      if (offerChange)
+        changed = true;
+    }
+
+    keyRegion.put(key, hll);
+
+    if (changed)
+      command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), 1));
+    else
+      command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), 0));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfd481e0/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hll/PFCountExecutor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hll/PFCountExecutor.java b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hll/PFCountExecutor.java
new file mode 100755
index 0000000..2d538c4
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hll/PFCountExecutor.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.executor.hll;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.internal.hll.CardinalityMergeException;
+import com.gemstone.gemfire.internal.hll.HyperLogLogPlus;
+import org.apache.geode.redis.internal.ByteArrayWrapper;
+import org.apache.geode.redis.internal.Coder;
+import org.apache.geode.redis.internal.Command;
+import org.apache.geode.redis.internal.ExecutionHandlerContext;
+import org.apache.geode.redis.internal.RedisConstants.ArityDef;
+import org.apache.geode.redis.internal.RedisDataType;
+
+public class PFCountExecutor extends HllExecutor {
+
+  @Override
+  public void executeCommand(Command command, ExecutionHandlerContext context) {
+    List<byte[]> commandElems = command.getProcessedCommand();
+
+    if (commandElems.size() < 2) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ArityDef.PFCOUNT));
+      return;
+    }
+
+    Region<ByteArrayWrapper, HyperLogLogPlus> keyRegion = context.getRegionProvider().gethLLRegion();
+
+    List<HyperLogLogPlus> hlls = new ArrayList<HyperLogLogPlus>();
+
+    for (int i = 1; i < commandElems.size(); i++) {
+      ByteArrayWrapper k = new ByteArrayWrapper(commandElems.get(i));
+      checkDataType(k, RedisDataType.REDIS_HLL, context);
+      HyperLogLogPlus h = keyRegion.get(k);
+      if (h != null)
+        hlls.add(h);
+    }
+    if (hlls.isEmpty()) {
+      command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), 0));
+      return;
+    }
+
+    HyperLogLogPlus tmp = hlls.remove(0);
+    HyperLogLogPlus[] estimators = hlls.toArray(new HyperLogLogPlus[hlls.size()]);
+    try {
+      tmp = (HyperLogLogPlus) tmp.merge(estimators);
+    } catch (CardinalityMergeException e) {
+      throw new RuntimeException(e);
+    }
+    long cardinality = tmp.cardinality();
+    command.setResponse(Coder.getIntegerResponse(context.getByteBufAllocator(), cardinality));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfd481e0/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hll/PFMergeExecutor.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hll/PFMergeExecutor.java b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hll/PFMergeExecutor.java
new file mode 100755
index 0000000..6231abb
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/redis/internal/executor/hll/PFMergeExecutor.java
@@ -0,0 +1,74 @@
+/*
+ * 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.executor.hll;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.internal.hll.CardinalityMergeException;
+import com.gemstone.gemfire.internal.hll.HyperLogLogPlus;
+import org.apache.geode.redis.internal.ByteArrayWrapper;
+import org.apache.geode.redis.internal.Coder;
+import org.apache.geode.redis.internal.Command;
+import org.apache.geode.redis.internal.ExecutionHandlerContext;
+import org.apache.geode.redis.internal.RedisDataType;
+import org.apache.geode.redis.internal.RedisConstants.ArityDef;
+
+public class PFMergeExecutor extends HllExecutor {
+
+  @Override
+  public void executeCommand(Command command, ExecutionHandlerContext context) {
+    List<byte[]> commandElems = command.getProcessedCommand();
+
+    if (commandElems.size() < 3) {
+      command.setResponse(Coder.getErrorResponse(context.getByteBufAllocator(), ArityDef.PFMERGE));
+      return;
+    }
+
+    ByteArrayWrapper destKey = command.getKey();
+    checkAndSetDataType(destKey, context);
+    Region<ByteArrayWrapper, HyperLogLogPlus> keyRegion = context.getRegionProvider().gethLLRegion();
+    HyperLogLogPlus mergedHLL = keyRegion.get(destKey);
+    if (mergedHLL == null)
+      mergedHLL = new HyperLogLogPlus(DEFAULT_HLL_DENSE);
+    List<HyperLogLogPlus> hlls = new ArrayList<HyperLogLogPlus>();
+
+    for (int i = 2; i < commandElems.size(); i++) {
+      ByteArrayWrapper k = new ByteArrayWrapper(commandElems.get(i));
+      checkDataType(k, RedisDataType.REDIS_HLL, context);
+      HyperLogLogPlus h = keyRegion.get(k);
+      if (h != null)
+        hlls.add(h);
+    }
+    if (hlls.isEmpty()) {
+      context.getRegionProvider().removeKey(destKey);
+      command.setResponse(Coder.getSimpleStringResponse(context.getByteBufAllocator(), "OK"));
+      return;
+    }
+
+    HyperLogLogPlus[] estimators = hlls.toArray(new HyperLogLogPlus[hlls.size()]);
+    try {
+      mergedHLL = (HyperLogLogPlus) mergedHLL.merge(estimators);
+    } catch (CardinalityMergeException e) {
+      throw new RuntimeException(e);
+    }
+    keyRegion.put(destKey, mergedHLL);
+    command.setResponse(Coder.getSimpleStringResponse(context.getByteBufAllocator(), "OK"));
+  }
+
+}


Mime
View raw message