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