You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by sl...@apache.org on 2011/07/29 19:02:39 UTC

svn commit: r1152303 - in /cassandra/trunk: ./ contrib/ interface/thrift/gen-java/org/apache/cassandra/thrift/ src/java/org/apache/cassandra/utils/ test/unit/org/apache/cassandra/utils/

Author: slebresne
Date: Fri Jul 29 17:02:38 2011
New Revision: 1152303

URL: http://svn.apache.org/viewvc?rev=1152303&view=rev
Log:
merge from 0.8

Modified:
    cassandra/trunk/   (props changed)
    cassandra/trunk/CHANGES.txt
    cassandra/trunk/contrib/   (props changed)
    cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java   (props changed)
    cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/Column.java   (props changed)
    cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/InvalidRequestException.java   (props changed)
    cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/NotFoundException.java   (props changed)
    cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/SuperColumn.java   (props changed)
    cassandra/trunk/src/java/org/apache/cassandra/utils/ByteBufferUtil.java
    cassandra/trunk/src/java/org/apache/cassandra/utils/FBUtilities.java
    cassandra/trunk/test/unit/org/apache/cassandra/utils/ByteBufferUtilTest.java

Propchange: cassandra/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Jul 29 17:02:38 2011
@@ -1,7 +1,7 @@
 /cassandra/branches/cassandra-0.6:922689-1052356,1052358-1053452,1053454,1053456-1131291
 /cassandra/branches/cassandra-0.7:1026516-1151306
 /cassandra/branches/cassandra-0.7.0:1053690-1055654
-/cassandra/branches/cassandra-0.8:1090934-1125013,1125019-1152110
+/cassandra/branches/cassandra-0.8:1090934-1125013,1125019-1152110,1152265
 /cassandra/branches/cassandra-0.8.0:1125021-1130369
 /cassandra/branches/cassandra-0.8.1:1101014-1125018
 /cassandra/tags/cassandra-0.7.0-rc3:1051699-1053689

Modified: cassandra/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/cassandra/trunk/CHANGES.txt?rev=1152303&r1=1152302&r2=1152303&view=diff
==============================================================================
--- cassandra/trunk/CHANGES.txt (original)
+++ cassandra/trunk/CHANGES.txt Fri Jul 29 17:02:38 2011
@@ -37,6 +37,7 @@
  * log Java classpath on startup (CASSANDRA-2895)
  * keep gossipped version in sync with actual on migration coordinator 
    (CASSANDRA-2946)
+ * speedup bytes to hex conversions dramatically (CASSANDRA-2850)
 
 
 0.8.2

Propchange: cassandra/trunk/contrib/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Jul 29 17:02:38 2011
@@ -1,7 +1,7 @@
 /cassandra/branches/cassandra-0.6/contrib:922689-1052356,1052358-1053452,1053454,1053456-1068009
 /cassandra/branches/cassandra-0.7/contrib:1026516-1151306
 /cassandra/branches/cassandra-0.7.0/contrib:1053690-1055654
-/cassandra/branches/cassandra-0.8/contrib:1090934-1125013,1125019-1152110
+/cassandra/branches/cassandra-0.8/contrib:1090934-1125013,1125019-1152110,1152265
 /cassandra/branches/cassandra-0.8.0/contrib:1125021-1130369
 /cassandra/branches/cassandra-0.8.1/contrib:1101014-1125018
 /cassandra/tags/cassandra-0.7.0-rc3/contrib:1051699-1053689

Propchange: cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Jul 29 17:02:38 2011
@@ -1,7 +1,7 @@
 /cassandra/branches/cassandra-0.6/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java:922689-1052356,1052358-1053452,1053454,1053456-1131291
 /cassandra/branches/cassandra-0.7/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java:1026516-1151306
 /cassandra/branches/cassandra-0.7.0/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java:1053690-1055654
-/cassandra/branches/cassandra-0.8/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java:1090934-1125013,1125019-1152110
+/cassandra/branches/cassandra-0.8/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java:1090934-1125013,1125019-1152110,1152265
 /cassandra/branches/cassandra-0.8.0/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java:1125021-1130369
 /cassandra/branches/cassandra-0.8.1/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java:1101014-1125018
 /cassandra/tags/cassandra-0.7.0-rc3/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java:1051699-1053689

