Fix time-based UUID generation

patch by slebresne; reviewed by vijay for CASSANDRA-5001


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/f726cb23
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/f726cb23
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/f726cb23

Branch: refs/heads/cassandra-1.2.0
Commit: f726cb23f501d525d1d98c21c1b27e320139ed3d
Parents: a0db8ff
Author: Sylvain Lebresne <sylv...@datastax.com>
Authored: Thu Nov 29 10:18:14 2012 +0100
Committer: Sylvain Lebresne <sylv...@datastax.com>
Committed: Thu Nov 29 10:18:14 2012 +0100

----------------------------------------------------------------------
 src/java/org/apache/cassandra/utils/UUIDGen.java   |    9 ++++-----
 .../unit/org/apache/cassandra/utils/UUIDTests.java |   12 ++++++++++++
 2 files changed, 16 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/f726cb23/src/java/org/apache/cassandra/utils/UUIDGen.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/UUIDGen.java 
b/src/java/org/apache/cassandra/utils/UUIDGen.java
index 2851965..e207c20 100644
--- a/src/java/org/apache/cassandra/utils/UUIDGen.java
+++ b/src/java/org/apache/cassandra/utils/UUIDGen.java
@@ -174,17 +174,16 @@ public class UUIDGen
     {
         if (uuid.version() != 1)
             throw new IllegalArgumentException("incompatible with uuid 
version: "+uuid.version());
-        return (uuid.timestamp() / 10000) - START_EPOCH;
+        return (uuid.timestamp() / 10000) + START_EPOCH;
     }
 
     // todo: could cache value if we assume node doesn't change.
     private long getClockSeqAndNode(InetAddress addr)
     {
         long lsb = 0;
-        lsb |= (clock & 0x3f00000000000000L) >>> 56; // was 58?
-        lsb |= 0x0000000000000080;
-        lsb |= (clock & 0x00ff000000000000L) >>> 48;
-        lsb |= makeNode(addr);
+        lsb |= 0x8000000000000000L;                 // variant (2 bits)
+        lsb |= (clock & 0x0000000000003FFFL) << 48; // clock sequence (14 bits)
+        lsb |= makeNode(addr);                      // 6 bytes
         return lsb;
     }
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/f726cb23/test/unit/org/apache/cassandra/utils/UUIDTests.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/utils/UUIDTests.java 
b/test/unit/org/apache/cassandra/utils/UUIDTests.java
index bbfe5e1..6cf96d0 100644
--- a/test/unit/org/apache/cassandra/utils/UUIDTests.java
+++ b/test/unit/org/apache/cassandra/utils/UUIDTests.java
@@ -71,6 +71,18 @@ public class UUIDTests
         assert comp.compare(first, sameAsFirst) == 0;
     }
 
+    @Test
+    public void testUUIDTimestamp() throws UnknownHostException
+    {
+        InetAddress addr = InetAddress.getByName("127.0.0.1");
+        long now = System.currentTimeMillis();
+        UUID uuid = UUIDGen.makeType1UUIDFromHost(addr);
+        long tstamp = UUIDGen.getAdjustedTimestamp(uuid);
+
+        // I'll be damn is the uuid timestamp is more than 10ms after now
+        assert now <= tstamp && now >= tstamp - 10 : "now = " + now + ", 
timestamp = " + tstamp;
+    }
+
     private void assertNonZero(BigInteger i)
     {
         assert i.toString(2).indexOf("1") > -1;

Reply via email to