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):