Mercurial > public > mercurial-scm > hg-stable
diff mercurial/revlogutils/docket.py @ 47323:7ea39d633cf3
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
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Wed, 19 May 2021 19:57:55 +0200 |
parents | 921648d31553 |
children | f612db768c7a |
line wrap: on
line diff
--- 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