Propchange: cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/Column.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Jul 29 17:02:38 2011
@@ -1,7 +1,7 @@
 /cassandra/branches/cassandra-0.6/interface/thrift/gen-java/org/apache/cassandra/thrift/Column.java:922689-1052356,1052358-1053452,1053454,1053456-1131291
 /cassandra/branches/cassandra-0.7/interface/thrift/gen-java/org/apache/cassandra/thrift/Column.java:1026516-1151306
 /cassandra/branches/cassandra-0.7.0/interface/thrift/gen-java/org/apache/cassandra/thrift/Column.java:1053690-1055654
-/cassandra/branches/cassandra-0.8/interface/thrift/gen-java/org/apache/cassandra/thrift/Column.java:1090934-1125013,1125019-1152110
+/cassandra/branches/cassandra-0.8/interface/thrift/gen-java/org/apache/cassandra/thrift/Column.java:1090934-1125013,1125019-1152110,1152265
 /cassandra/branches/cassandra-0.8.0/interface/thrift/gen-java/org/apache/cassandra/thrift/Column.java:1125021-1130369
 /cassandra/branches/cassandra-0.8.1/interface/thrift/gen-java/org/apache/cassandra/thrift/Column.java:1101014-1125018
 /cassandra/tags/cassandra-0.7.0-rc3/interface/thrift/gen-java/org/apache/cassandra/thrift/Column.java:1051699-1053689

Propchange: cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/InvalidRequestException.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Jul 29 17:02:38 2011
@@ -1,7 +1,7 @@
 /cassandra/branches/cassandra-0.6/interface/thrift/gen-java/org/apache/cassandra/thrift/InvalidRequestException.java:922689-1052356,1052358-1053452,1053454,1053456-1131291
 /cassandra/branches/cassandra-0.7/interface/thrift/gen-java/org/apache/cassandra/thrift/InvalidRequestException.java:1026516-1151306
 /cassandra/branches/cassandra-0.7.0/interface/thrift/gen-java/org/apache/cassandra/thrift/InvalidRequestException.java:1053690-1055654
-/cassandra/branches/cassandra-0.8/interface/thrift/gen-java/org/apache/cassandra/thrift/InvalidRequestException.java:1090934-1125013,1125019-1152110
+/cassandra/branches/cassandra-0.8/interface/thrift/gen-java/org/apache/cassandra/thrift/InvalidRequestException.java:1090934-1125013,1125019-1152110,1152265
 /cassandra/branches/cassandra-0.8.0/interface/thrift/gen-java/org/apache/cassandra/thrift/InvalidRequestException.java:1125021-1130369
 /cassandra/branches/cassandra-0.8.1/interface/thrift/gen-java/org/apache/cassandra/thrift/InvalidRequestException.java:1101014-1125018
 /cassandra/tags/cassandra-0.7.0-rc3/interface/thrift/gen-java/org/apache/cassandra/thrift/InvalidRequestException.java:1051699-1053689

Propchange: cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/NotFoundException.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Jul 29 17:02:38 2011
@@ -1,7 +1,7 @@
 /cassandra/branches/cassandra-0.6/interface/thrift/gen-java/org/apache/cassandra/thrift/NotFoundException.java:922689-1052356,1052358-1053452,1053454,1053456-1131291
 /cassandra/branches/cassandra-0.7/interface/thrift/gen-java/org/apache/cassandra/thrift/NotFoundException.java:1026516-1151306
 /cassandra/branches/cassandra-0.7.0/interface/thrift/gen-java/org/apache/cassandra/thrift/NotFoundException.java:1053690-1055654
-/cassandra/branches/cassandra-0.8/interface/thrift/gen-java/org/apache/cassandra/thrift/NotFoundException.java:1090934-1125013,1125019-1152110
+/cassandra/branches/cassandra-0.8/interface/thrift/gen-java/org/apache/cassandra/thrift/NotFoundException.java:1090934-1125013,1125019-1152110,1152265
 /cassandra/branches/cassandra-0.8.0/interface/thrift/gen-java/org/apache/cassandra/thrift/NotFoundException.java:1125021-1130369
 /cassandra/branches/cassandra-0.8.1/interface/thrift/gen-java/org/apache/cassandra/thrift/NotFoundException.java:1101014-1125018
 /cassandra/tags/cassandra-0.7.0-rc3/interface/thrift/gen-java/org/apache/cassandra/thrift/NotFoundException.java:1051699-1053689

