You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

81 lines
1.9 KiB

  1. package uuid
  2. /****************
  3. * Date: 14/02/14
  4. * Time: 7:46 PM
  5. ***************/
  6. import (
  7. "time"
  8. )
  9. const (
  10. // A tick is 100 ns
  11. ticksPerSecond = 10000000
  12. // Difference between
  13. gregorianToUNIXOffset uint64 = 0x01B21DD213814000
  14. // set the following to the number of 100ns ticks of the actual
  15. // resolution of your system's clock
  16. idsPerTimestamp = 1024
  17. )
  18. var (
  19. lastTimestamp Timestamp
  20. idsThisTimestamp = idsPerTimestamp
  21. )
  22. // ********************************************** Timestamp
  23. type Timestamp uint64
  24. // TODO Create c version same as package runtime and time
  25. func Now() (sec int64, nsec int32) {
  26. t := time.Now()
  27. sec = t.Unix()
  28. nsec = int32(t.Nanosecond())
  29. return
  30. }
  31. // Converts Unix formatted time to RFC4122 UUID formatted times
  32. // UUID UTC base time is October 15, 1582.
  33. // Unix base time is January 1, 1970.
  34. // Converts time to 100 nanosecond ticks since epoch
  35. // There are 1000000000 nanoseconds in a second,
  36. // 1000000000 / 100 = 10000000 tiks per second
  37. func timestamp() Timestamp {
  38. sec, nsec := Now()
  39. return Timestamp(uint64(sec)*ticksPerSecond +
  40. uint64(nsec)/100 + gregorianToUNIXOffset)
  41. }
  42. func (o Timestamp) Unix() time.Time {
  43. t := uint64(o) - gregorianToUNIXOffset
  44. return time.Unix(0, int64(t*100))
  45. }
  46. // Get time as 60-bit 100ns ticks since UUID epoch.
  47. // Compensate for the fact that real clock resolution is
  48. // less than 100ns.
  49. func currentUUIDTimestamp() Timestamp {
  50. var timeNow Timestamp
  51. for {
  52. timeNow = timestamp()
  53. // if clock reading changed since last UUID generated
  54. if lastTimestamp != timeNow {
  55. // reset count of UUIDs with this timestamp
  56. idsThisTimestamp = 0
  57. lastTimestamp = timeNow
  58. break
  59. }
  60. if idsThisTimestamp < idsPerTimestamp {
  61. idsThisTimestamp++
  62. break
  63. }
  64. // going too fast for the clock; spin
  65. }
  66. // add the count of UUIDs to low order bits of the clock reading
  67. return timeNow + Timestamp(idsThisTimestamp)
  68. }