geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From u..@apache.org
Subject geode git commit: GEODE-2449: Moved Coder.java from core to redis module. fix up code from code review
Date Fri, 10 Feb 2017 22:45:52 GMT
Repository: geode
Updated Branches:
  refs/heads/feature/GEODE-2449 81e64a9a2 -> 318b56a5e


GEODE-2449: Moved Coder.java from core to redis module.
fix up code from code review


Project: http://git-wip-us.apache.org/repos/asf/geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/318b56a5
Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/318b56a5
Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/318b56a5

Branch: refs/heads/feature/GEODE-2449
Commit: 318b56a5e6a8cb443929dbe3d80fa5711777c2ef
Parents: 81e64a9
Author: Udo Kohlmeyer <ukohlmeyer@pivotal.io>
Authored: Fri Feb 10 14:45:45 2017 -0800
Committer: Udo Kohlmeyer <ukohlmeyer@pivotal.io>
Committed: Fri Feb 10 14:45:45 2017 -0800

----------------------------------------------------------------------
 .../geode/internal/cache/GemFireCacheImpl.java  |  12 +-
 .../org/apache/geode/redis/internal/Coder.java  | 521 -------------------
 .../geode/redis/GeodeRedisServiceImpl.java      |   4 +-
 .../org/apache/geode/redis/internal/Coder.java  | 521 +++++++++++++++++++
 4 files changed, 529 insertions(+), 529 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/geode/blob/318b56a5/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java
b/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java
index 4015ea9..e8f410d 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/GemFireCacheImpl.java
@@ -610,11 +610,6 @@ public class GemFireCacheImpl
    */
   private GemFireMemcachedServer memcachedServer;
 
