PageRenderTime 36ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/java/com/fasterxml/uuid/impl/TimeBasedGenerator.java

http://github.com/cowtowncoder/java-uuid-generator
Java | 112 lines | 41 code | 14 blank | 57 comment | 2 complexity | 4c5356e2ece49082a2d5f9f4273ff514 MD5 | raw file
Possible License(s): Apache-2.0
  1. package com.fasterxml.uuid.impl;
  2. import java.util.UUID;
  3. import com.fasterxml.uuid.*;
  4. /**
  5. * Implementation of UUID generator that uses time/location based generation
  6. * method (variant 1).
  7. *<p>
  8. * As all JUG provided implementations, this generator is fully thread-safe.
  9. * Additionally it can also be made externally synchronized with other
  10. * instances (even ones running on other JVMs); to do this,
  11. * use {@link com.fasterxml.uuid.ext.FileBasedTimestampSynchronizer}
  12. * (or equivalent).
  13. *
  14. * @since 3.0
  15. */
  16. public class TimeBasedGenerator extends NoArgGenerator
  17. {
  18. /*
  19. /**********************************************************************
  20. /* Configuration
  21. /**********************************************************************
  22. */
  23. protected final EthernetAddress _ethernetAddress;
  24. /**
  25. * Object used for synchronizing access to timestamps, to guarantee
  26. * that timestamps produced by this generator are unique and monotonically increasings.
  27. * Some implementations offer even stronger guarantees, for example that
  28. * same guarantee holds between instances running on different JVMs (or
  29. * with native code).
  30. */
  31. protected final UUIDTimer _timer;
  32. /**
  33. * Base values for the second long (last 8 bytes) of UUID to construct
  34. */
  35. protected final long _uuidL2;
  36. /*
  37. /**********************************************************************
  38. /* Construction
  39. /**********************************************************************
  40. */
  41. /**
  42. * @param ethAddr Hardware address (802.1) to use for generating
  43. * spatially unique part of UUID. If system has more than one NIC,
  44. */
  45. public TimeBasedGenerator(EthernetAddress ethAddr, UUIDTimer timer)
  46. {
  47. byte[] uuidBytes = new byte[16];
  48. if (ethAddr == null) {
  49. ethAddr = EthernetAddress.constructMulticastAddress();
  50. }
  51. // initialize baseline with MAC address info
  52. _ethernetAddress = ethAddr;
  53. _ethernetAddress.toByteArray(uuidBytes, 10);
  54. // and add clock sequence
  55. int clockSeq = timer.getClockSequence();
  56. uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE] = (byte) (clockSeq >> 8);
  57. uuidBytes[UUIDUtil.BYTE_OFFSET_CLOCK_SEQUENCE+1] = (byte) clockSeq;
  58. long l2 = UUIDUtil.gatherLong(uuidBytes, 8);
  59. _uuidL2 = UUIDUtil.initUUIDSecondLong(l2);
  60. _timer = timer;
  61. }
  62. /*
  63. /**********************************************************************
  64. /* Access to config
  65. /**********************************************************************
  66. */
  67. @Override
  68. public UUIDType getType() { return UUIDType.TIME_BASED; }
  69. public EthernetAddress getEthernetAddress() { return _ethernetAddress; }
  70. /*
  71. /**********************************************************************
  72. /* UUID generation
  73. /**********************************************************************
  74. */
  75. /* As timer is not synchronized (nor _uuidBytes), need to sync; but most
  76. * importantly, synchronize on timer which may also be shared between
  77. * multiple instances
  78. */
  79. @Override
  80. public UUID generate()
  81. {
  82. final long rawTimestamp = _timer.getTimestamp();
  83. // Time field components are kind of shuffled, need to slice:
  84. int clockHi = (int) (rawTimestamp >>> 32);
  85. int clockLo = (int) rawTimestamp;
  86. // and dice
  87. int midhi = (clockHi << 16) | (clockHi >>> 16);
  88. // need to squeeze in type (4 MSBs in byte 6, clock hi)
  89. midhi &= ~0xF000; // remove high nibble of 6th byte
  90. midhi |= 0x1000; // type 1
  91. long midhiL = (long) midhi;
  92. midhiL = ((midhiL << 32) >>> 32); // to get rid of sign extension
  93. // and reconstruct
  94. long l1 = (((long) clockLo) << 32) | midhiL;
  95. // last detail: must force 2 MSB to be '10'
  96. return new UUID(l1, _uuidL2);
  97. }
  98. }