Mercurial > public > mercurial-scm > hg
comparison mercurial/revlogutils/docket.py @ 47312: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 |
comparison
equal
deleted
inserted
replaced
47311:5bc6d2fc1cfc | 47312:7ea39d633cf3 |
---|---|
15 # | 15 # |
16 # * a data file, containing variable width data for these revisions, | 16 # * a data file, containing variable width data for these revisions, |
17 | 17 |
18 from __future__ import absolute_import | 18 from __future__ import absolute_import |
19 | 19 |
20 import errno | |
21 import os | |
22 import random | |
20 import struct | 23 import struct |
21 | 24 |
22 from .. import ( | 25 from .. import ( |
26 encoding, | |
23 error, | 27 error, |
28 node, | |
29 pycompat, | |
24 util, | 30 util, |
25 ) | 31 ) |
26 | 32 |
27 from . import ( | 33 from . import ( |
28 constants, | 34 constants, |
29 ) | 35 ) |
36 | |
37 | |
38 def make_uid(id_size=8): | |
39 """return a new unique identifier. | |
40 | |
41 The identifier is random and composed of ascii characters.""" | |
42 # size we "hex" the result we need half the number of bits to have a final | |
43 # uuid of size ID_SIZE | |
44 return node.hex(os.urandom(id_size // 2)) | |
45 | |
46 | |
47 # some special test logic to avoid anoying random output in the test | |
48 stable_docket_file = encoding.environ.get(b'HGTEST_UUIDFILE') | |
49 | |
50 if stable_docket_file: | |
51 | |
52 def make_uid(id_size=8): | |
53 try: | |
54 with open(stable_docket_file, mode='rb') as f: | |
55 seed = f.read().strip() | |
56 except IOError as inst: | |
57 if inst.errno != errno.ENOENT: | |
58 raise | |
59 seed = b'04' # chosen by a fair dice roll. garanteed to be random | |
60 if pycompat.ispy3: | |
61 iter_seed = iter(seed) | |
62 else: | |
63 iter_seed = (ord(c) for c in seed) | |
64 # some basic circular sum hashing on 64 bits | |
65 int_seed = 0 | |
66 low_mask = int('1' * 35, 2) | |
67 for i in iter_seed: | |
68 high_part = int_seed >> 35 | |
69 low_part = (int_seed & low_mask) << 28 | |
70 int_seed = high_part + low_part + i | |
71 r = random.Random() | |
72 if pycompat.ispy3: | |
73 r.seed(int_seed, version=1) | |
74 else: | |
75 r.seed(int_seed) | |
76 # once we drop python 3.8 support we can simply use r.randbytes | |
77 raw = r.getrandbits(id_size * 4) | |
78 assert id_size == 8 | |
79 p = struct.pack('>L', raw) | |
80 new = node.hex(p) | |
81 with open(stable_docket_file, 'wb') as f: | |
82 f.write(new) | |
83 return new | |
84 | |
30 | 85 |
31 # Docket format | 86 # Docket format |
32 # | 87 # |
33 # * 4 bytes: revlog version | 88 # * 4 bytes: revlog version |
34 # | This is mandatory as docket must be compatible with the previous | 89 # | This is mandatory as docket must be compatible with the previous |