Propchange: cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/SuperColumn.java
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Jul 29 17:02:38 2011
@@ -1,7 +1,7 @@
 /cassandra/branches/cassandra-0.6/interface/thrift/gen-java/org/apache/cassandra/thrift/SuperColumn.java:922689-1052356,1052358-1053452,1053454,1053456-1131291
 /cassandra/branches/cassandra-0.7/interface/thrift/gen-java/org/apache/cassandra/thrift/SuperColumn.java:1026516-1151306
 /cassandra/branches/cassandra-0.7.0/interface/thrift/gen-java/org/apache/cassandra/thrift/SuperColumn.java:1053690-1055654
-/cassandra/branches/cassandra-0.8/interface/thrift/gen-java/org/apache/cassandra/thrift/SuperColumn.java:1090934-1125013,1125019-1152110
+/cassandra/branches/cassandra-0.8/interface/thrift/gen-java/org/apache/cassandra/thrift/SuperColumn.java:1090934-1125013,1125019-1152110,1152265
 /cassandra/branches/cassandra-0.8.0/interface/thrift/gen-java/org/apache/cassandra/thrift/SuperColumn.java:1125021-1130369
 /cassandra/branches/cassandra-0.8.1/interface/thrift/gen-java/org/apache/cassandra/thrift/SuperColumn.java:1101014-1125018
 /cassandra/tags/cassandra-0.7.0-rc3/interface/thrift/gen-java/org/apache/cassandra/thrift/SuperColumn.java:1051699-1053689

Modified: cassandra/trunk/src/java/org/apache/cassandra/utils/ByteBufferUtil.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/utils/ByteBufferUtil.java?rev=1152303&r1=1152302&r2=1152303&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/utils/ByteBufferUtil.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/utils/ByteBufferUtil.java Fri Jul 29 17:02:38 2011
@@ -437,7 +437,6 @@ public class ByteBufferUtil
         return ByteBuffer.allocate(8).putDouble(0, d);
     }
 
-
     public static InputStream inputStream(ByteBuffer bytes)
     {
         final ByteBuffer copy = bytes.duplicate();
@@ -473,16 +472,16 @@ public class ByteBufferUtil
 
     public static String bytesToHex(ByteBuffer bytes)
     {
-        StringBuilder sb = new StringBuilder();
-        for (int i = bytes.position(); i < bytes.limit(); i++)
+        final int offset = bytes.position();
+        final int size = bytes.remaining();
+        final char[] c = new char[size * 2];
+        for (int i = 0; i < size; i++)
         {
-            int bint = bytes.get(i) & 0xff;
-            if (bint <= 0xF)
-                // toHexString does not 0 pad its results.
-                sb.append("0");
-            sb.append(Integer.toHexString(bint));
+            final int bint = bytes.get(i+offset);
+            c[i * 2] = FBUtilities.byteToChar[(bint & 0xf0) >> 4];
+            c[1 + i * 2] = FBUtilities.byteToChar[bint & 0x0f];
         }
-        return sb.toString();
+        return FBUtilities.wrapCharArray(c);
     }
 
     public static ByteBuffer hexToBytes(String str)

Modified: cassandra/trunk/src/java/org/apache/cassandra/utils/FBUtilities.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/utils/FBUtilities.java?rev=1152303&r1=1152302&r2=1152303&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/utils/FBUtilities.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/utils/FBUtilities.java Fri Jul 29 17:02:38 2011
@@ -19,6 +19,7 @@
 package org.apache.cassandra.utils;
 
 import java.io.*;
+import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.math.BigInteger;
@@ -63,6 +64,59 @@ public class FBUtilities
     private static volatile InetAddress localInetAddress_;
     private static volatile InetAddress broadcastInetAddress_;
 
+    private final static byte[] charToByte = new byte[256];
+    // package protected for use by ByteBufferUtil. Do not modify this array !!
+    static final char[] byteToChar = new char[16];
+    static
+    {
+        for (char c = 0; c < charToByte.length; ++c)
+        {
+            if (c >= '0' && c <= '9')
+                charToByte[c] = (byte)(c - '0');
+            else if (c >= 'A' && c <= 'F')
+                charToByte[c] = (byte)(c - 'A' + 10);
+            else if (c >= 'a' && c <= 'f')
+                charToByte[c] = (byte)(c - 'a' + 10);
+            else
+                charToByte[c] = (byte)-1;
+        }
+
+        for (int i = 0; i < 16; ++i)
+        {
+            byteToChar[i] = Integer.toHexString(i).charAt(0);
+        }
+    }
+
+    /**
+     * This constructor enables us to construct a String directly by wrapping a char array, with zero-copy.
+     * This can save time, and a lot of memory, when converting large column values.
+     */
+    private static final Constructor<String> stringConstructor = getProtectedConstructor(String.class, int.class, int.class, char[].class);
+
+    /**
+     * Create a String from a char array with zero-copy (if available), using reflection to access a package-protected constructor of String.
+     * */
+    public static String wrapCharArray(char[] c)
+    {
+        if (c == null)
+            return null;
+
+        String s = null;
+
+        if (stringConstructor != null)
+        {
+            try
+            {
+                s = stringConstructor.newInstance(0, c.length, c);
+            }
+            catch (Exception e)
+            {
+                // Swallowing as we'll just use a copying constructor
+            }
+        }
+        return s == null ? new String(c) : s;
+    }
+
     private static final ThreadLocal<MessageDigest> localMD5Digest = new ThreadLocal<MessageDigest>()
     {
         @Override
@@ -314,23 +368,22 @@ public class FBUtilities
         byte[] bytes = new byte[str.length()/2];
         for (int i = 0; i < bytes.length; i++)
         {
-            bytes[i] = (byte)Integer.parseInt(str.substring(i*2, i*2+2), 16);
+            bytes[i] = (byte)((charToByte[str.charAt(i * 2)] << 4) | charToByte[str.charAt(i*2 + 1)]);
         }
         return bytes;
     }
 
     public static String bytesToHex(byte... bytes)
     {
-        StringBuilder sb = new StringBuilder();
-        for (byte b : bytes)
+        char[] c = new char[bytes.length * 2];
+        for (int i = 0; i < bytes.length; i++)
         {
-            int bint = b & 0xff;
-            if (bint <= 0xF)
-                // toHexString does not 0 pad its results.
-                sb.append("0");
-            sb.append(Integer.toHexString(bint));
+            int bint = bytes[i];
+            c[i * 2] = FBUtilities.byteToChar[(bint & 0xf0) >> 4];
+            c[1 + i * 2] = FBUtilities.byteToChar[bint & 0x0f];
         }
-        return sb.toString();
+
+        return wrapCharArray(c);
     }
 
     public static void renameWithConfirm(String tmpFilename, String filename) throws IOException
@@ -591,6 +644,28 @@ public class FBUtilities
         return field;
     }
 
