26 # Docket format |
26 # Docket format |
27 # |
27 # |
28 # * 4 bytes: revlog version |
28 # * 4 bytes: revlog version |
29 # | This is mandatory as docket must be compatible with the previous |
29 # | This is mandatory as docket must be compatible with the previous |
30 # | revlog index header. |
30 # | revlog index header. |
31 S_HEADER = struct.Struct(constants.INDEX_HEADER.format) |
31 # * 8 bytes: size of index data |
|
32 S_HEADER = struct.Struct(constants.INDEX_HEADER.format + 'L') |
32 |
33 |
33 |
34 |
34 class RevlogDocket(object): |
35 class RevlogDocket(object): |
35 """metadata associated with revlog""" |
36 """metadata associated with revlog""" |
36 |
37 |
37 def __init__(self, revlog, version_header=None): |
38 def __init__(self, revlog, version_header=None, index_end=0): |
38 self._version_header = version_header |
39 self._version_header = version_header |
39 self._dirty = False |
40 self._dirty = False |
40 self._radix = revlog.radix |
41 self._radix = revlog.radix |
41 self._path = revlog._docket_file |
42 self._path = revlog._docket_file |
42 self._opener = revlog.opener |
43 self._opener = revlog.opener |
|
44 self._index_end = index_end |
43 |
45 |
44 def index_filepath(self): |
46 def index_filepath(self): |
45 """file path to the current index file associated to this docket""" |
47 """file path to the current index file associated to this docket""" |
46 # very simplistic version at first |
48 # very simplistic version at first |
47 return b"%s.idx" % self._radix |
49 return b"%s.idx" % self._radix |
48 |
50 |
49 def write(self, transaction): |
51 @property |
|
52 def index_end(self): |
|
53 return self._index_end |
|
54 |
|
55 @index_end.setter |
|
56 def index_end(self, new_size): |
|
57 if new_size != self._index_end: |
|
58 self._index_end = new_size |
|
59 self._dirty = True |
|
60 |
|
61 def write(self, transaction, stripping=False): |
50 """write the modification of disk if any |
62 """write the modification of disk if any |
51 |
63 |
52 This make the new content visible to all process""" |
64 This make the new content visible to all process""" |
53 if self._dirty: |
65 if self._dirty: |
54 transaction.addbackup(self._path, location=b'store') |
66 if not stripping: |
|
67 # XXX we could, leverage the docket while stripping. However it |
|
68 # is not powerfull enough at the time of this comment |
|
69 transaction.addbackup(self._path, location=b'store') |
55 with self._opener(self._path, mode=b'w', atomictemp=True) as f: |
70 with self._opener(self._path, mode=b'w', atomictemp=True) as f: |
56 f.write(self._serialize()) |
71 f.write(self._serialize()) |
57 self._dirty = False |
72 self._dirty = False |
58 |
73 |
59 def _serialize(self): |
74 def _serialize(self): |
60 return S_HEADER.pack(self._version_header) |
75 data = ( |
|
76 self._version_header, |
|
77 self._index_end, |
|
78 ) |
|
79 return S_HEADER.pack(*data) |
61 |
80 |
62 |
81 |
63 def default_docket(revlog, version_header): |
82 def default_docket(revlog, version_header): |
64 """given a revlog version a new docket object for the given revlog""" |
83 """given a revlog version a new docket object for the given revlog""" |
65 if (version_header & 0xFFFF) != constants.REVLOGV2: |
84 if (version_header & 0xFFFF) != constants.REVLOGV2: |
70 |
89 |
71 |
90 |
72 def parse_docket(revlog, data): |
91 def parse_docket(revlog, data): |
73 """given some docket data return a docket object for the given revlog""" |
92 """given some docket data return a docket object for the given revlog""" |
74 header = S_HEADER.unpack(data[: S_HEADER.size]) |
93 header = S_HEADER.unpack(data[: S_HEADER.size]) |
75 (version_header,) = header |
94 version_header, index_size = header |
76 docket = RevlogDocket( |
95 docket = RevlogDocket( |
77 revlog, |
96 revlog, |
78 version_header=version_header, |
97 version_header=version_header, |
|
98 index_end=index_size, |
79 ) |
99 ) |
80 return docket |
100 return docket |