[muscle] Assorted java client updates

  • From: Lior Okman <lior.okman@xxxxxxxxxxxxxxxxxx>
  • To: Jeremy Friesner <jaf@xxxxxxxxxxxx>
  • Date: Thu, 28 Dec 2006 20:21:27 +0200


Hi Jeremy,

The attached patch does the following:

1. Use a StringBuffer in toString() methods, instead of concatenating
strings directly.
2. Use the faster ByteBuffer operations to fill in arrays, instead of
looping over the arrays and manually setting the values.
3. Use List instead of Vector and HashMap instead of HashTable. This is
to lose the extra unneeded synchronization point that exists in these
old and deprecated (as of Java 1.2) classes. Since ByteBuffer assumes at
least JDK 1.4, no need to use older API.
4. Use Iterator instead of Enumeration - same reason as item 3.
5. Changed the implementation of Queue.removeAllElements() to a more
efficient implementation.
6. Modified the ThreadPool to use a ThreadGroup and provide thread names
- this makes the class more profiler friendly.


Regards,

Lior
diff -Nur /tmp/muscle/java/com/lcs/muscle/message/Message.java 
com/lcs/muscle/message/Message.java
--- /tmp/muscle/java/com/lcs/muscle/message/Message.java        2006-02-10 
05:16:59.000000000 +0200
+++ com/lcs/muscle/message/Message.java 2006-12-28 19:48:06.000000000 +0200
@@ -9,10 +9,10 @@
 import java.io.UnsupportedEncodingException;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.Hashtable;
+import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
-import java.util.Vector;
+import java.util.Map;
 
 import com.lcs.muscle.support.Flattenable;
 import com.lcs.muscle.support.LEDataInputStream;
@@ -43,7 +43,7 @@
    /** Default Constructor. */
    public Message()
    {
-      if (_empty == null) _empty = new Hashtable();  // IE5 is lame
+      if (_empty == null) _empty = new HashMap();  // IE5 is lame
    }
 
    /** Constructor.
@@ -81,11 +81,11 @@
       clear();
       Message copyMe = (Message)c;
       what = copyMe.what;
-      Enumeration fields = copyMe.fieldNames();
-      while(fields.hasMoreElements()) 
+      Iterator fields = copyMe.fieldNames();
+      while(fields.hasNext()) 
       {
          try {
-            copyMe.copyField((String)fields.nextElement(), this);
+            copyMe.copyField((String)fields.next(), this);
          }
          catch(FieldNotFoundException ex) {
             ex.printStackTrace();  // should never happen
@@ -93,12 +93,12 @@
       }
    }
 
-   /** Returns an Enumeration of Strings that are the
+   /** Returns an Iterator of Strings that are the
      * field names present in this Message
      */