+    /**
+     * Used to get access to protected/private constructor of the specified class
+     * @param klass - name of the class
+     * @param paramTypes - types of the constructor parameters
+     * @return Constructor if successful, null if the constructor cannot be
+     * accessed
+     */
+    public static Constructor getProtectedConstructor(Class klass, Class... paramTypes)
+    {
+        Constructor c;
+        try
+        {
+            c = klass.getDeclaredConstructor(paramTypes);
+            c.setAccessible(true);
+            return c;
+        }
+        catch (Exception e)
+        {
+            return null;
+        }
+    }
+
     public static IRowCacheProvider newCacheProvider(String cache_provider) throws ConfigurationException
     {
         if (!cache_provider.contains("."))

Modified: cassandra/trunk/test/unit/org/apache/cassandra/utils/ByteBufferUtilTest.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/test/unit/org/apache/cassandra/utils/ByteBufferUtilTest.java?rev=1152303&r1=1152302&r2=1152303&view=diff
==============================================================================
--- cassandra/trunk/test/unit/org/apache/cassandra/utils/ByteBufferUtilTest.java (original)
+++ cassandra/trunk/test/unit/org/apache/cassandra/utils/ByteBufferUtilTest.java Fri Jul 29 17:02:38 2011
@@ -227,11 +227,26 @@ public class ByteBufferUtilTest
         for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++)
         {
             ByteBuffer bb = ByteBuffer.allocate(1);
-            bb.put((byte)i);
+            bb.put((byte) i);
             bb.clear();
             String s = ByteBufferUtil.bytesToHex(bb);
             ByteBuffer bb2 = ByteBufferUtil.hexToBytes(s);
-            assert bb.equals(bb2);
+            assertEquals(bb, bb2);
         }
+        // check that non-zero buffer positions work,
+        // i.e. that conversion accounts for the buffer offset and limit correctly
+        ByteBuffer bb = ByteBuffer.allocate(4);
+        for (int i = 0; i < 4; i++)
+        {
+            bb.put((byte) i);
+        }
+        // use a chunk out of the middle of the buffer
+        bb.position(1);
+        bb.limit(3);
+        assertEquals(2, bb.remaining());
+        String s = ByteBufferUtil.bytesToHex(bb);
+        ByteBuffer bb2 = ByteBufferUtil.hexToBytes(s);
+        assertEquals(bb, bb2);
+        assertEquals("0102", s);
     }
 }