Mercurial > hg
comparison mercurial/pure/parsers.py @ 46407:095fa99ae5f5
revlog: prepare pure parser for being overloaded
The current class uses module-level variables which don't allow for reusing the
current logic for a slightly different revlog version.
Differential Revision: https://phab.mercurial-scm.org/D9903
author | Raphaël Gomès <rgomes@octobus.net> |
---|---|
date | Thu, 28 Jan 2021 15:26:33 +0100 |
parents | 89a2afe31e82 |
children | e83327af26f1 |
comparison
equal
deleted
inserted
replaced
46406:95054317e172 | 46407:095fa99ae5f5 |
---|---|
31 def dirstatetuple(*x): | 31 def dirstatetuple(*x): |
32 # x is a tuple | 32 # x is a tuple |
33 return x | 33 return x |
34 | 34 |
35 | 35 |
36 indexformatng = b">Qiiiiii20s12x" | |
37 indexfirst = struct.calcsize(b'Q') | |
38 sizeint = struct.calcsize(b'i') | |
39 indexsize = struct.calcsize(indexformatng) | |
40 nullitem = (0, 0, 0, -1, -1, -1, -1, nullid) | |
41 | |
42 | |
43 def gettype(q): | 36 def gettype(q): |
44 return int(q & 0xFFFF) | 37 return int(q & 0xFFFF) |
45 | 38 |
46 | 39 |
47 def offset_type(offset, type): | 40 def offset_type(offset, type): |
48 return int(int(offset) << 16 | type) | 41 return int(int(offset) << 16 | type) |
49 | 42 |
50 | 43 |
51 class BaseIndexObject(object): | 44 class BaseIndexObject(object): |
45 index_format = b">Qiiiiii20s12x" | |
46 big_int_size = struct.calcsize(b'Q') | |
47 int_size = struct.calcsize(b'i') | |
48 index_size = struct.calcsize(index_format) | |
49 null_item = (0, 0, 0, -1, -1, -1, -1, nullid) | |
50 | |
52 @property | 51 @property |
53 def nodemap(self): | 52 def nodemap(self): |
54 msg = b"index.nodemap is deprecated, use index.[has_node|rev|get_rev]" | 53 msg = b"index.nodemap is deprecated, use index.[has_node|rev|get_rev]" |
55 util.nouideprecwarn(msg, b'5.3', stacklevel=2) | 54 util.nouideprecwarn(msg, b'5.3', stacklevel=2) |
56 return self._nodemap | 55 return self._nodemap |
92 return self._lgt + len(self._extra) | 91 return self._lgt + len(self._extra) |
93 | 92 |
94 def append(self, tup): | 93 def append(self, tup): |
95 if '_nodemap' in vars(self): | 94 if '_nodemap' in vars(self): |
96 self._nodemap[tup[7]] = len(self) | 95 self._nodemap[tup[7]] = len(self) |
97 data = _pack(indexformatng, *tup) | 96 data = _pack(self.index_format, *tup) |
98 self._extra.append(data) | 97 self._extra.append(data) |
99 | 98 |
100 def _check_index(self, i): | 99 def _check_index(self, i): |
101 if not isinstance(i, int): | 100 if not isinstance(i, int): |
102 raise TypeError(b"expecting int indexes") | 101 raise TypeError(b"expecting int indexes") |
103 if i < 0 or i >= len(self): | 102 if i < 0 or i >= len(self): |
104 raise IndexError | 103 raise IndexError |
105 | 104 |
106 def __getitem__(self, i): | 105 def __getitem__(self, i): |
107 if i == -1: | 106 if i == -1: |
108 return nullitem | 107 return self.null_item |
109 self._check_index(i) | 108 self._check_index(i) |
110 if i >= self._lgt: | 109 if i >= self._lgt: |
111 data = self._extra[i - self._lgt] | 110 data = self._extra[i - self._lgt] |
112 else: | 111 else: |
113 index = self._calculate_index(i) | 112 index = self._calculate_index(i) |
114 data = self._data[index : index + indexsize] | 113 data = self._data[index : index + self.index_size] |
115 r = _unpack(indexformatng, data) | 114 r = _unpack(self.index_format, data) |
116 if self._lgt and i == 0: | 115 if self._lgt and i == 0: |
117 r = (offset_type(0, gettype(r[0])),) + r[1:] | 116 r = (offset_type(0, gettype(r[0])),) + r[1:] |
118 return r | 117 return r |
119 | 118 |
120 | 119 |
121 class IndexObject(BaseIndexObject): | 120 class IndexObject(BaseIndexObject): |
122 def __init__(self, data): | 121 def __init__(self, data): |
123 assert len(data) % indexsize == 0 | 122 assert len(data) % self.index_size == 0 |
124 self._data = data | 123 self._data = data |
125 self._lgt = len(data) // indexsize | 124 self._lgt = len(data) // self.index_size |
126 self._extra = [] | 125 self._extra = [] |
127 | 126 |
128 def _calculate_index(self, i): | 127 def _calculate_index(self, i): |
129 return i * indexsize | 128 return i * self.index_size |
130 | 129 |
131 def __delitem__(self, i): | 130 def __delitem__(self, i): |
132 if not isinstance(i, slice) or not i.stop == -1 or i.step is not None: | 131 if not isinstance(i, slice) or not i.stop == -1 or i.step is not None: |
133 raise ValueError(b"deleting slices only supports a:-1 with step 1") | 132 raise ValueError(b"deleting slices only supports a:-1 with step 1") |
134 i = i.start | 133 i = i.start |
135 self._check_index(i) | 134 self._check_index(i) |
136 self._stripnodes(i) | 135 self._stripnodes(i) |
137 if i < self._lgt: | 136 if i < self._lgt: |
138 self._data = self._data[: i * indexsize] | 137 self._data = self._data[: i * self.index_size] |
139 self._lgt = i | 138 self._lgt = i |
140 self._extra = [] | 139 self._extra = [] |
141 else: | 140 else: |
142 self._extra = self._extra[: i - self._lgt] | 141 self._extra = self._extra[: i - self._lgt] |
143 | 142 |
196 def _inline_scan(self, lgt): | 195 def _inline_scan(self, lgt): |
197 off = 0 | 196 off = 0 |
198 if lgt is not None: | 197 if lgt is not None: |
199 self._offsets = [0] * lgt | 198 self._offsets = [0] * lgt |
200 count = 0 | 199 count = 0 |
201 while off <= len(self._data) - indexsize: | 200 while off <= len(self._data) - self.index_size: |
201 start = off + self.big_int_size | |
202 (s,) = struct.unpack( | 202 (s,) = struct.unpack( |
203 b'>i', self._data[off + indexfirst : off + sizeint + indexfirst] | 203 b'>i', |
204 self._data[start : start + self.int_size], | |
204 ) | 205 ) |
205 if lgt is not None: | 206 if lgt is not None: |
206 self._offsets[count] = off | 207 self._offsets[count] = off |
207 count += 1 | 208 count += 1 |
208 off += indexsize + s | 209 off += self.index_size + s |
209 if off != len(self._data): | 210 if off != len(self._data): |
210 raise ValueError(b"corrupted data") | 211 raise ValueError(b"corrupted data") |
211 return count | 212 return count |
212 | 213 |
213 def __delitem__(self, i): | 214 def __delitem__(self, i): |