-   public Enumeration fieldNames()
+   public Iterator fieldNames()
    {
-      return (_fieldTable != null) ? _fieldTable.keys() : _empty.keys();
+      return (_fieldTable != null) ? _fieldTable.keySet().iterator() : 
_empty.keySet().iterator();
    }
 
    /** Returns the given 'what' constant as a human readable 4-byte string, 
e.g. "BOOL", "BYTE", etc.
@@ -124,10 +124,10 @@
       if (type == B_ANY_TYPE) return _fieldTable.size();
       
       int count = 0;
-      Enumeration e = _fieldTable.elements();
-      while(e.hasMoreElements())
+      Iterator e = _fieldTable.values().iterator();
+      while(e.hasNext())
       {
-         MessageField field = (MessageField) e.nextElement();
+         MessageField field = (MessageField) e.next();
          if (field.typeCode() == type) count++;
       }
       return count;
@@ -142,15 +142,16 @@
    /** Returns a string that is a summary of the contents of this Message.  
Good for debugging. */
    public String toString()
    {
-      String ret = "Message:  what='" + whatString(what) + "' ("+what+"), 
countFields=" + countFields() + ", flattenedSize=" + flattenedSize() + "\n";
-      // Better to not use the keyword "enum" - it is reserved in JDK 1.5
-      Enumeration enumeration = fieldNames();
-      while(enumeration.hasMoreElements())
+         StringBuffer ret = new StringBuffer();
+      ret.append("Message:  what='").append(whatString(what)).append("' 
(").append(what).append("), countFields=")
+        .append(countFields()).append(", 
flattenedSize=").append(flattenedSize()).append('\n');
+      Iterator iterator = fieldNames();
+      while(iterator.hasNext())
       {
-         String fieldName = (String) enumeration.nextElement();
-         ret += "   " + fieldName + ": " + 
_fieldTable.get(fieldName).toString() + "\n";
+         String fieldName = (String) iterator.next();
+         ret.append("   ").append(fieldName).append(": 
").append(_fieldTable.get(fieldName)).append('\n');
       }
-      return ret;
+      return ret.toString();
    }
    
    /** Renames a field.
@@ -177,10 +178,10 @@
       int sum = 4 + 4 + 4;  // 4 bytes for the protocol revision #, 4 bytes 
for the number-of-entries field, 4 bytes for what code
       if (_fieldTable != null)
       {
-         Enumeration e = fieldNames();
-         while(e.hasMoreElements())
+         Iterator e = fieldNames();
+         while(e.hasNext())
          {
-            String fieldName = (String) e.nextElement();
+            String fieldName = (String) e.next();
             MessageField field = (MessageField) _fieldTable.get(fieldName);
  
             // 4 bytes for the name length, name data, 4 bytes for entry type 
code, 4 bytes for entry data length, entry data
@@ -213,10 +214,10 @@
       out.writeInt(CURRENT_PROTOCOL_VERSION);
       out.writeInt(what);
       out.writeInt(countFields());
-      Enumeration e = fieldNames();
-      while(e.hasMoreElements())
+      Iterator e = fieldNames();
+      while(e.hasNext())
       {
-         String name = (String) e.nextElement();
+         String name = (String) e.next();
          MessageField field = (MessageField) _fieldTable.get(name);
          out.writeInt(name.length()+1);
          out.writeBytes(name);
@@ -241,10 +242,10 @@
       out.putInt(CURRENT_PROTOCOL_VERSION);
       out.putInt(what);
       out.putInt(countFields());
-      Enumeration e = fieldNames();
-      while(e.hasMoreElements())
+      Iterator e = fieldNames();
+      while(e.hasNext())
       {
-         String name = (String) e.nextElement();
+         String name = (String) e.next();
          MessageField field = (MessageField) _fieldTable.get(name);
          byte[] nameBytes = name.getBytes();
          out.putInt(nameBytes.length+1);
@@ -1229,7 +1230,7 @@
    /** Convenience method:  when it returns, _fieldTable is guaranteed to be 
non-null. */
    private void ensureFieldTableAllocated()
    {
-      if (_fieldTable == null) _fieldTable = new Hashtable();
+      if (_fieldTable == null) _fieldTable = new HashMap();
    }
 
    /** Sets the contents of a field */
@@ -1509,35 +1510,40 @@
             case B_INT16_TYPE:                                         
             {
                short [] array = (short[]) _payload;
-               for (int i=0; i<_numItems; i++) out.putShort(array[i]);
+               out.asShortBuffer().put(array, 0, _numItems);
+               out.position(out.position()+array.length*2);
             }
             break;
 
             case B_FLOAT_TYPE: 
             { 
                float [] array = (float[]) _payload;
-               for (int i=0; i<_numItems; i++) out.putFloat(array[i]);
+               out.asFloatBuffer().put(array, 0, _numItems);
+               out.position(out.position()+array.length*4);
             }
             break;
 
             case B_INT32_TYPE:
             { 
                int [] array = (int[]) _payload;
-               for (int i=0; i<_numItems; i++) out.putInt(array[i]);
+               out.asIntBuffer().put(array, 0, _numItems);
+               out.position(out.position()+array.length*4);
             }
             break;
 
             case B_INT64_TYPE: 
             { 
                long [] array = (long[]) _payload;
-               for (int i=0; i<_numItems; i++) out.putLong(array[i]);
+               out.asLongBuffer().put(array, 0, _numItems);
+               out.position(out.position()+array.length*8);
             }
             break;
 
             case B_DOUBLE_TYPE: 
             { 
                double [] array = (double[]) _payload;
-               for (int i=0; i<_numItems; i++) out.putDouble(array[i]);
+               out.asDoubleBuffer().put(array, 0, _numItems);
+               out.position(out.position()+array.length*8);
             }
             break;
 
@@ -1629,7 +1635,8 @@
              case B_INT16_TYPE:                                         
              { 
                 short [] array = new short[_numItems];
-                for (int i=0; i<_numItems; i++) array[i] = in.getShort();
+                in.asShortBuffer().get(array);
+                in.position(in.position()+array.length*2);
                 _payload = array;
              }
              break;
@@ -1637,7 +1644,8 @@
              case B_FLOAT_TYPE: 
              { 
                 float [] array = new float[_numItems];
-                for (int i=0; i<_numItems; i++) array[i] = in.getFloat();
+                in.asFloatBuffer().get(array);
+                in.position(in.position()+array.length*4);
                 _payload = array;
              }
              break;
@@ -1645,7 +1653,8 @@
              case B_INT32_TYPE:
              { 
                 int [] array = new int[_numItems];
-                for (int i=0; i<_numItems; i++) array[i] = in.getInt();
+                in.asIntBuffer().get(array);
+                in.position(in.position()+array.length*4);
                 _payload = array;
              }
              break;
@@ -1653,7 +1662,8 @@
              case B_INT64_TYPE: 
              { 
                 long [] array = new long[_numItems];
-                for (int i=0; i<_numItems; i++) array[i] = in.getLong();
+                in.asLongBuffer().get(array);
+                in.position(in.position()+array.length*8);
                 _payload = array;
              }
              break;
@@ -1661,7 +1671,8 @@
              case B_DOUBLE_TYPE: 
              {
                 double [] array = new double[_numItems];
-                for (int i=0; i<_numItems; i++) array[i] = in.getDouble();
+                in.asDoubleBuffer().get(array);
+                in.position(in.position()+array.length*8);
                 _payload = array;
              }
              break;
@@ -1702,8 +1713,6 @@
                    numBytes -= (subMessageSize + 4);  // 4 for the size int
                 }
                 _numItems = temp.size();
-//                Message array[] = new Message[_numItems];
-//              for (int j=0; j<_numItems; j++) array[j] = (Message) 
temp.get(j);
                 Message[] array = (Message[]) temp.toArray(new 
Message[_numItems]);
                 _payload = array;
              }
@@ -1837,18 +1846,18 @@
 
             case B_MESSAGE_TYPE:
             {
-               Vector temp = new Vector();
+               List temp = new ArrayList();
                while(numBytes > 0)
                {
                   Message subMessage = new Message();
                   int subMessageSize = in.readInt(); 
                   subMessage.unflatten(in, subMessageSize);
-                  temp.addElement(subMessage);
+                  temp.add(subMessage);
                   numBytes -= (subMessageSize + 4);  // 4 for the size int
                }
                _numItems = temp.size();
                Message array[] = new Message[_numItems];
-               for (int j=0; j<_numItems; j++) array[j] = (Message) 
temp.elementAt(j);
+               for (int j=0; j<_numItems; j++) array[j] = (Message) 
temp.get(j);
                _payload = array;
             }
             break;
@@ -1891,95 +1900,97 @@
       /** Prints some debug info about our state to (out) */
       public String toString()
       {
-         String ret = "  Type='"+whatString(_type)+"', " + _numItems + " 
items: ";
+         StringBuffer ret = new StringBuffer("  Type='");
+         ret.append(whatString(_type)).append("', 
").append(_numItems).append(" items: ");
          int pitems = (_numItems < 10) ? _numItems : 10;
          switch(_type)
          {
             case B_BOOL_TYPE:  
             {
                boolean [] array = (boolean[]) _payload;
-               for (int i=0; i<pitems; i++) ret += ((array[i]) ? "true " : 
"false ");
+               for (int i=0; i<pitems; i++) ret.append((array[i]) ? "true " : 
"false ");
             }
             break;
 
             case B_INT8_TYPE:                       
             {
                byte [] array = (byte[]) _payload;
-               for (int i=0; i<pitems; i++) ret += (array[i] + " ");
+               for (int i=0; i<pitems; i++) ret.append(array[i]).append(' ');
             }
             break;
 
             case B_INT16_TYPE:                                         
             { 
                short [] array = (short[]) _payload;
-               for (int i=0; i<pitems; i++) ret += (array[i] + " ");
+               for (int i=0; i<pitems; i++) ret.append(array[i]).append(' ');
             }
             break;
 
             case B_FLOAT_TYPE: 
             { 
                float [] array = (float[]) _payload;
-               for (int i=0; i<pitems; i++) ret += (array[i] + " ");
+               for (int i=0; i<pitems; i++) ret.append(array[i]).append(' ');
             }
             break;
 
             case B_INT32_TYPE:
             { 
                int [] array = (int[]) _payload;
-               for (int i=0; i<pitems; i++) ret += (array[i] + " ");
+               for (int i=0; i<pitems; i++) ret.append(array[i]).append(' ');
             }
             break;
 
             case B_INT64_TYPE: 
             { 
                long [] array = (long[]) _payload;
-               for (int i=0; i<pitems; i++) ret += (array[i] + " ");
+               for (int i=0; i<pitems; i++) ret.append(array[i]).append(' ');
             }
             break;
 
             case B_DOUBLE_TYPE: 
             {
                double [] array = (double[]) _payload;
-               for (int i=0; i<pitems; i++) ret += (array[i] + " ");
+               for (int i=0; i<pitems; i++) ret.append(array[i]).append(' ');
             }
             break;
 
             case B_POINT_TYPE:  
             { 
                Point [] array = (Point[]) _payload;
-               for (int i=0; i<pitems; i++) ret += array[i];
+               for (int i=0; i<pitems; i++) ret.append(array[i]);
             }
             break;
 
             case B_RECT_TYPE:                                          
             {
                Rect [] array = (Rect[]) _payload;
-               for (int i=0; i<pitems; i++) ret += array[i];
+               for (int i=0; i<pitems; i++) ret.append(array[i]);
             }
             break;
 
             case B_MESSAGE_TYPE:
             {
                Message [] array = (Message[]) _payload;
-               for (int i=0; i<pitems; i++) ret += 
("["+whatString(array[i].what)+", "+array[i].countFields()+" fields] ");
+               for (int i=0; i<pitems; i++) 
+                       
ret.append('[').append(whatString(array[i].what)).append(", 
").append(array[i].countFields()).append(" fields] ");
             }
             break;
 
             case B_STRING_TYPE:
             {
                String [] array = (String[]) _payload;
-               for (int i=0; i<pitems; i++) ret += ("[" + array[i] + "] ");
+               for (int i=0; i<pitems; i++) 
ret.append('[').append(array[i]).append("] ");
             }
             break;
 
             default:
             {
                byte [][] array = (byte[][]) _payload;
-               for (int i=0; i<pitems; i++) ret += ("["+array[i].length+" 
bytes] ");
+               for (int i=0; i<pitems; i++) 
ret.append('[').append(array[i].length).append(" bytes] ");
             }
             break;
          }
-         return ret;
+         return ret.toString();
       }
 
       /** Makes an independent clone of this field object (a bit expensive) */
@@ -2153,7 +2164,7 @@
    private LEDataInputStream _lepais = null;
    private LEDataOutputStream _lepaos = null;   
 
-   private Hashtable _fieldTable = null;    // our name -> MessageField table
-   private static Hashtable _empty; // = new Hashtable(0);  // had to change 
this to be done on-demand in the ctor, as IE was throwing fits :^(
+   private Map _fieldTable = null;    // our name -> MessageField table
+   private static Map _empty; // = new Hashtable(0);  // had to change this to 
be done on-demand in the ctor, as IE was throwing fits :^(
 }
 
diff -Nur /tmp/muscle/java/com/lcs/muscle/queue/Queue.java 
com/lcs/muscle/queue/Queue.java
--- /tmp/muscle/java/com/lcs/muscle/queue/Queue.java    2006-01-31 
03:47:36.000000000 +0200
+++ com/lcs/muscle/queue/Queue.java     2006-12-28 18:27:15.000000000 +0200
@@ -160,7 +160,12 @@
    }
 
    /** Removes all elements from the queue. */
-   public void removeAllElements() {while(_elementCount > 0) 
removeLastElement();}
+   public void removeAllElements() {
+          _queue = null;  // demand-allocated object array
+          _elementCount = 0;  // number of valid elements in the array
+          _headIndex = -1;   // index of the first filled slot, or -1 
+          _tailIndex = -1; 
+   }
 
    /** Returns the number of elements in the queue.  (This number does not 
include pre-allocated space) */
    public int size() {return _elementCount;}
diff -Nur /tmp/muscle/java/com/lcs/muscle/test/TestClient.java 
com/lcs/muscle/test/TestClient.java
--- /tmp/muscle/java/com/lcs/muscle/test/TestClient.java        2006-12-28 
19:12:03.000000000 +0200
+++ com/lcs/muscle/test/TestClient.java 2006-12-28 19:46:12.000000000 +0200
@@ -48,6 +48,7 @@
             try {
                String command = st.nextToken();
                Message msg = new Message();
+               msg.what = PR_COMMAND_PING;
                if (command.equalsIgnoreCase("q")) break;
                else if (command.equalsIgnoreCase("t"))
                {
diff -Nur /tmp/muscle/java/com/lcs/muscle/thread/ThreadPool.java 
com/lcs/muscle/thread/ThreadPool.java
--- /tmp/muscle/java/com/lcs/muscle/thread/ThreadPool.java      2005-08-19 
03:17:03.000000000 +0300
+++ com/lcs/muscle/thread/ThreadPool.java       2006-12-28 18:21:06.000000000 
+0200
@@ -34,7 +34,7 @@
       if ((_idleThreadCount <= 0)&&(_threadCount < _highMark))
       {
          _threadCount++;              // note that the new thread exists
-         Thread t = new Thread(this);
+         Thread t = new Thread(_threadGroup, this, "MUSCLE worker 
thread-"+_threadCount);
          t.setDaemon(true);
          t.start();  // and off he goes
       }
@@ -105,7 +105,8 @@
    }
 
    private static ThreadPool _defaultThreadPool = new ThreadPool();  // 
singleton
-
+   
+   private ThreadGroup _threadGroup = new ThreadGroup("Muscle Threads");
    private Queue _tasks = new Queue();  // Runnables that need to be run
    private int _idleThreadCount = 0;    // how many threads are idle
    private int _threadCount = 0;        // how many threads are in the pool

Other related posts: