docket: move the uid logic in the `revlogutils.docket` module
We want to use it for revlog-v2 (& Co), it seems more logical to have the logic
lives inside the `docket` file than the `nodemap` file.
Differential Revision: https://phab.mercurial-scm.org/D10755
--- a/mercurial/revlogutils/docket.py Wed May 19 17:12:06 2021 +0200
+++ b/mercurial/revlogutils/docket.py Wed May 19 19:57:55 2021 +0200
@@ -17,10 +17,16 @@
from __future__ import absolute_import
+import errno
+import os
+import random
import struct
from .. import (
+ encoding,
error,
+ node,
+ pycompat,
util,
)
@@ -28,6 +34,55 @@
constants,
)
+
+def make_uid(id_size=8):
+ """return a new unique identifier.
+
+ The identifier is random and composed of ascii characters."""
+ # size we "hex" the result we need half the number of bits to have a final
+ # uuid of size ID_SIZE
+ return node.hex(os.urandom(id_size // 2))
+
+
+# some special test logic to avoid anoying random output in the test
+stable_docket_file = encoding.environ.get(b'HGTEST_UUIDFILE')
+
+if stable_docket_file:
+
+ def make_uid(id_size=8):
+ try:
+ with open(stable_docket_file, mode='rb') as f:
+ seed = f.read().strip()
+ except IOError as inst:
+ if inst.errno != errno.ENOENT:
+ raise
+ seed = b'04' # chosen by a fair dice roll. garanteed to be random
+ if pycompat.ispy3:
+ iter_seed = iter(seed)
+ else:
+ iter_seed = (ord(c) for c in seed)
+ # some basic circular sum hashing on 64 bits
+ int_seed = 0
+ low_mask = int('1' * 35, 2)
+ for i in iter_seed:
+ high_part = int_seed >> 35
+ low_part = (int_seed & low_mask) << 28
+ int_seed = high_part + low_part + i
+ r = random.Random()
+ if pycompat.ispy3:
+ r.seed(int_seed, version=1)
+ else:
+ r.seed(int_seed)
+ # once we drop python 3.8 support we can simply use r.randbytes
+ raw = r.getrandbits(id_size * 4)
+ assert id_size == 8
+ p = struct.pack('>L', raw)
+ new = node.hex(p)
+ with open(stable_docket_file, 'wb') as f:
+ f.write(new)
+ return new
+
+
# Docket format
#
# * 4 bytes: revlog version
--- a/mercurial/revlogutils/nodemap.py Wed May 19 17:12:06 2021 +0200
+++ b/mercurial/revlogutils/nodemap.py Wed May 19 19:57:55 2021 +0200
@@ -9,19 +9,16 @@
from __future__ import absolute_import
import errno
-import os
-import random
import re
import struct
from ..node import hex
from .. import (
- encoding,
error,
- pycompat,
util,
)
+from . import docket as docket_mod
class NodeMap(dict):
@@ -281,56 +278,6 @@
S_VERSION = struct.Struct(">B")
S_HEADER = struct.Struct(">BQQQQ")
-ID_SIZE = 8
-
-
-def _make_uid():
- """return a new unique identifier.
-
- The identifier is random and composed of ascii characters."""
- # size we "hex" the result we need half the number of bits to have a final
- # uuid of size ID_SIZE
- return hex(os.urandom(ID_SIZE // 2))
-
-
-# some special test logic to avoid anoying random output in the test
-stable_docket_file = encoding.environ.get(b'HGTEST_DOCKETIDFILE')
-
-if stable_docket_file:
-
- def _make_uid():
- try:
- with open(stable_docket_file, mode='rb') as f:
- seed = f.read().strip()
- except IOError as inst:
- if inst.errno != errno.ENOENT:
- raise
- seed = b'4' # chosen by a fair dice roll. garanteed to be random
- if pycompat.ispy3:
- iter_seed = iter(seed)
- else:
- iter_seed = (ord(c) for c in seed)
- # some basic circular sum hashing on 64 bits
- int_seed = 0
- low_mask = int('1' * 35, 2)
- for i in iter_seed:
- high_part = int_seed >> 35
- low_part = (int_seed & low_mask) << 28
- int_seed = high_part + low_part + i
- r = random.Random()
- if pycompat.ispy3:
- r.seed(int_seed, version=1)
- else:
- r.seed(int_seed)
- # once we drop python 3.8 support we can simply use r.randbytes
- raw = r.getrandbits(ID_SIZE * 4)
- assert ID_SIZE == 8
- p = struct.pack('>L', raw)
- new = hex(p)
- with open(stable_docket_file, 'wb') as f:
- f.write(new)
- return new
-
class NodeMapDocket(object):
"""metadata associated with persistent nodemap data
@@ -340,7 +287,7 @@
def __init__(self, uid=None):
if uid is None:
- uid = _make_uid()
+ uid = docket_mod.make_uid()
# a unique identifier for the data file:
# - When new data are appended, it is preserved.
# - When a new data file is created, a new identifier is generated.
--- a/tests/run-tests.py Wed May 19 17:12:06 2021 +0200
+++ b/tests/run-tests.py Wed May 19 19:57:55 2021 +0200
@@ -1386,8 +1386,8 @@
env['PYTHONUSERBASE'] = sysconfig.get_config_var('userbase') or ''
env['HGEMITWARNINGS'] = '1'
env['TESTTMP'] = _bytes2sys(self._testtmp)
- docket_id_file = os.path.join(_bytes2sys(self._testtmp), 'DOCKETID')
- env['HGTEST_DOCKETIDFILE'] = docket_id_file
+ uid_file = os.path.join(_bytes2sys(self._testtmp), 'UID')
+ env['HGTEST_UUIDFILE'] = uid_file
env['TESTNAME'] = self.name
env['HOME'] = _bytes2sys(self._testtmp)
if os.name == 'nt':