[jboss-cvs] JBoss Messaging SVN: r5913 - in trunk: tests/src/org/jboss/messaging/tests/timing/util and 1 other directory.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Fri Feb 20 14:58:52 EST 2009


Author: clebert.suconic at jboss.com
Date: 2009-02-20 14:58:52 -0500 (Fri, 20 Feb 2009)
New Revision: 5913

Added:
   trunk/src/main/org/jboss/messaging/util/UTFUtil.java
   trunk/tests/src/org/jboss/messaging/tests/timing/util/UTF8Test.java
Log:
https://jira.jboss.org/jira/browse/JBMESSAGING-1320 - Adding Utility, we will decide later if we will use it or not

Added: trunk/src/main/org/jboss/messaging/util/UTFUtil.java
===================================================================
--- trunk/src/main/org/jboss/messaging/util/UTFUtil.java	                        (rev 0)
+++ trunk/src/main/org/jboss/messaging/util/UTFUtil.java	2009-02-20 19:58:52 UTC (rev 5913)
@@ -0,0 +1,374 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.messaging.util;
+
+import java.io.IOException;
+
+import org.jboss.messaging.core.logging.Logger;
+import org.jboss.messaging.core.remoting.spi.MessagingBuffer;
+
+/**
+ * 
+ * A UTFUtil
+ *
+ * @author <a href="mailto:clebert.suconic at jboss.org">Clebert Suconic</a>
+ * 
+ * Created Feb 20, 2009 1:37:18 PM
+ *
+ *
+ */
+public class UTFUtil
+{
+   static boolean optimizeStrings = true;
+
+   private static final Logger log = Logger.getLogger(UTFUtil.class);
+
+   private static final boolean isDebug = log.isDebugEnabled();
+
+   private static ThreadLocal<StringUtilBuffer> currenBuffer = new ThreadLocal<StringUtilBuffer>();
+
+   private static void flushByteBuffer(final MessagingBuffer out, final byte[] byteBuffer, final Position pos) throws IOException
+   {
+      out.putBytes(byteBuffer, 0, pos.pos);
+      pos.pos = 0;
+   }
+
+   public static void saveUTF(final MessagingBuffer out, final String str) throws IOException
+   {
+      StringUtilBuffer buffer = getThreadLocalBuffer();
+
+      int len = calculateUTFSize(str, buffer);
+      if (len > 0xffff)
+      {
+         out.putBoolean(true);
+         out.putInt(len);
+      }
+      else
+      {
+         out.putBoolean(false);
+         out.putShort((short)len);
+      }
+
+      if (len == (long)str.length())
+      {
+         if (len > buffer.byteBuffer.length)
+         {
+            buffer.resizeByteBuffer(len);
+         }
+
+         for (int byteLocation = 0; byteLocation < len; byteLocation++)
+         {
+            buffer.byteBuffer[byteLocation] = (byte)buffer.charBuffer[byteLocation];
+         }
+         out.putBytes(buffer.byteBuffer, 0, len);
+      }
+      else
+      {
+         if (isDebug)
+         {
+            log.debug("Saving string with utfSize=" + len + " stringSize=" + str.length());
+         }
+
+         Position pos = buffer.position.reset();
+
+         int stringLength = str.length();
+         for (int bufferPosition = 0; bufferPosition < stringLength;)
+         {
+            int countArray = Math.min(stringLength - bufferPosition, buffer.charBuffer.length);
+            str.getChars(bufferPosition, bufferPosition + countArray, buffer.charBuffer, 0);
+
+            for (int i = 0; i < countArray; i++)
+            {
+               char charAtPos = buffer.charBuffer[i];
+               if (charAtPos >= 1 && charAtPos < 0x7f)
+               {
+                  if (pos.pos >= buffer.byteBuffer.length)
+                  {
+                     flushByteBuffer(out, buffer.byteBuffer, pos);
+                  }
+                  buffer.byteBuffer[pos.pos++] = (byte)charAtPos;
+               }
+               else if (charAtPos >= 0x800)
+               {
+                  if (pos.pos + 3 >= buffer.byteBuffer.length)
+                  {
+                     flushByteBuffer(out, buffer.byteBuffer, pos);
+                  }
+
+                  buffer.byteBuffer[pos.pos++] = (byte)(0xE0 | charAtPos >> 12 & 0x0F);
+                  buffer.byteBuffer[pos.pos++] = (byte)(0x80 | charAtPos >> 6 & 0x3F);
+                  buffer.byteBuffer[pos.pos++] = (byte)(0x80 | charAtPos >> 0 & 0x3F);
+               }
+               else
+               {
+                  if (pos.pos + 2 >= buffer.byteBuffer.length)
+                  {
+                     flushByteBuffer(out, buffer.byteBuffer, pos);
+                  }
+
+                  buffer.byteBuffer[pos.pos++] = (byte)(0xC0 | charAtPos >> 6 & 0x1F);
+                  buffer.byteBuffer[pos.pos++] = (byte)(0x80 | charAtPos >> 0 & 0x3F);
+
+               }
+            }
+
+            bufferPosition += countArray;
+         }
+         flushByteBuffer(out, buffer.byteBuffer, pos);
+      }
+   }
+
+   public static String readUTF(final MessagingBuffer input) throws IOException
+   {
+      StringUtilBuffer buffer = getThreadLocalBuffer();
+
+      long size = 0;
+
+      boolean isLong = input.getBoolean();
+
+      if (isLong)
+      {
+         size = input.getInt();
+      }
+      else
+      {
+         size = input.getShort();
+      }
+
+      if (isDebug)
+      {
+         log.debug("Reading string with utfSize=" + size + " isLong=" + isLong);
+      }
+
+      long count = 0;
+      int byte1, byte2, byte3;
+      int charCount = 0;
+      Position pos = buffer.position.reset();;
+      StringBuffer strbuffer = null;
+
+      while (count < size)
+      {
+         if (pos.pos >= pos.size)
+         {
+            if (isDebug)
+            {
+               log.debug("readString::pulling data to Buffer at pos " + pos.pos + " size= " + pos.size);
+            }
+            pullDataFromBuffer(input, pos, buffer.byteBuffer, count, size);
+         }
+         byte1 = buffer.byteBuffer[pos.pos++];
+         count++;
+
+         if (byte1 > 0 && byte1 <= 0x7F)
+         {
+            buffer.charBuffer[charCount++] = (char)byte1;
+         }
+         else
+         {
+            int c = byte1 & 0xff;
+            switch (c >> 4)
+            {
+               case 0xc:
+               case 0xd:
+                  if (pos.pos >= pos.size)
+                  {
+                     if (isDebug)
+                     {
+                        log.debug("readString::pulling data to Buffer at pos test1 " + pos.pos + " size= " + pos.size);
+                     }
+                     pullDataFromBuffer(input, pos, buffer.byteBuffer, count, size);
+                  }
+                  byte2 = buffer.byteBuffer[pos.pos++];
+                  buffer.charBuffer[charCount++] = (char)((c & 0x1F) << 6 | byte2 & 0x3F);
+                  count++;
+                  break;
+               case 0xe:
+                  if (pos.pos >= pos.size)
+                  {
+                     if (isDebug)
+                     {
+                        log.debug("readString::pulling data to Buffer at pos test2 " + pos.pos + " size= " + pos.size);
+                     }
+                     pullDataFromBuffer(input, pos, buffer.byteBuffer, count, size);
+                  }
+                  byte2 = buffer.byteBuffer[pos.pos++];
+                  count++;
+                  if (pos.pos >= pos.size)
+                  {
+                     pullDataFromBuffer(input, pos, buffer.byteBuffer, count, size);
+                  }
+                  byte3 = buffer.byteBuffer[pos.pos++];
+                  buffer.charBuffer[charCount++] = (char)((c & 0x0F) << 12 | (byte2 & 0x3F) << 6 | (byte3 & 0x3F) << 0);
+                  count++;
+
+                  break;
+            }
+         }
+
+         if (charCount == buffer.charBuffer.length)
+         {
+            if (strbuffer == null)
+            {
+               strbuffer = new StringBuffer((int)size);
+            }
+            strbuffer.append(buffer.charBuffer);
+            charCount = 0;
+         }
+      }
+
+      if (strbuffer != null)
+      {
+         strbuffer.append(buffer.charBuffer, 0, charCount);
+         return strbuffer.toString();
+      }
+      else
+      {
+         return new String(buffer.charBuffer, 0, charCount);
+      }
+
+   }
+
+   private static StringUtilBuffer getThreadLocalBuffer()
+   {
+      StringUtilBuffer retValue = currenBuffer.get();
+      if (retValue == null)
+      {
+         retValue = new StringUtilBuffer();
+         currenBuffer.set(retValue);
+      }
+
+      return retValue;
+   }
+
+   private static void pullDataFromBuffer(final MessagingBuffer input,
+                                          final Position pos,
+                                          final byte[] byteBuffer,
+                                          final long currentPosition,
+                                          final long size) throws IOException
+   {
+      pos.pos = 0;
+
+      pos.size = (int)Math.min(size - currentPosition, byteBuffer.length);
+
+      input.getBytes(byteBuffer, 0, (int)pos.size);
+   }
+
+   public static int calculateUTFSize(final String str, final StringUtilBuffer stringBuffer)
+   {
+      int calculatedLen = 0;
+      int stringLength = str.length();
+      if (stringLength > stringBuffer.charBuffer.length)
+      {
+         stringBuffer.resizeCharBuffer(stringLength);
+      }
+      str.getChars(0, stringLength, stringBuffer.charBuffer, 0);
+
+      for (int i = 0; i < stringLength; i++)
+      {
+         char c = stringBuffer.charBuffer[i];
+
+         if (c >= 1 && c < 0x7f)
+         {
+            calculatedLen++;
+         }
+         else if (c >= 0x800)
+         {
+            calculatedLen += 3;
+         }
+         else
+         {
+            calculatedLen += 2;
+         }
+
+      }
+
+      return calculatedLen;
+   }
+
+   /* A way to pass an integer as a parameter to a method */
+   public static class Position
+   {
+      int pos;
+
+      long size;
+
+      public Position reset()
+      {
+         pos = 0;
+         size = 0;
+         return this;
+      }
+   }
+
+   private static class StringUtilBuffer
+   {
+
+      Position position = new Position();
+
+      public char charBuffer[];
+
+      public byte byteBuffer[];
+
+      public void resizeCharBuffer(final int newSize)
+      {
+         if (newSize <= charBuffer.length)
+         {
+            throw new RuntimeException("New buffer can't be smaller");
+         }
+         char[] newCharBuffer = new char[newSize];
+         for (int i = 0; i < charBuffer.length; i++)
+         {
+            newCharBuffer[i] = charBuffer[i];
+         }
+         charBuffer = newCharBuffer;
+      }
+
+      public void resizeByteBuffer(final int newSize)
+      {
+         System.out.println("Buffer size = " + newSize);
+         if (newSize <= byteBuffer.length)
+         {
+            throw new RuntimeException("New buffer can't be smaller");
+         }
+         byte[] newByteBuffer = new byte[newSize];
+         for (int i = 0; i < byteBuffer.length; i++)
+         {
+            newByteBuffer[i] = byteBuffer[i];
+         }
+         byteBuffer = newByteBuffer;
+      }
+
+      public StringUtilBuffer()
+      {
+         this(1024, 1024);
+      }
+
+      public StringUtilBuffer(final int sizeChar, final int sizeByte)
+      {
+         charBuffer = new char[sizeChar];
+         byteBuffer = new byte[sizeByte];
+      }
+
+   }
+
+}