-  // /**
-  // * Redis server is started when {@link DistributionConfig#getRedisPort()} is set
-  // */
-  // private CacheService redisServer;
-
   /**
    * {@link ExtensionPoint} support.
    * 
@@ -1369,7 +1364,12 @@ public class GemFireCacheImpl
     int port = system.getConfig().getRedisPort();
     if (port != 0) {
       GeodeRedisService geodeRedisService = getService(GeodeRedisService.class);
-      geodeRedisService.start();
+      if (geodeRedisService != null) {
+        geodeRedisService.start();
+      } else {
+        throw new GemFireConfigException(
+            "Geode Redis Service could not be started because it was not registered as a
service");
+      }
     }
   }
 

http://git-wip-us.apache.org/repos/asf/geode/blob/318b56a5/geode-core/src/main/java/org/apache/geode/redis/internal/Coder.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/redis/internal/Coder.java b/geode-core/src/main/java/org/apache/geode/redis/internal/Coder.java
deleted file mode 100644
index 928f345..0000000
--- a/geode-core/src/main/java/org/apache/geode/redis/internal/Coder.java
+++ /dev/null
@@ -1,521 +0,0 @@
-/*
- * 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;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.ByteBufAllocator;
-
-import java.io.UnsupportedEncodingException;
-import java.text.DecimalFormat;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.geode.cache.EntryDestroyedException;
-import org.apache.geode.cache.query.Struct;
-
-/**
- * This is a safe encoder and decoder for all redis matching needs
- * 
- *
- */
-public class Coder {
-
-  /*
-   * Take no chances on char to byte conversions with default charsets on jvms, so we'll
hard code
-   * the UTF-8 symbol values as bytes here
-   */
-
-
-  /**
-   * byte identifier of a bulk string
-   */
-  public static final byte BULK_STRING_ID = 36; // '$'
-
-  /**
-   * byte identifier of an array
-   */
-  public static final byte ARRAY_ID = 42; // '*'
-
-  /**
-   * byte identifier of an error
-   */
-  public static final byte ERROR_ID = 45; // '-'
-
-  /**
-   * byte identifier of an integer
-   */
-  public static final byte INTEGER_ID = 58; // ':'
-
-  public static final byte OPEN_BRACE_ID = 0x28; // '('
-  public static final byte OPEN_BRACKET_ID = 0x5b; // '['
-  public static final byte HYPHEN_ID = 0x2d; // '-'
-  public static final byte PLUS_ID = 0x2b; // '+'
-  public static final byte NUMBER_1_BYTE = 0x31; // '1'
-  /**
-   * byte identifier of a simple string
-   */
-  public static final byte SIMPLE_STRING_ID = 43; // '+'
-  public static final String CRLF = "\r\n";
-  public static final byte[] CRLFar = stringToBytes(CRLF); // {13, 10} == {'\r', '\n'}
-
-  /**
-   * byte array of a nil response
-   */
-  public static final byte[] bNIL = stringToBytes("$-1\r\n"); // {'$', '-', '1', '\r', '\n'};
-
-  /**
-   * byte array of an empty string
-   */
-  public static final byte[] bEMPTY_ARRAY = stringToBytes("*0\r\n"); // {'*', '0', '\r',
'\n'};
-
-  public static final byte[] err = stringToBytes("ERR ");
-  public static final byte[] noAuth = stringToBytes("NOAUTH ");
-  public static final byte[] wrongType = stringToBytes("WRONGTYPE ");
-
-  /**
-   * The charset being used by this coder, {@value #CHARSET}.
-   */
-  public static final String CHARSET = "UTF-8";
-
-  protected static final DecimalFormat decimalFormatter = new DecimalFormat("#");
-  static {
-    decimalFormatter.setMaximumFractionDigits(10);
-  }
-
-  /**
-   * Positive infinity string
-   */
-  public static final String P_INF = "+inf";
-
-  /**
-   * Negative infinity string
-   */
-  public static final String N_INF = "-inf";
-
-  public static final ByteBuf getBulkStringResponse(ByteBufAllocator alloc, byte[] value)
{
-    ByteBuf response = alloc.buffer(value.length + 20);
-    response.writeByte(BULK_STRING_ID);
-    response.writeBytes(intToBytes(value.length));
-    response.writeBytes(CRLFar);
-    response.writeBytes(value);
-    response.writeBytes(CRLFar);
-    return response;
-  }
-
-  public static final ByteBuf getBulkStringResponse(ByteBufAllocator alloc, double value)
{
-    ByteBuf response = alloc.buffer();
-    byte[] doub = doubleToBytes(value);
-    response.writeByte(BULK_STRING_ID);
-    response.writeBytes(intToBytes(doub.length));
-    response.writeBytes(CRLFar);
-    response.writeBytes(doub);
-    response.writeBytes(CRLFar);
-    return response;
-  }
-
-  public static final ByteBuf getBulkStringResponse(ByteBufAllocator alloc, String value)
{
-    byte[] valueAr = stringToBytes(value);
-    int length = valueAr == null ? 0 : valueAr.length;
-    ByteBuf response = alloc.buffer(length + 20);
-    response.writeByte(BULK_STRING_ID);
-    response.writeBytes(intToBytes(length));
-    response.writeBytes(CRLFar);
-    response.writeBytes(valueAr);
-    response.writeBytes(CRLFar);
-    return response;
-  }
-
-  public static final ByteBuf getBulkStringArrayResponse(ByteBufAllocator alloc,
-      List<String> items) {
-    Iterator<String> it = items.iterator();
-    ByteBuf response = alloc.buffer();
-    response.writeByte(ARRAY_ID);
-    response.writeBytes(intToBytes(items.size()));
-    response.writeBytes(CRLFar);
-    while (it.hasNext()) {
-      String next = it.next();
-      response.writeByte(BULK_STRING_ID);
-      response.writeBytes(intToBytes(next.length()));
-      response.writeBytes(CRLFar);
-      response.writeBytes(stringToBytes(next));
-      response.writeBytes(CRLFar);
-    }
-    return response;
-  }
-
-  public static final ByteBuf getBulkStringArrayResponse(ByteBufAllocator alloc,
-      Collection<ByteArrayWrapper> items) {
-    Iterator<ByteArrayWrapper> it = items.iterator();
-    ByteBuf response = alloc.buffer();
-    response.writeByte(ARRAY_ID);
-    response.writeBytes(intToBytes(items.size()));
-    response.writeBytes(CRLFar);
-    while (it.hasNext()) {
-      ByteArrayWrapper nextWrapper = it.next();
-      if (nextWrapper != null) {
-        response.writeByte(BULK_STRING_ID);
-        response.writeBytes(intToBytes(nextWrapper.length()));
-        response.writeBytes(CRLFar);
-        response.writeBytes(nextWrapper.toBytes());
-        response.writeBytes(CRLFar);
-      } else
-        response.writeBytes(getNilResponse(alloc));
-    }
-
-    return response;
-  }
-
-  public static final ByteBuf getKeyValArrayResponse(ByteBufAllocator alloc,
-      Collection<Entry<ByteArrayWrapper, ByteArrayWrapper>> items) {
-    Iterator<Map.Entry<ByteArrayWrapper, ByteArrayWrapper>> it = items.iterator();
-    ByteBuf response = alloc.buffer();
-    response.writeByte(ARRAY_ID);
-
-    int size = 0;
-    ByteBuf tmp = alloc.buffer();
-    while (it.hasNext()) {
-      Map.Entry<ByteArrayWrapper, ByteArrayWrapper> next = it.next();
-      byte[] key;
-      byte[] nextByteArray;
-      try {
-        key = next.getKey().toBytes();
-        nextByteArray = next.getValue().toBytes();
-      } catch (EntryDestroyedException e) {
-        continue;
-      }
-      tmp.writeByte(BULK_STRING_ID); // Add key
-      tmp.writeBytes(intToBytes(key.length));
-      tmp.writeBytes(CRLFar);
-      tmp.writeBytes(key);
-      tmp.writeBytes(CRLFar);
-      tmp.writeByte(BULK_STRING_ID); // Add value
-      tmp.writeBytes(intToBytes(nextByteArray.length));
-      tmp.writeBytes(CRLFar);
-      tmp.writeBytes(nextByteArray);
-      tmp.writeBytes(CRLFar);
-      size++;
-    }
-
-    response.writeBytes(intToBytes(size * 2));
-    response.writeBytes(CRLFar);
-    response.writeBytes(tmp);
-
-    tmp.release();
-
-    return response;
-  }
-
-  public static final ByteBuf getScanResponse(ByteBufAllocator alloc, List<?> items)
{
-    ByteBuf response = alloc.buffer();
-    response.writeByte(ARRAY_ID);
-    response.writeBytes(intToBytes(2));
-    response.writeBytes(CRLFar);
-    response.writeByte(BULK_STRING_ID);
-    byte[] cursor = stringToBytes((String) items.get(0));
-    response.writeBytes(intToBytes(cursor.length));
-    response.writeBytes(CRLFar);
-    response.writeBytes(cursor);
-    response.writeBytes(CRLFar);
-    items = items.subList(1, items.size());
-    Iterator<?> it = items.iterator();
-    response.writeByte(ARRAY_ID);
-    response.writeBytes(intToBytes(items.size()));
-    response.writeBytes(CRLFar);
-
-    while (it.hasNext()) {
-      Object nextObject = it.next();
-      if (nextObject instanceof String) {
-        String next = (String) nextObject;
-        response.writeByte(BULK_STRING_ID);
-        response.writeBytes(intToBytes(next.length()));
-        response.writeBytes(CRLFar);
-        response.writeBytes(stringToBytes(next));
-        response.writeBytes(CRLFar);
-      } else if (nextObject instanceof ByteArrayWrapper) {
-        byte[] next = ((ByteArrayWrapper) nextObject).toBytes();
-        response.writeByte(BULK_STRING_ID);
-        response.writeBytes(intToBytes(next.length));
-        response.writeBytes(CRLFar);
-        response.writeBytes(next);
-        response.writeBytes(CRLFar);
-      }
-    }
-    return response;
-  }
-
-  public static final ByteBuf getEmptyArrayResponse(ByteBufAllocator alloc) {
-    ByteBuf buf = alloc.buffer().writeBytes(bEMPTY_ARRAY);
-    return buf;
-  }
-
-  public static final ByteBuf getSimpleStringResponse(ByteBufAllocator alloc, String string)
{
-    byte[] simpAr = stringToBytes(string);
-
-    ByteBuf response = alloc.buffer(simpAr.length + 20);
-    response.writeByte(SIMPLE_STRING_ID);
-    response.writeBytes(simpAr);
-    response.writeBytes(CRLFar);
-    return response;
-  }
-
-  public static final ByteBuf getErrorResponse(ByteBufAllocator alloc, String error) {
-    byte[] errorAr = stringToBytes(error);
-    ByteBuf response = alloc.buffer(errorAr.length + 25);
-    response.writeByte(ERROR_ID);
-    response.writeBytes(err);
-    response.writeBytes(errorAr);
-    response.writeBytes(CRLFar);
-    return response;
-  }
-
-  public static final ByteBuf getNoAuthResponse(ByteBufAllocator alloc, String error) {
-    byte[] errorAr = stringToBytes(error);
-    ByteBuf response = alloc.buffer(errorAr.length + 25);
-    response.writeByte(ERROR_ID);
-    response.writeBytes(noAuth);
-    response.writeBytes(errorAr);
-    response.writeBytes(CRLFar);
-    return response;
-  }
-
-  public static final ByteBuf getWrongTypeResponse(ByteBufAllocator alloc, String error)
{
-    byte[] errorAr = stringToBytes(error);
-    ByteBuf response = alloc.buffer(errorAr.length + 31);
-    response.writeByte(ERROR_ID);
-    response.writeBytes(wrongType);
-    response.writeBytes(errorAr);
-    response.writeBytes(CRLFar);
-    return response;
-  }
-
-  public static final ByteBuf getIntegerResponse(ByteBufAllocator alloc, int integer) {
-    ByteBuf response = alloc.buffer(15);
-    response.writeByte(INTEGER_ID);
-    response.writeBytes(intToBytes(integer));
-    response.writeBytes(CRLFar);
-    return response;
-  }
-
-  public static final ByteBuf getIntegerResponse(ByteBufAllocator alloc, long l) {
-    ByteBuf response = alloc.buffer(25);
-    response.writeByte(INTEGER_ID);
-    response.writeBytes(longToBytes(l));
-    response.writeBytes(CRLFar);
-    return response;
-  }
-
-  public static final ByteBuf getNilResponse(ByteBufAllocator alloc) {
-    ByteBuf buf = alloc.buffer().writeBytes(bNIL);
-    return buf;
-  }
-
-  public static ByteBuf getBulkStringArrayResponseOfValues(ByteBufAllocator alloc,
-      Collection<?> items) {
-    Iterator<?> it = items.iterator();
-    ByteBuf response = alloc.buffer();
-    response.writeByte(Coder.ARRAY_ID);
-    ByteBuf tmp = alloc.buffer();
-    int size = 0;
-    while (it.hasNext()) {
-      Object next = it.next();
-      ByteArrayWrapper nextWrapper = null;
-      if (next instanceof Entry) {
-        try {
-          nextWrapper = (ByteArrayWrapper) ((Entry<?, ?>) next).getValue();
-        } catch (EntryDestroyedException e) {
-          continue;
-        }
-      } else if (next instanceof Struct) {
-        nextWrapper = (ByteArrayWrapper) ((Struct) next).getFieldValues()[1];
-      }
-      if (nextWrapper != null) {
-        tmp.writeByte(Coder.BULK_STRING_ID);
-        tmp.writeBytes(intToBytes(nextWrapper.length()));
-        tmp.writeBytes(Coder.CRLFar);
-        tmp.writeBytes(nextWrapper.toBytes());
-        tmp.writeBytes(Coder.CRLFar);
-      } else {
-        tmp.writeBytes(Coder.bNIL);
-      }
-      size++;
-    }
-
-    response.writeBytes(intToBytes(size));
-    response.writeBytes(Coder.CRLFar);
-    response.writeBytes(tmp);
-
-    tmp.release();
-
-    return response;
-  }
-
-  public static ByteBuf zRangeResponse(ByteBufAllocator alloc, Collection<?> list,
-      boolean withScores) {
-    if (list.isEmpty())
-      return Coder.getEmptyArrayResponse(alloc);
-
-    ByteBuf buffer = alloc.buffer();
-    buffer.writeByte(Coder.ARRAY_ID);
-    ByteBuf tmp = alloc.buffer();
-    int size = 0;
-
-    for (Object entry : list) {
-      ByteArrayWrapper key;
-      DoubleWrapper score;
-      if (entry instanceof Entry) {
-        try {
-          key = (ByteArrayWrapper) ((Entry<?, ?>) entry).getKey();
-          score = (DoubleWrapper) ((Entry<?, ?>) entry).getValue();
-        } catch (EntryDestroyedException e) {
-          continue;
-        }
-      } else {
-        Object[] fieldVals = ((Struct) entry).getFieldValues();
-        key = (ByteArrayWrapper) fieldVals[0];
-        score = (DoubleWrapper) fieldVals[1];
-      }
-      byte[] byteAr = key.toBytes();
-      tmp.writeByte(Coder.BULK_STRING_ID);
-      tmp.writeBytes(intToBytes(byteAr.length));
-      tmp.writeBytes(Coder.CRLFar);
-      tmp.writeBytes(byteAr);
-      tmp.writeBytes(Coder.CRLFar);
-      size++;
-      if (withScores) {
-        String scoreString = score.toString();
-        byte[] scoreAr = stringToBytes(scoreString);
-        tmp.writeByte(Coder.BULK_STRING_ID);
-        tmp.writeBytes(intToBytes(scoreString.length()));
-        tmp.writeBytes(Coder.CRLFar);
-        tmp.writeBytes(scoreAr);
-        tmp.writeBytes(Coder.CRLFar);
-        size++;
-      }
-    }
-
-    buffer.writeBytes(intToBytes(size));
-    buffer.writeBytes(Coder.CRLFar);
-    buffer.writeBytes(tmp);
-
-    tmp.release();
-
-    return buffer;
-  }
-
-  public static ByteBuf getArrayOfNils(ByteBufAllocator alloc, int length) {
-    ByteBuf response = alloc.buffer();
-    response.writeByte(Coder.ARRAY_ID);
-    response.writeBytes(intToBytes(length));
-    response.writeBytes(Coder.CRLFar);
-
-    for (int i = 0; i < length; i++)
-      response.writeBytes(bNIL);
-
-    return response;
-  }
-
-  public static String bytesToString(byte[] bytes) {
-    if (bytes == null)
-      return null;
-    try {
-      return new String(bytes, CHARSET).intern();
-    } catch (UnsupportedEncodingException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  public static String doubleToString(double d) {
-    if (d == Double.POSITIVE_INFINITY)
-      return "Infinity";
-    else if (d == Double.NEGATIVE_INFINITY)
-      return "-Infinity";
-    return String.valueOf(d);
-  }
-
-  public static byte[] stringToBytes(String string) {
-    if (string == null || string.equals(""))
-      return null;
-    try {
-      return string.getBytes(CHARSET);
-    } catch (UnsupportedEncodingException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  public static ByteArrayWrapper stringToByteArrayWrapper(String s) {
-    return new ByteArrayWrapper(stringToBytes(s));
-  }
-
-  /*
-   * These toByte methods convert to byte arrays of the string representation of the input,
not
-   * literal to byte
-   */
-
-  public static byte[] intToBytes(int i) {
-    return stringToBytes(String.valueOf(i));
-  }
-
-  public static byte[] longToBytes(long l) {
-    return stringToBytes(String.valueOf(l));
-  }
-
-  public static byte[] doubleToBytes(double d) {
-    return stringToBytes(doubleToString(d));
-  }
-
-  public static int bytesToInt(byte[] bytes) {
-    return Integer.parseInt(bytesToString(bytes));
-  }
-
-  public static long bytesToLong(byte[] bytes) {
-    return Long.parseLong(bytesToString(bytes));
-  }
-
-  /**
-   * A conversion where the byte array actually represents a string, so it is converted as
a string
-   * not as a literal double
-   * 
-   * @param bytes Array holding double
-   * @return Parsed value
-   * @throws NumberFormatException if bytes to string does not yield a convertible double
-   */
-  public static Double bytesToDouble(byte[] bytes) {
-    return stringToDouble(bytesToString(bytes));
-  }
-
-  /**
-   * Redis specific manner to parse floats
-   * 
-   * @param d String holding double
-   * @return Value of string
-   * @throws NumberFormatException if the double cannot be parsed
-   */
-  public static double stringToDouble(String d) {
-    if (d.equalsIgnoreCase(P_INF))
-      return Double.POSITIVE_INFINITY;
-    else if (d.equalsIgnoreCase(N_INF))
-      return Double.NEGATIVE_INFINITY;
-    else
-      return Double.parseDouble(d);
-  }
-
-  public static ByteArrayWrapper stringToByteWrapper(String s) {
-    return new ByteArrayWrapper(stringToBytes(s));
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/geode/blob/318b56a5/geode-redis/src/main/java/org/apache/geode/redis/GeodeRedisServiceImpl.java
----------------------------------------------------------------------
diff --git a/geode-redis/src/main/java/org/apache/geode/redis/GeodeRedisServiceImpl.java b/geode-redis/src/main/java/org/apache/geode/redis/GeodeRedisServiceImpl.java
index 8d81456..1026d40 100644
--- a/geode-redis/src/main/java/org/apache/geode/redis/GeodeRedisServiceImpl.java
+++ b/geode-redis/src/main/java/org/apache/geode/redis/GeodeRedisServiceImpl.java
@@ -580,9 +580,9 @@ public class GeodeRedisServiceImpl implements GeodeRedisService {
       Future<?> bossGroupFuture = bossGroup.shutdownGracefully(0, 1, TimeUnit.SECONDS);
       ChannelFuture closeFuture = this.serverChannel.close();
 
+      // TODO we need to investigate how the shutdown should work.
       // We are likely brought here by a channel read reading a shutdown message, in which
case
-      // calling
-      // await or sync can cause a deadlock.
+      // calling await or sync can cause a deadlock.
       // workerGroupFuture.syncUninterruptibly();
       // bossGroupFuture.syncUninterruptibly();
       this.regionProvider.close();

http://git-wip-us.apache.org/repos/asf/geode/blob/318b56a5/geode-redis/src/main/java/org/apache/geode/redis/internal/Coder.java
----------------------------------------------------------------------
diff --git a/geode-redis/src/main/java/org/apache/geode/redis/internal/Coder.java b/geode-redis/src/main/java/org/apache/geode/redis/internal/Coder.java
new file mode 100644
index 0000000..928f345
--- /dev/null
+++ b/geode-redis/src/main/java/org/apache/geode/redis/internal/Coder.java
@@ -0,0 +1,521 @@
+/*
+ * 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;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufAllocator;
+
+import java.io.UnsupportedEncodingException;
+import java.text.DecimalFormat;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.geode.cache.EntryDestroyedException;
+import org.apache.geode.cache.query.Struct;
+
+/**
+ * This is a safe encoder and decoder for all redis matching needs
+ * 
+ *
+ */
+public class Coder {
+
+  /*
+   * Take no chances on char to byte conversions with default charsets on jvms, so we'll
hard code
+   * the UTF-8 symbol values as bytes here
+   */
+
+
+  /**
+   * byte identifier of a bulk string
+   */
+  public static final byte BULK_STRING_ID = 36; // '$'
+
+  /**
+   * byte identifier of an array
+   */
+  public static final byte ARRAY_ID = 42; // '*'
+
+  /**
+   * byte identifier of an error
+   */
+  public static final byte ERROR_ID = 45; // '-'
+
+  /**
+   * byte identifier of an integer
+   */
+  public static final byte INTEGER_ID = 58; // ':'
+
+  public static final byte OPEN_BRACE_ID = 0x28; // '('
+  public static final byte OPEN_BRACKET_ID = 0x5b; // '['
+  public static final byte HYPHEN_ID = 0x2d; // '-'
+  public static final byte PLUS_ID = 0x2b; // '+'
+  public static final byte NUMBER_1_BYTE = 0x31; // '1'
+  /**
+   * byte identifier of a simple string
+   */
+  public static final byte SIMPLE_STRING_ID = 43; // '+'
+  public static final String CRLF = "\r\n";
+  public static final byte[] CRLFar = stringToBytes(CRLF); // {13, 10} == {'\r', '\n'}
+
+  /**
+   * byte array of a nil response
+   */
+  public static final byte[] bNIL = stringToBytes("$-1\r\n"); // {'$', '-', '1', '\r', '\n'};
+
+  /**
+   * byte array of an empty string
+   */
+  public static final byte[] bEMPTY_ARRAY = stringToBytes("*0\r\n"); // {'*', '0', '\r',
'\n'};
+
+  public static final byte[] err = stringToBytes("ERR ");
+  public static final byte[] noAuth = stringToBytes("NOAUTH ");
+  public static final byte[] wrongType = stringToBytes("WRONGTYPE ");
+
+  /**
+   * The charset being used by this coder, {@value #CHARSET}.
+   */
+  public static final String CHARSET = "UTF-8";
+
+  protected static final DecimalFormat decimalFormatter = new DecimalFormat("#");
+  static {
+    decimalFormatter.setMaximumFractionDigits(10);
+  }
+
+  /**
+   * Positive infinity string
+   */
+  public static final String P_INF = "+inf";
+
+  /**
+   * Negative infinity string
+   */
+  public static final String N_INF = "-inf";
+
+  public static final ByteBuf getBulkStringResponse(ByteBufAllocator alloc, byte[] value)
{
+    ByteBuf response = alloc.buffer(value.length + 20);
+    response.writeByte(BULK_STRING_ID);
+    response.writeBytes(intToBytes(value.length));
+    response.writeBytes(CRLFar);
+    response.writeBytes(value);
+    response.writeBytes(CRLFar);
+    return response;
+  }
+
+  public static final ByteBuf getBulkStringResponse(ByteBufAllocator alloc, double value)
{
+    ByteBuf response = alloc.buffer();
+    byte[] doub = doubleToBytes(value);
+    response.writeByte(BULK_STRING_ID);
+    response.writeBytes(intToBytes(doub.length));
+    response.writeBytes(CRLFar);
+    response.writeBytes(doub);
+    response.writeBytes(CRLFar);
+    return response;
+  }
+
+  public static final ByteBuf getBulkStringResponse(ByteBufAllocator alloc, String value)
{
+    byte[] valueAr = stringToBytes(value);
+    int length = valueAr == null ? 0 : valueAr.length;
+    ByteBuf response = alloc.buffer(length + 20);
+    response.writeByte(BULK_STRING_ID);
+    response.writeBytes(intToBytes(length));
+    response.writeBytes(CRLFar);
+    response.writeBytes(valueAr);
+    response.writeBytes(CRLFar);
+    return response;
+  }
+
+  public static final ByteBuf getBulkStringArrayResponse(ByteBufAllocator alloc,
+      List<String> items) {
+    Iterator<String> it = items.iterator();
+    ByteBuf response = alloc.buffer();
+    response.writeByte(ARRAY_ID);
+    response.writeBytes(intToBytes(items.size()));
+    response.writeBytes(CRLFar);
+    while (it.hasNext()) {
+      String next = it.next();
+      response.writeByte(BULK_STRING_ID);
+      response.writeBytes(intToBytes(next.length()));
+      response.writeBytes(CRLFar);
+      response.writeBytes(stringToBytes(next));
+      response.writeBytes(CRLFar);
+    }
+    return response;
+  }
+
+  public static final ByteBuf getBulkStringArrayResponse(ByteBufAllocator alloc,
+      Collection<ByteArrayWrapper> items) {
+    Iterator<ByteArrayWrapper> it = items.iterator();
+    ByteBuf response = alloc.buffer();
+    response.writeByte(ARRAY_ID);
+    response.writeBytes(intToBytes(items.size()));
+    response.writeBytes(CRLFar);
+    while (it.hasNext()) {
+      ByteArrayWrapper nextWrapper = it.next();
+      if (nextWrapper != null) {
+        response.writeByte(BULK_STRING_ID);
+        response.writeBytes(intToBytes(nextWrapper.length()));
+        response.writeBytes(CRLFar);
+        response.writeBytes(nextWrapper.toBytes());
+        response.writeBytes(CRLFar);
+      } else
+        response.writeBytes(getNilResponse(alloc));
+    }
+
+    return response;
+  }
+
+  public static final ByteBuf getKeyValArrayResponse(ByteBufAllocator alloc,
+      Collection<Entry<ByteArrayWrapper, ByteArrayWrapper>> items) {
+    Iterator<Map.Entry<ByteArrayWrapper, ByteArrayWrapper>> it = items.iterator();
+    ByteBuf response = alloc.buffer();
+    response.writeByte(ARRAY_ID);
+
+    int size = 0;
+    ByteBuf tmp = alloc.buffer();
+    while (it.hasNext()) {
+      Map.Entry<ByteArrayWrapper, ByteArrayWrapper> next = it.next();
+      byte[] key;
+      byte[] nextByteArray;
+      try {
+        key = next.getKey().toBytes();
+        nextByteArray = next.getValue().toBytes();
+      } catch (EntryDestroyedException e) {
+        continue;
+      }
+      tmp.writeByte(BULK_STRING_ID); // Add key
+      tmp.writeBytes(intToBytes(key.length));
+      tmp.writeBytes(CRLFar);
+      tmp.writeBytes(key);
+      tmp.writeBytes(CRLFar);
+      tmp.writeByte(BULK_STRING_ID); // Add value
+      tmp.writeBytes(intToBytes(nextByteArray.length));
+      tmp.writeBytes(CRLFar);
+      tmp.writeBytes(nextByteArray);
+      tmp.writeBytes(CRLFar);
+      size++;
+    }
+
+    response.writeBytes(intToBytes(size * 2));
+    response.writeBytes(CRLFar);
+    response.writeBytes(tmp);
+
+    tmp.release();
+
+    return response;
+  }
+
+  public static final ByteBuf getScanResponse(ByteBufAllocator alloc, List<?> items)
{
+    ByteBuf response = alloc.buffer();
+    response.writeByte(ARRAY_ID);
+    response.writeBytes(intToBytes(2));
+    response.writeBytes(CRLFar);
+    response.writeByte(BULK_STRING_ID);
+    byte[] cursor = stringToBytes((String) items.get(0));
+    response.writeBytes(intToBytes(cursor.length));
+    response.writeBytes(CRLFar);
+    response.writeBytes(cursor);
+    response.writeBytes(CRLFar);
+    items = items.subList(1, items.size());
+    Iterator<?> it = items.iterator();
+    response.writeByte(ARRAY_ID);
+    response.writeBytes(intToBytes(items.size()));
+    response.writeBytes(CRLFar);
+
+    while (it.hasNext()) {
+      Object nextObject = it.next();
+      if (nextObject instanceof String) {
+        String next = (String) nextObject;
+        response.writeByte(BULK_STRING_ID);
+        response.writeBytes(intToBytes(next.length()));
+        response.writeBytes(CRLFar);
+        response.writeBytes(stringToBytes(next));
+        response.writeBytes(CRLFar);
+      } else if (nextObject instanceof ByteArrayWrapper) {
+        byte[] next = ((ByteArrayWrapper) nextObject).toBytes();
+        response.writeByte(BULK_STRING_ID);
+        response.writeBytes(intToBytes(next.length));
+        response.writeBytes(CRLFar);
+        response.writeBytes(next);
+        response.writeBytes(CRLFar);
+      }
+    }
+    return response;
+  }
+
+  public static final ByteBuf getEmptyArrayResponse(ByteBufAllocator alloc) {
+    ByteBuf buf = alloc.buffer().writeBytes(bEMPTY_ARRAY);
+    return buf;
+  }
+
+  public static final ByteBuf getSimpleStringResponse(ByteBufAllocator alloc, String string)
{
+    byte[] simpAr = stringToBytes(string);
+
+    ByteBuf response = alloc.buffer(simpAr.length + 20);
+    response.writeByte(SIMPLE_STRING_ID);
+    response.writeBytes(simpAr);
+    response.writeBytes(CRLFar);
+    return response;
+  }
+
+  public static final ByteBuf getErrorResponse(ByteBufAllocator alloc, String error) {
+    byte[] errorAr = stringToBytes(error);
+    ByteBuf response = alloc.buffer(errorAr.length + 25);
+    response.writeByte(ERROR_ID);
+    response.writeBytes(err);
+    response.writeBytes(errorAr);
+    response.writeBytes(CRLFar);
+    return response;
+  }
+
+  public static final ByteBuf getNoAuthResponse(ByteBufAllocator alloc, String error) {
+    byte[] errorAr = stringToBytes(error);
+    ByteBuf response = alloc.buffer(errorAr.length + 25);
+    response.writeByte(ERROR_ID);
+    response.writeBytes(noAuth);
+    response.writeBytes(errorAr);
+    response.writeBytes(CRLFar);
+    return response;
+  }
+
+  public static final ByteBuf getWrongTypeResponse(ByteBufAllocator alloc, String error)
{
+    byte[] errorAr = stringToBytes(error);
+    ByteBuf response = alloc.buffer(errorAr.length + 31);
+    response.writeByte(ERROR_ID);
+    response.writeBytes(wrongType);
+    response.writeBytes(errorAr);
+    response.writeBytes(CRLFar);
+    return response;
+  }
+
+  public static final ByteBuf getIntegerResponse(ByteBufAllocator alloc, int integer) {
+    ByteBuf response = alloc.buffer(15);
+    response.writeByte(INTEGER_ID);
+    response.writeBytes(intToBytes(integer));
+    response.writeBytes(CRLFar);
+    return response;
+  }
+
+  public static final ByteBuf getIntegerResponse(ByteBufAllocator alloc, long l) {
+    ByteBuf response = alloc.buffer(25);
+    response.writeByte(INTEGER_ID);
+    response.writeBytes(longToBytes(l));
+    response.writeBytes(CRLFar);
+    return response;
+  }
+
+  public static final ByteBuf getNilResponse(ByteBufAllocator alloc) {
+    ByteBuf buf = alloc.buffer().writeBytes(bNIL);
+    return buf;
+  }
+
+  public static ByteBuf getBulkStringArrayResponseOfValues(ByteBufAllocator alloc,
+      Collection<?> items) {
+    Iterator<?> it = items.iterator();
+    ByteBuf response = alloc.buffer();
+    response.writeByte(Coder.ARRAY_ID);
+    ByteBuf tmp = alloc.buffer();
+    int size = 0;
+    while (it.hasNext()) {
+      Object next = it.next();
+      ByteArrayWrapper nextWrapper = null;
+      if (next instanceof Entry) {
+        try {
+          nextWrapper = (ByteArrayWrapper) ((Entry<?, ?>) next).getValue();
+        } catch (EntryDestroyedException e) {
+          continue;
+        }
+      } else if (next instanceof Struct) {
+        nextWrapper = (ByteArrayWrapper) ((Struct) next).getFieldValues()[1];
+      }
+      if (nextWrapper != null) {
+        tmp.writeByte(Coder.BULK_STRING_ID);
+        tmp.writeBytes(intToBytes(nextWrapper.length()));
+        tmp.writeBytes(Coder.CRLFar);
+        tmp.writeBytes(nextWrapper.toBytes());
+        tmp.writeBytes(Coder.CRLFar);
+      } else {
+        tmp.writeBytes(Coder.bNIL);
+      }
+      size++;
+    }
+
+    response.writeBytes(intToBytes(size));
+    response.writeBytes(Coder.CRLFar);
+    response.writeBytes(tmp);
+
+    tmp.release();
+
+    return response;
+  }
+
+  public static ByteBuf zRangeResponse(ByteBufAllocator alloc, Collection<?> list,
+      boolean withScores) {
+    if (list.isEmpty())
+      return Coder.getEmptyArrayResponse(alloc);
+
+    ByteBuf buffer = alloc.buffer();
+    buffer.writeByte(Coder.ARRAY_ID);
+    ByteBuf tmp = alloc.buffer();
+    int size = 0;
+
+    for (Object entry : list) {
+      ByteArrayWrapper key;
+      DoubleWrapper score;
+      if (entry instanceof Entry) {
+        try {
+          key = (ByteArrayWrapper) ((Entry<?, ?>) entry).getKey();
+          score = (DoubleWrapper) ((Entry<?, ?>) entry).getValue();
+        } catch (EntryDestroyedException e) {
+          continue;
+        }
+      } else {
+        Object[] fieldVals = ((Struct) entry).getFieldValues();
+        key = (ByteArrayWrapper) fieldVals[0];
+        score = (DoubleWrapper) fieldVals[1];
+      }
+      byte[] byteAr = key.toBytes();
+      tmp.writeByte(Coder.BULK_STRING_ID);
+      tmp.writeBytes(intToBytes(byteAr.length));
+      tmp.writeBytes(Coder.CRLFar);
+      tmp.writeBytes(byteAr);
+      tmp.writeBytes(Coder.CRLFar);
+      size++;
+      if (withScores) {
+        String scoreString = score.toString();
+        byte[] scoreAr = stringToBytes(scoreString);
+        tmp.writeByte(Coder.BULK_STRING_ID);
+        tmp.writeBytes(intToBytes(scoreString.length()));
+        tmp.writeBytes(Coder.CRLFar);
+        tmp.writeBytes(scoreAr);
+        tmp.writeBytes(Coder.CRLFar);
+        size++;
+      }
+    }
+
+    buffer.writeBytes(intToBytes(size));
+    buffer.writeBytes(Coder.CRLFar);
+    buffer.writeBytes(tmp);
+
+    tmp.release();
+
+    return buffer;
+  }
+
+  public static ByteBuf getArrayOfNils(ByteBufAllocator alloc, int length) {
+    ByteBuf response = alloc.buffer();
+    response.writeByte(Coder.ARRAY_ID);
+    response.writeBytes(intToBytes(length));
+    response.writeBytes(Coder.CRLFar);
+
+    for (int i = 0; i < length; i++)
+      response.writeBytes(bNIL);
+
+    return response;
+  }
+
+  public static String bytesToString(byte[] bytes) {
+    if (bytes == null)
+      return null;
+    try {
+      return new String(bytes, CHARSET).intern();
+    } catch (UnsupportedEncodingException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public static String doubleToString(double d) {
+    if (d == Double.POSITIVE_INFINITY)
+      return "Infinity";
+    else if (d == Double.NEGATIVE_INFINITY)
+      return "-Infinity";
+    return String.valueOf(d);
+  }
+
+  public static byte[] stringToBytes(String string) {
+    if (string == null || string.equals(""))
+      return null;
+    try {
+      return string.getBytes(CHARSET);
+    } catch (UnsupportedEncodingException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public static ByteArrayWrapper stringToByteArrayWrapper(String s) {
+    return new ByteArrayWrapper(stringToBytes(s));
+  }
+
+  /*
+   * These toByte methods convert to byte arrays of the string representation of the input,
not
+   * literal to byte
+   */
+
+  public static byte[] intToBytes(int i) {
+    return stringToBytes(String.valueOf(i));
+  }
+
+  public static byte[] longToBytes(long l) {
+    return stringToBytes(String.valueOf(l));
+  }
+
+  public static byte[] doubleToBytes(double d) {
+    return stringToBytes(doubleToString(d));
+  }
+
+  public static int bytesToInt(byte[] bytes) {
+    return Integer.parseInt(bytesToString(bytes));
+  }
+
+  public static long bytesToLong(byte[] bytes) {
+    return Long.parseLong(bytesToString(bytes));
+  }
+
+  /**
+   * A conversion where the byte array actually represents a string, so it is converted as
a string
+   * not as a literal double
+   * 
+   * @param bytes Array holding double
+   * @return Parsed value
+   * @throws NumberFormatException if bytes to string does not yield a convertible double
+   */
+  public static Double bytesToDouble(byte[] bytes) {
+    return stringToDouble(bytesToString(bytes));
+  }
+
+  /**
+   * Redis specific manner to parse floats
+   * 
+   * @param d String holding double
+   * @return Value of string
+   * @throws NumberFormatException if the double cannot be parsed
+   */
+  public static double stringToDouble(String d) {
+    if (d.equalsIgnoreCase(P_INF))
+      return Double.POSITIVE_INFINITY;
+    else if (d.equalsIgnoreCase(N_INF))
+      return Double.NEGATIVE_INFINITY;
+    else
+      return Double.parseDouble(d);
+  }
+
+  public static ByteArrayWrapper stringToByteWrapper(String s) {
+    return new ByteArrayWrapper(stringToBytes(s));
+  }
+
+}


Mime
View raw message