Skip to content

Commit f9ac658

Browse files
committed
address Victor's review
1 parent 571d2fe commit f9ac658

File tree

1 file changed

+25
-18
lines changed

1 file changed

+25
-18
lines changed

Lib/uuid.py

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,14 @@ def uuid5(namespace, name):
760760
_last_timestamp_v7 = None
761761
_last_counter_v7 = 0 # 42-bit counter
762762

763+
def _uuid7_get_counter_and_tail():
764+
rand = int.from_bytes(os.urandom(10))
765+
# 42-bit counter with MSB set to 0
766+
counter = (rand >> 32) & 0x1ff_ffff_ffff
767+
# 32-bit random data
768+
tail = rand & 0xffff_ffff
769+
return counter, tail
770+
763771
def uuid7():
764772
"""Generate a UUID from a Unix timestamp in milliseconds and random bits.
765773
@@ -778,14 +786,6 @@ def uuid7():
778786
# advanced and the counter is reset to a random 42-bit integer with MSB
779787
# set to 0.
780788

781-
def get_counter_and_tail():
782-
rand = int.from_bytes(os.urandom(10))
783-
# 42-bit counter with MSB set to 0
784-
counter = (rand >> 32) & 0x1ff_ffff_ffff
785-
# 32-bit random data
786-
tail = rand & 0xffff_ffff
787-
return counter, tail
788-
789789
global _last_timestamp_v7
790790
global _last_counter_v7
791791

@@ -794,33 +794,40 @@ def get_counter_and_tail():
794794
timestamp_ms = nanoseconds // 1_000_000
795795

796796
if _last_timestamp_v7 is None or timestamp_ms > _last_timestamp_v7:
797-
counter, tail = get_counter_and_tail()
797+
counter, tail = _uuid7_get_counter_and_tail()
798798
else:
799799
if timestamp_ms < _last_timestamp_v7:
800800
timestamp_ms = _last_timestamp_v7 + 1
801801
# advance the 42-bit counter
802802
counter = _last_counter_v7 + 1
803803
if counter > 0x3ff_ffff_ffff:
804-
timestamp_ms += 1 # advance the 48-bit timestamp
805-
counter, tail = get_counter_and_tail()
804+
# advance the 48-bit timestamp
805+
timestamp_ms += 1
806+
counter, tail = _uuid7_get_counter_and_tail()
806807
else:
808+
# 32-bit random data
807809
tail = int.from_bytes(os.urandom(4))
808810

809-
_last_timestamp_v7 = timestamp_ms
810-
_last_counter_v7 = counter
811-
812811
unix_ts_ms = timestamp_ms & 0xffff_ffff_ffff
813812
counter_msbs = counter >> 30
814-
counter_hi = counter_msbs & 0x0fff # keep 12 bits and clear variant bits
815-
counter_lo = counter & 0x3fff_ffff # keep 30 bits and clear version bits
813+
# keep 12 counter's MSBs and clear variant bits
814+
counter_hi = counter_msbs & 0x0fff
815+
# keep 30 counter's LSBs and clear version bits
816+
counter_lo = counter & 0x3fff_ffff
817+
# ensure that the fail is always a 32-bit integer
818+
tail &= 0xffff_ffff
816819

817820
int_uuid_7 = unix_ts_ms << 80
818821
int_uuid_7 |= counter_hi << 64
819822
int_uuid_7 |= counter_lo << 32
820-
int_uuid_7 |= tail & 0xffff_ffff
823+
int_uuid_7 |= tail
821824
# by construction, the variant and version bits are already cleared
822825
int_uuid_7 |= _RFC_4122_VERSION_7_FLAGS
823-
return UUID._from_int(int_uuid_7)
826+
res = UUID._from_int(int_uuid_7)
827+
# defer global update until all computations are done
828+
_last_timestamp_v7 = timestamp_ms
829+
_last_counter_v7 = counter
830+
return res
824831

825832
def uuid8(a=None, b=None, c=None):
826833
"""Generate a UUID from three custom blocks.

0 commit comments

Comments
 (0)