Added: trunk/tests/src/org/jboss/messaging/tests/timing/util/UTF8Test.java
===================================================================
--- trunk/tests/src/org/jboss/messaging/tests/timing/util/UTF8Test.java	                        (rev 0)
+++ trunk/tests/src/org/jboss/messaging/tests/timing/util/UTF8Test.java	2009-02-20 19:58:52 UTC (rev 5913)
@@ -0,0 +1,176 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.messaging.tests.timing.util;
+
+import junit.framework.TestCase;
+
+import org.jboss.messaging.integration.transports.netty.ChannelBufferWrapper;
+import org.jboss.messaging.util.UTFUtil;
+
+public class UTF8Test extends TestCase
+{
+
+   private final String str = "abcdef&^*&!^ghijkl\uB5E2\uCAC7\uB2BB\uB7DD\uB7C7\uB3A3\uBCE4\uB5A5" + "abcdef&^*&!^ghijkl\uB5E2\uCAC7\uB2BB\uB7DD\uB7C7\uB3A3\uBCE4\uB5A5"
+                              + "abcdef&^*&!^ghijkl\uB5E2\uCAC7\uB2BB\uB7DD\uB7C7\uB3A3\uBCE4\uB5A5"
+                              + "abcdef&^*&!^ghijkl\uB5E2\uCAC7\uB2BB\uB7DD\uB7C7\uB3A3\uBCE4\uB5A5"
+                              + "abcdef&^*&!^ghijkl\uB5E2\uCAC7\uB2BB\uB7DD\uB7C7\uB3A3\uBCE4\uB5A5"
+                              + "abcdef&^*&!^ghijkl\uB5E2\uCAC7\uB2BB\uB7DD\uB7C7\uB3A3\uBCE4\uB5A5"
+                              + "abcdef&^*&!^ghijkl\uB5E2\uCAC7\uB2BB\uB7DD\uB7C7\uB3A3\uBCE4\uB5A5"
+                              + "abcdef&^*&!^ghijkl\uB5E2\uCAC7\uB2BB\uB7DD\uB7C7\uB3A3\uBCE4\uB5A5"
+                              + "abcdef&^*&!^ghijkl\uB5E2\uCAC7\uB2BB\uB7DD\uB7C7\uB3A3\uBCE4\uB5A5";
+
+   final int TIMES = 5;
+   final long numberOfIteractions = 1000000;
+
+   // Attributes ----------------------------------------------------
+
+   // Static --------------------------------------------------------
+
+   // Constructors --------------------------------------------------
+
+   // Public --------------------------------------------------------
+
+
+   public void testValidateUTF() throws Exception
+   {
+      ChannelBufferWrapper buffer = new ChannelBufferWrapper(10 * 1024);
+
+      UTFUtil.saveUTF(buffer, str);
+
+      buffer.rewind();
+
+      String newStr = UTFUtil.readUTF(buffer);
+
+      assertEquals(str, newStr);
+   }
+
+   public void testUTF() throws Exception
+   {
+      ChannelBufferWrapper buffer = new ChannelBufferWrapper(10 * 1024);
+
+      long start = System.currentTimeMillis();
+
+      for (int c = 0; c < TIMES; c++)
+      {
+         for (long i = 0; i < numberOfIteractions; i++)
+         {
+            if (i == 10000)
+            {
+               start = System.currentTimeMillis();
+            }
+
+            buffer.rewind();
+            buffer.putUTF(str);
+         }
+
+         long spentTime = System.currentTimeMillis() - start;
+
+         System.out.println("Time WriteUTF = " + spentTime);
+      }
+
+   }
+
+   public void testReadUTF() throws Exception
+   {
+      ChannelBufferWrapper buffer = new ChannelBufferWrapper(10 * 1024);
+
+      buffer.putUTF(str);
+
+      long start = System.currentTimeMillis();
+
+      for (int c = 0; c < TIMES; c++)
+      {
+         for (long i = 0; i < numberOfIteractions; i++)
+         {
+            if (i == 10000)
+            {
+               start = System.currentTimeMillis();
+            }
+
+            buffer.rewind();
+            String newstr = buffer.getUTF();
+            assertEquals(str, newstr);
+         }
+
+         long spentTime = System.currentTimeMillis() - start;
+
+         System.out.println("Time readUTF = " + spentTime);
+      }
+
+   }
+
+   public void testNewUTF() throws Exception
+   {
+      ChannelBufferWrapper buffer = new ChannelBufferWrapper(10 * 1024);
+
+      long start = System.currentTimeMillis();
+
+      for (int c = 0; c < TIMES; c++)
+      {
+         for (long i = 0; i < numberOfIteractions; i++)
+         {
+            if (i == 10000)
+            {
+               start = System.currentTimeMillis();
+            }
+
+            buffer.rewind();
+            UTFUtil.saveUTF(buffer, str);
+         }
+
+         long spentTime = System.currentTimeMillis() - start;
+
+         System.out.println("time NewUTF = " + spentTime);
+      }
+
+   }
+
+   public void testReadNewUTF() throws Exception
+   {
+      ChannelBufferWrapper buffer = new ChannelBufferWrapper(10 * 1024);
+
+      UTFUtil.saveUTF(buffer, str);
+
+      long start = System.currentTimeMillis();
+
+      for (int c = 0; c < TIMES; c++)
+      {
+         for (long i = 0; i < numberOfIteractions; i++)
+         {
+            if (i == 10000)
+            {
+               start = System.currentTimeMillis();
+            }
+
+            buffer.rewind();
+            String newstr = UTFUtil.readUTF(buffer);
+            assertEquals(str, newstr);
+         }
+
+         long spentTime = System.currentTimeMillis() - start;
+
+         System.out.println("spentTime readUTFNew = " + spentTime);
+      }
+
+   }
+}




More information about the jboss-cvs-commits mailing list