You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by ee...@apache.org on 2011/02/03 04:54:03 UTC

svn commit: r1066730 - /cassandra/trunk/src/java/org/apache/cassandra/utils/UUIDGen.java

Author: eevans
Date: Thu Feb  3 03:54:02 2011
New Revision: 1066730

URL: http://svn.apache.org/viewvc?rev=1066730&view=rev
Log:
fix UUIDv1 generation for non-default date-times

Patch by eevans; reviewed by gdusbabek for CASSANDRA-2099

Modified:
    cassandra/trunk/src/java/org/apache/cassandra/utils/UUIDGen.java

Modified: cassandra/trunk/src/java/org/apache/cassandra/utils/UUIDGen.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/utils/UUIDGen.java?rev=1066730&r1=1066729&r2=1066730&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/utils/UUIDGen.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/utils/UUIDGen.java Thu Feb  3 03:54:02 2011
@@ -38,7 +38,7 @@ public class UUIDGen
      */
     public static UUID makeType1UUIDFromHost(InetAddress addr)
     {
-        return new UUID(instance.createTime(System.currentTimeMillis()), instance.getClockSeqAndNode(addr));
+        return new UUID(instance.createTimeSafe(), instance.getClockSeqAndNode(addr));
     }
     
     /** creates a type 1 uuid from raw bytes. */
@@ -69,19 +69,27 @@ public class UUIDGen
      */
     public static byte[] getTimeUUIDBytes()
     {
-        return getTimeUUIDBytes(System.currentTimeMillis());
+        return createTimeUUIDBytes(instance.createTimeSafe());
     }
     
     /**
      * Converts a milliseconds-since-epoch timestamp into the 16 byte representation
      * of a type 1 UUID (a time-based UUID).
      * 
+     * <p><i><b>Warning:</b> This method is not guaranteed to return unique UUIDs; Multiple
+     * invocations using identical timestamps will result in identical UUIDs.</i></p>
+     * 
      * @param timeMillis
      * @return a type 1 UUID represented as a byte[]
      */
     public static byte[] getTimeUUIDBytes(long timeMillis)
     {
-        long msb = instance.createTime(timeMillis), lsb = instance.getClockSeqAndNode();
+        return createTimeUUIDBytes(instance.createTimeUnsafe(timeMillis));
+    }
+    
+    private static byte[] createTimeUUIDBytes(long msb)
+    {
+        long lsb = instance.getClockSeqAndNode();
         byte[] uuidBytes = new byte[16];
         
         for (int i = 0; i < 8; i++)
@@ -93,6 +101,20 @@ public class UUIDGen
         return uuidBytes;
     }
     
+    /**
+     * Returns a milliseconds-since-epoch value for a type-1 UUID.
+     * 
+     * @param uuid a type-1 (time-based) UUID
+     * @return the number of milliseconds since the unix epoch
+     * @throws InvalidArgumentException if the UUID is not version 1
+     */
+    public static long getAdjustedTimestamp(UUID uuid)
+    {
+        if (uuid.version() != 1)
+            throw new IllegalArgumentException("incompatible with uuid version: "+uuid.version());
+        return (uuid.timestamp() / 10000) - START_EPOCH;
+    }
+    
     private long getClockSeqAndNode()
     {
         try
@@ -118,14 +140,25 @@ public class UUIDGen
     
     // needs to return two different values for the same when.
     // we can generate at most 10k UUIDs per ms.
-    private synchronized long createTime(long when)
+    private synchronized long createTimeSafe()
     {
-        long nanosSince = (when - START_EPOCH) * 10000;
+        long nanosSince = (System.currentTimeMillis() - START_EPOCH) * 10000;
         if (nanosSince > lastNanos)
             lastNanos = nanosSince;
         else
             nanosSince = ++lastNanos;
         
+        return createTime(nanosSince);
+    }
+
+    private long createTimeUnsafe(long when)
+    {
+        long nanosSince = (when - START_EPOCH) * 10000;
+        return createTime(nanosSince);
+    }
+    
+    private long createTime(long nanosSince)
+    {   
         long msb = 0L; 
         msb |= (0x00000000ffffffffL & nanosSince) << 32;
         msb |= (0x0000ffff00000000L & nanosSince) >>> 16; 
@@ -133,7 +166,7 @@ public class UUIDGen
         msb |= 0x0000000000001000L; // sets the version to 1.
         return msb;
     }
-    
+
     // Lazily create node hashes, and cache them for later
     private long makeNode(InetAddress addr)
     {