You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by kw...@apache.org on 2017/06/21 08:22:01 UTC

qpid-broker-j git commit: QPID-7827: Delegate the creation of UUIDs to factory to avoid proliferation of UUID instances representing the same underlying UUID.

Repository: qpid-broker-j
Updated Branches:
  refs/heads/6.1.x 5293cc0eb -> bc58bc309


QPID-7827: Delegate the creation of UUIDs to factory to avoid proliferation of UUID instances representing the same underlying UUID.

Cherry picked from 2ddbca0b16e47b18f24beaa1f4fa88d594a25618.  Manually resolved conflicts and backported CachingUUIDFactory to JDK 1.7 (#putIfAbsent).


Project: http://git-wip-us.apache.org/repos/asf/qpid-broker-j/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-broker-j/commit/bc58bc30
Tree: http://git-wip-us.apache.org/repos/asf/qpid-broker-j/tree/bc58bc30
Diff: http://git-wip-us.apache.org/repos/asf/qpid-broker-j/diff/bc58bc30

Branch: refs/heads/6.1.x
Commit: bc58bc3093eba424f8bcd125399db0e9bc1e7fd6
Parents: 5293cc0
Author: Keith Wall <kw...@apache.org>
Authored: Mon Jun 19 14:30:22 2017 +0100
Committer: Keith Wall <kw...@apache.org>
Committed: Wed Jun 21 09:16:29 2017 +0100

----------------------------------------------------------------------
 .../berkeleydb/AbstractBDBMessageStore.java     | 28 +++++-----
 .../tuple/PreparedTransactionBinding.java       | 46 +++++++++-------
 .../berkeleydb/tuple/QueueEntryBinding.java     | 47 +++++++---------
 .../server/store/AbstractJDBCMessageStore.java  | 12 +++--
 .../qpid/server/util/CachingUUIDFactory.java    | 56 ++++++++++++++++++++
 .../server/util/CachingUUIDFactoryTest.java     | 47 ++++++++++++++++
 6 files changed, 169 insertions(+), 67 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/bc58bc30/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/AbstractBDBMessageStore.java
----------------------------------------------------------------------
diff --git a/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/AbstractBDBMessageStore.java b/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/AbstractBDBMessageStore.java
index 4313dcd..9fe8b55 100644
--- a/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/AbstractBDBMessageStore.java
+++ b/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/AbstractBDBMessageStore.java
@@ -71,6 +71,7 @@ import org.apache.qpid.server.store.berkeleydb.tuple.XidBinding;
 import org.apache.qpid.server.store.handler.DistributedTransactionHandler;
 import org.apache.qpid.server.store.handler.MessageHandler;
 import org.apache.qpid.server.store.handler.MessageInstanceHandler;
+import org.apache.qpid.server.util.CachingUUIDFactory;
 
 
 public abstract class AbstractBDBMessageStore implements MessageStore
@@ -616,9 +617,8 @@ public abstract class AbstractBDBMessageStore implements MessageStore
     {
 
         DatabaseEntry key = new DatabaseEntry();
-        QueueEntryBinding keyBinding = QueueEntryBinding.getInstance();
-        QueueEntryKey dd = new QueueEntryKey(queue.getId(), messageId);
-        keyBinding.objectToEntry(dd, key);
+        QueueEntryKey queueEntryKey = new QueueEntryKey(queue.getId(), messageId);
+        QueueEntryBinding.objectToEntry(queueEntryKey, key);
         DatabaseEntry value = new DatabaseEntry();
         value.setData(ENQUEUE_RECORD_VALUE, 0, ENQUEUE_RECORD_VALUE.length);
 
@@ -658,10 +658,9 @@ public abstract class AbstractBDBMessageStore implements MessageStore
     {
 
         DatabaseEntry key = new DatabaseEntry();
-        QueueEntryBinding keyBinding = QueueEntryBinding.getInstance();
         QueueEntryKey queueEntryKey = new QueueEntryKey(queueId, messageId);
         UUID id = queueId;
-        keyBinding.objectToEntry(queueEntryKey, key);
+        QueueEntryBinding.objectToEntry(queueEntryKey, key);
 
         getLogger().debug("Dequeue message id {} from queue with id {}", messageId, id);
 
@@ -705,8 +704,7 @@ public abstract class AbstractBDBMessageStore implements MessageStore
 
         DatabaseEntry value = new DatabaseEntry();
         PreparedTransaction preparedTransaction = new PreparedTransaction(enqueues, dequeues);
-        PreparedTransactionBinding valueBinding = new PreparedTransactionBinding();
-        valueBinding.objectToEntry(preparedTransaction, value);
+        PreparedTransactionBinding.objectToEntry(preparedTransaction, value);
         for(org.apache.qpid.server.store.Transaction.EnqueueRecord enqueue : enqueues)
         {
             StoredMessage storedMessage = enqueue.getMessage().getStoredMessage();
@@ -1556,13 +1554,13 @@ public abstract class AbstractBDBMessageStore implements MessageStore
                 DatabaseEntry value = new DatabaseEntry();
                 value.setPartial(0, 0, true);
 
-                QueueEntryBinding keyBinding = QueueEntryBinding.getInstance();
-                keyBinding.objectToEntry(new QueueEntryKey(queue.getId(), 0l), key);
+                CachingUUIDFactory uuidFactory = new CachingUUIDFactory();
+                QueueEntryBinding.objectToEntry(new QueueEntryKey(queue.getId(), 0L), key);
 
                 if (!searchCompletedSuccessfully && (searchCompletedSuccessfully =
                         cursor.getSearchKeyRange(key, value, LockMode.READ_UNCOMMITTED) == OperationStatus.SUCCESS))
                 {
-                    QueueEntryKey entry = keyBinding.entryToObject(key);
+                    QueueEntryKey entry = QueueEntryBinding.entryToObject(uuidFactory, key);
                     if (entry.getQueueId().equals(queue.getId()))
                     {
                         entries.add(entry);
@@ -1573,7 +1571,7 @@ public abstract class AbstractBDBMessageStore implements MessageStore
                 {
                     while (cursor.getNext(key, value, LockMode.READ_UNCOMMITTED) == OperationStatus.SUCCESS)
                     {
-                        QueueEntryKey entry = keyBinding.entryToObject(key);
+                        QueueEntryKey entry = QueueEntryBinding.entryToObject(uuidFactory, key);
                         if (entry.getQueueId().equals(queue.getId()))
                         {
                             entries.add(entry);
@@ -1613,13 +1611,13 @@ public abstract class AbstractBDBMessageStore implements MessageStore
             try(Cursor cursor = getDeliveryDb().openCursor(null, null))
             {
                 DatabaseEntry key = new DatabaseEntry();
-                QueueEntryBinding keyBinding = QueueEntryBinding.getInstance();
+                CachingUUIDFactory uuidFactory = new CachingUUIDFactory();
 
                 DatabaseEntry value = new DatabaseEntry();
                 value.setPartial(0, 0, true);
                 while (cursor.getNext(key, value, LockMode.READ_UNCOMMITTED) == OperationStatus.SUCCESS)
                 {
-                    QueueEntryKey entry = keyBinding.entryToObject(key);
+                    QueueEntryKey entry = QueueEntryBinding.entryToObject(uuidFactory, key);
                     entries.add(entry);
                 }
             }
@@ -1647,15 +1645,15 @@ public abstract class AbstractBDBMessageStore implements MessageStore
 
             try(Cursor cursor = getXidDb().openCursor(null, null))
             {
+                CachingUUIDFactory uuidFactory = new CachingUUIDFactory();
                 DatabaseEntry key = new DatabaseEntry();
                 XidBinding keyBinding = XidBinding.getInstance();
-                PreparedTransactionBinding valueBinding = new PreparedTransactionBinding();
                 DatabaseEntry value = new DatabaseEntry();
 
                 while (cursor.getNext(key, value, LockMode.READ_UNCOMMITTED) == OperationStatus.SUCCESS)
                 {
                     Xid xid = keyBinding.entryToObject(key);
-                    PreparedTransaction preparedTransaction = valueBinding.entryToObject(value);
+                    PreparedTransaction preparedTransaction = PreparedTransactionBinding.entryToObject(uuidFactory, value);
                     if (!handler.handle(new BDBStoredXidRecord(xid.getFormat(), xid.getGlobalId(), xid.getBranchId()),
                                         preparedTransaction.getEnqueues(), preparedTransaction.getDequeues()))
                     {

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/bc58bc30/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuple/PreparedTransactionBinding.java
----------------------------------------------------------------------
diff --git a/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuple/PreparedTransactionBinding.java b/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuple/PreparedTransactionBinding.java
index 4d111e5..23e302a 100644
--- a/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuple/PreparedTransactionBinding.java
+++ b/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuple/PreparedTransactionBinding.java
@@ -26,6 +26,8 @@ import java.util.UUID;
 import com.sleepycat.bind.tuple.TupleBinding;
 import com.sleepycat.bind.tuple.TupleInput;
 import com.sleepycat.bind.tuple.TupleOutput;
+import com.sleepycat.je.DatabaseEntry;
+
 import org.apache.qpid.server.message.EnqueueableMessage;
 import org.apache.qpid.server.store.MessageDurability;
 import org.apache.qpid.server.store.MessageEnqueueRecord;
@@ -34,49 +36,53 @@ import org.apache.qpid.server.store.Transaction;
 import org.apache.qpid.server.store.TransactionLogResource;
 import org.apache.qpid.server.store.berkeleydb.AbstractBDBMessageStore;
 import org.apache.qpid.server.store.berkeleydb.entry.PreparedTransaction;
+import org.apache.qpid.server.util.CachingUUIDFactory;
 
-public class PreparedTransactionBinding extends TupleBinding<PreparedTransaction>
+public class PreparedTransactionBinding
 {
-    @Override
-    public PreparedTransaction entryToObject(TupleInput input)
+    private PreparedTransactionBinding()
     {
-        Transaction.EnqueueRecord[] enqueues = readEnqueueRecords(input);
-
-        Transaction.DequeueRecord[] dequeues = readDequeueRecords(input);
+    }
 
+    public static PreparedTransaction entryToObject(final CachingUUIDFactory uuidFactory, final DatabaseEntry value)
+    {
+        TupleInput input = TupleBinding.entryToInput(value);
+        Transaction.EnqueueRecord[] enqueues = readEnqueueRecords(uuidFactory, input);
+        Transaction.DequeueRecord[] dequeues = readDequeueRecords(uuidFactory, input);
         return new PreparedTransaction(enqueues, dequeues);
     }
 
-    private Transaction.EnqueueRecord[] readEnqueueRecords(TupleInput input)
+    private static Transaction.EnqueueRecord[] readEnqueueRecords(final CachingUUIDFactory uuidFactory, TupleInput input)
     {
         Transaction.EnqueueRecord[] records = new Transaction.EnqueueRecord[input.readInt()];
         for(int i = 0; i < records.length; i++)
         {
-            records[i] = new EnqueueRecordImpl(new UUID(input.readLong(), input.readLong()), input.readLong());
+            UUID queueId = uuidFactory.createUuidFromBits(input.readLong(), input.readLong());
+            records[i] = new EnqueueRecordImpl(queueId, input.readLong());
         }
         return records;
     }
 
-    private Transaction.DequeueRecord[] readDequeueRecords(TupleInput input)
+    private static Transaction.DequeueRecord[] readDequeueRecords(final CachingUUIDFactory uuidFactory, TupleInput input)
     {
         Transaction.DequeueRecord[] records = new Transaction.DequeueRecord[input.readInt()];
         for(int i = 0; i < records.length; i++)
         {
-            records[i] = new DequeueRecordImpl(new UUID(input.readLong(), input.readLong()), input.readLong());
+            UUID queueId = uuidFactory.createUuidFromBits(input.readLong(), input.readLong());
+            records[i] = new DequeueRecordImpl(queueId, input.readLong());
         }
         return records;
     }
 
-
-    @Override
-    public void objectToEntry(PreparedTransaction preparedTransaction, TupleOutput output)
+    public static void objectToEntry(final PreparedTransaction preparedTransaction, final DatabaseEntry value)
     {
-        writeRecords(preparedTransaction.getEnqueues(), output);
-        writeRecords(preparedTransaction.getDequeues(), output);
-
+        TupleOutput tupleOutput = new TupleOutput();
+        writeRecords(preparedTransaction.getEnqueues(), tupleOutput);
+        writeRecords(preparedTransaction.getDequeues(), tupleOutput);
+        TupleBinding.outputToEntry(tupleOutput, value);
     }
 
-    private void writeRecords(Transaction.EnqueueRecord[] records, TupleOutput output)
+    private static void writeRecords(Transaction.EnqueueRecord[] records, TupleOutput output)
     {
         if(records == null)
         {
@@ -95,7 +101,7 @@ public class PreparedTransactionBinding extends TupleBinding<PreparedTransaction
         }
     }
 
-    private void writeRecords(Transaction.DequeueRecord[] records, TupleOutput output)
+    private static void writeRecords(Transaction.DequeueRecord[] records, TupleOutput output)
     {
         if(records == null)
         {
@@ -120,7 +126,7 @@ public class PreparedTransactionBinding extends TupleBinding<PreparedTransaction
         private long _messageNumber;
         private UUID _queueId;
 
-        public EnqueueRecordImpl(UUID queueId, long messageNumber)
+        EnqueueRecordImpl(UUID queueId, long messageNumber)
         {
             _messageNumber = messageNumber;
             _queueId = queueId;
@@ -175,7 +181,7 @@ public class PreparedTransactionBinding extends TupleBinding<PreparedTransaction
 
         private final AbstractBDBMessageStore.BDBEnqueueRecord _record;
 
-        public DequeueRecordImpl(final UUID queueId, final long messageNumber)
+        DequeueRecordImpl(final UUID queueId, final long messageNumber)
         {
             _record = new AbstractBDBMessageStore.BDBEnqueueRecord(queueId, messageNumber);
         }

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/bc58bc30/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuple/QueueEntryBinding.java
----------------------------------------------------------------------
diff --git a/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuple/QueueEntryBinding.java b/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuple/QueueEntryBinding.java
index ee00e5d..32f1bb9 100644
--- a/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuple/QueueEntryBinding.java
+++ b/bdbstore/src/main/java/org/apache/qpid/server/store/berkeleydb/tuple/QueueEntryBinding.java
@@ -22,46 +22,39 @@ package org.apache.qpid.server.store.berkeleydb.tuple;
 
 import java.util.UUID;
 
-import com.sleepycat.bind.EntryBinding;
 import com.sleepycat.je.DatabaseEntry;
 
 import org.apache.qpid.server.store.berkeleydb.entry.QueueEntryKey;
+import org.apache.qpid.server.util.CachingUUIDFactory;
 
-public class QueueEntryBinding implements EntryBinding<QueueEntryKey>
+public class QueueEntryBinding
 {
-
-    private static final QueueEntryBinding INSTANCE = new QueueEntryBinding();
-
-    public static QueueEntryBinding getInstance()
+    private QueueEntryBinding()
     {
-        return INSTANCE;
     }
 
-    /** private constructor forces getInstance instead */
-    private QueueEntryBinding() { }
-
-    public QueueEntryKey entryToObject(DatabaseEntry entry)
+    public static QueueEntryKey entryToObject(final CachingUUIDFactory uuidFactory, DatabaseEntry entry)
     {
         byte[] data = entry.getData();
         int offset = entry.getOffset();
 
-        UUID queueId = new UUID(readUnsignedLong(data,offset)^ 0x8000000000000000L, readUnsignedLong(data,offset+8)^ 0x8000000000000000L);
+        UUID queueId = uuidFactory.createUuidFromBits(readUnsignedLong(data, offset) ^ 0x8000000000000000L, readUnsignedLong(data, offset + 8) ^ 0x8000000000000000L);
         long messageId = readUnsignedLong(data,offset+16)^ 0x8000000000000000L;
 
         return new QueueEntryKey(queueId, messageId);
     }
 
-    public void objectToEntry(QueueEntryKey mk, DatabaseEntry entry)
+    public static void objectToEntry(QueueEntryKey entryKey, DatabaseEntry entry)
     {
         byte[] output = new byte[24];
-        UUID uuid = mk.getQueueId();
+        UUID uuid = entryKey.getQueueId();
         writeUnsignedLong(uuid.getMostSignificantBits() ^ 0x8000000000000000L, output, 0);
         writeUnsignedLong(uuid.getLeastSignificantBits() ^ 0x8000000000000000L, output, 8);
-        writeUnsignedLong(mk.getMessageId() ^ 0x8000000000000000L, output, 16);
+        writeUnsignedLong(entryKey.getMessageId() ^ 0x8000000000000000L, output, 16);
         entry.setData(output);
     }
 
-    private void writeUnsignedLong(long val, byte[] data, int offset)
+    private static void writeUnsignedLong(long val, byte[] data, int offset)
     {
         data[offset++] = (byte) (val >>> 56);
         data[offset++] = (byte) (val >>> 48);
@@ -73,19 +66,15 @@ public class QueueEntryBinding implements EntryBinding<QueueEntryKey>
         data[offset] = (byte) val;
     }
 
-    private long readUnsignedLong(final byte[] data, int offset)
+    private static long readUnsignedLong(final byte[] data, int offset)
     {
-        return (((long)data[offset++] & 0xffl) << 56)
-               | (((long)data[offset++] & 0xffl) << 48)
-               | (((long)data[offset++] & 0xffl) << 40)
-               | (((long)data[offset++] & 0xffl) << 32)
-               | (((long)data[offset++] & 0xffl) << 24)
-               | (((long)data[offset++] & 0xffl) << 16)
-               | (((long)data[offset++] & 0xffl) << 8)
-               | ((long)data[offset] & 0xffl) ;
+        return (((long)data[offset++] & 0xffL) << 56)
+               | (((long)data[offset++] & 0xffL) << 48)
+               | (((long)data[offset++] & 0xffL) << 40)
+               | (((long)data[offset++] & 0xffL) << 32)
+               | (((long)data[offset++] & 0xffL) << 24)
+               | (((long)data[offset++] & 0xffL) << 16)
+               | (((long)data[offset++] & 0xffL) << 8)
+               | ((long)data[offset] & 0xffL) ;
     }
-
-
-
-
 }

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/bc58bc30/broker-core/src/main/java/org/apache/qpid/server/store/AbstractJDBCMessageStore.java
----------------------------------------------------------------------
diff --git a/broker-core/src/main/java/org/apache/qpid/server/store/AbstractJDBCMessageStore.java b/broker-core/src/main/java/org/apache/qpid/server/store/AbstractJDBCMessageStore.java
index 6b95012..d74d44d 100644
--- a/broker-core/src/main/java/org/apache/qpid/server/store/AbstractJDBCMessageStore.java
+++ b/broker-core/src/main/java/org/apache/qpid/server/store/AbstractJDBCMessageStore.java
@@ -54,6 +54,7 @@ import org.apache.qpid.server.plugin.MessageMetaDataType;
 import org.apache.qpid.server.store.handler.DistributedTransactionHandler;
 import org.apache.qpid.server.store.handler.MessageHandler;
 import org.apache.qpid.server.store.handler.MessageInstanceHandler;
+import org.apache.qpid.server.util.CachingUUIDFactory;
 
 public abstract class AbstractJDBCMessageStore implements MessageStore
 {
@@ -1843,6 +1844,7 @@ public abstract class AbstractJDBCMessageStore implements MessageStore
             Connection conn = null;
             try
             {
+                CachingUUIDFactory uuidFactory = new CachingUUIDFactory();
                 conn = newAutoCommitConnection();
                 PreparedStatement stmt = conn.prepareStatement("SELECT queue_id, message_id FROM " + getQueueEntryTableName()
                                                                + " WHERE queue_id = ? ORDER BY queue_id, message_id");
@@ -1856,7 +1858,8 @@ public abstract class AbstractJDBCMessageStore implements MessageStore
                         {
                             String id = rs.getString(1);
                             long messageId = rs.getLong(2);
-                            if (!handler.handle(new JDBCEnqueueRecord(UUID.fromString(id), messageId)))
+                            UUID uuid = uuidFactory.createUuidFromString(id);
+                            if (!handler.handle(new JDBCEnqueueRecord(uuid, messageId)))
                             {
                                 break;
                             }
@@ -1891,6 +1894,7 @@ public abstract class AbstractJDBCMessageStore implements MessageStore
             Connection conn = null;
             try
             {
+                CachingUUIDFactory uuidFactory = new CachingUUIDFactory();
                 conn = newAutoCommitConnection();
                 Statement stmt = conn.createStatement();
                 try
@@ -1903,7 +1907,8 @@ public abstract class AbstractJDBCMessageStore implements MessageStore
                         {
                             String id = rs.getString(1);
                             long messageId = rs.getLong(2);
-                            if (!handler.handle(new JDBCEnqueueRecord(UUID.fromString(id), messageId)))
+                            UUID queueId = uuidFactory.createUuidFromString(id);
+                            if (!handler.handle(new JDBCEnqueueRecord(queueId, messageId)))
                             {
                                 break;
                             }
@@ -1968,6 +1973,7 @@ public abstract class AbstractJDBCMessageStore implements MessageStore
 
                 for (Xid xid : xids)
                 {
+                    CachingUUIDFactory uuidFactory = new CachingUUIDFactory();
                     List<RecordImpl> enqueues = new ArrayList<>();
                     List<RecordImpl> dequeues = new ArrayList<>();
 
@@ -1988,7 +1994,7 @@ public abstract class AbstractJDBCMessageStore implements MessageStore
                             {
 
                                 String actionType = rs.getString(1);
-                                UUID queueId = UUID.fromString(rs.getString(2));
+                                UUID queueId = uuidFactory.createUuidFromString(rs.getString(2));
                                 long messageId = rs.getLong(3);
 
                                 RecordImpl record = new RecordImpl(queueId, messageId);

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/bc58bc30/broker-core/src/main/java/org/apache/qpid/server/util/CachingUUIDFactory.java
----------------------------------------------------------------------
diff --git a/broker-core/src/main/java/org/apache/qpid/server/util/CachingUUIDFactory.java b/broker-core/src/main/java/org/apache/qpid/server/util/CachingUUIDFactory.java
new file mode 100644
index 0000000..c854ae9
--- /dev/null
+++ b/broker-core/src/main/java/org/apache/qpid/server/util/CachingUUIDFactory.java
@@ -0,0 +1,56 @@
+/*
+ * 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.qpid.server.util;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+public class CachingUUIDFactory
+{
+    private final Map<UUID, UUID> _uuids = new HashMap<>();
+
+    public UUID createUuidFromString(final String name)
+    {
+        UUID candidate = UUID.fromString(name);
+        return cacheIfNecessary(candidate);
+    }
+
+    public UUID createUuidFromBits(final long mostSigBits, final long leastSigBits)
+    {
+        UUID candidate = new UUID(mostSigBits, leastSigBits);
+        return cacheIfNecessary(candidate);
+    }
+
+    private UUID cacheIfNecessary(final UUID candidate)
+    {
+        UUID existing = _uuids.get(candidate);
+        if (existing != null)
+        {
+            return existing;
+        }
+        else
+        {
+            _uuids.put(candidate, candidate);
+            return candidate;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/qpid-broker-j/blob/bc58bc30/broker-core/src/test/java/org/apache/qpid/server/util/CachingUUIDFactoryTest.java
----------------------------------------------------------------------
diff --git a/broker-core/src/test/java/org/apache/qpid/server/util/CachingUUIDFactoryTest.java b/broker-core/src/test/java/org/apache/qpid/server/util/CachingUUIDFactoryTest.java
new file mode 100644
index 0000000..f27df9a
--- /dev/null
+++ b/broker-core/src/test/java/org/apache/qpid/server/util/CachingUUIDFactoryTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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.qpid.server.util;
+
+import java.util.UUID;
+
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class CachingUUIDFactoryTest extends QpidTestCase
+{
+    private final CachingUUIDFactory _factory = new CachingUUIDFactory();
+
+    public void testUuidFromBits()
+    {
+        UUID first = _factory.createUuidFromBits(0L,0L);
+        UUID second = _factory.createUuidFromBits(0L,0L);
+        assertSame("UUIDFactory should return the same object", first, second);
+    }
+
+    public void testUuidFromString()
+    {
+        String uuidStr = UUID.randomUUID().toString();
+        UUID first = _factory.createUuidFromString(new String(uuidStr));
+        UUID second = _factory.createUuidFromString(new String(uuidStr));
+        UUID third = _factory.createUuidFromBits(second.getMostSignificantBits(), second.getLeastSignificantBits());
+        assertSame("UUIDFactory should return the same object", first, second);
+        assertSame("UUIDFactory should return the same object", first, third);
+    }
+}
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org