Show More
@@ -342,6 +342,38 b' static PyObject *index_get(indexObject *' | |||
|
342 | 342 | sidedata_offset, sidedata_comp_len); |
|
343 | 343 | } |
|
344 | 344 | } |
|
345 | /* | |
|
346 | * Return the raw binary string representing a revision | |
|
347 | */ | |
|
348 | static PyObject *index_entry_binary(indexObject *self, PyObject *args) | |
|
349 | { | |
|
350 | long rev; | |
|
351 | int header; | |
|
352 | const char *data; | |
|
353 | char entry[v2_hdrsize]; | |
|
354 | ||
|
355 | Py_ssize_t length = index_length(self); | |
|
356 | ||
|
357 | if (!PyArg_ParseTuple(args, "lI", &rev, &header)) { | |
|
358 | return NULL; | |
|
359 | } | |
|
360 | if (rev < 0 || rev >= length) { | |
|
361 | PyErr_Format(PyExc_ValueError, "revlog index out of range: %ld", | |
|
362 | rev); | |
|
363 | return NULL; | |
|
364 | }; | |
|
365 | ||
|
366 | data = index_deref(self, rev); | |
|
367 | if (data == NULL) | |
|
368 | return NULL; | |
|
369 | if (rev == 0) { | |
|
370 | // put the header at the start of the first entry | |
|
371 | memcpy(entry, data, self->hdrsize); | |
|
372 | putbe32(header, entry); | |
|
373 | return PyBytes_FromStringAndSize(entry, self->hdrsize); | |
|
374 | } | |
|
375 | return PyBytes_FromStringAndSize(data, self->hdrsize); | |
|
376 | } | |
|
345 | 377 | |
|
346 | 378 | /* |
|
347 | 379 | * Return the hash of node corresponding to the given rev. |
@@ -2859,6 +2891,8 b' static PyMethodDef index_methods[] = {' | |||
|
2859 | 2891 | {"shortest", (PyCFunction)index_shortest, METH_VARARGS, |
|
2860 | 2892 | "find length of shortest hex nodeid of a binary ID"}, |
|
2861 | 2893 | {"stats", (PyCFunction)index_stats, METH_NOARGS, "stats for the index"}, |
|
2894 | {"entry_binary", (PyCFunction)index_entry_binary, METH_VARARGS, | |
|
2895 | "return an entry in binary form"}, | |
|
2862 | 2896 | {NULL} /* Sentinel */ |
|
2863 | 2897 | }; |
|
2864 | 2898 |
@@ -127,10 +127,24 b' class BaseIndexObject(object):' | |||
|
127 | 127 | r = (offset_type(0, gettype(r[0])),) + r[1:] |
|
128 | 128 | return r |
|
129 | 129 | |
|
130 | def entry_binary(self, rev, header): | |
|
131 | """return the raw binary string representing a revision""" | |
|
132 | entry = self[rev] | |
|
133 | p = revlog_constants.INDEX_ENTRY_V1.pack(*entry) | |
|
134 | if rev == 0: | |
|
135 | v_fmt = revlog_constants.INDEX_HEADER | |
|
136 | v_bin = v_fmt.pack(header) | |
|
137 | p = v_bin + p[v_fmt.size :] | |
|
138 | return p | |
|
139 | ||
|
130 | 140 | |
|
131 | 141 | class IndexObject(BaseIndexObject): |
|
132 | 142 | def __init__(self, data): |
|
133 | assert len(data) % self.entry_size == 0 | |
|
143 | assert len(data) % self.entry_size == 0, ( | |
|
144 | len(data), | |
|
145 | self.entry_size, | |
|
146 | len(data) % self.entry_size, | |
|
147 | ) | |
|
134 | 148 | self._data = data |
|
135 | 149 | self._lgt = len(data) // self.entry_size |
|
136 | 150 | self._extra = [] |
@@ -272,6 +286,16 b' class Index2Mixin(object):' | |||
|
272 | 286 | msg = b"cannot rewrite entries outside of this transaction" |
|
273 | 287 | raise KeyError(msg) |
|
274 | 288 | |
|
289 | def entry_binary(self, rev, header): | |
|
290 | """return the raw binary string representing a revision""" | |
|
291 | entry = self[rev] | |
|
292 | p = revlog_constants.INDEX_ENTRY_V2.pack(*entry) | |
|
293 | if rev == 0: | |
|
294 | v_fmt = revlog_constants.INDEX_HEADER | |
|
295 | v_bin = v_fmt.pack(header) | |
|
296 | p = v_bin + p[v_fmt.size :] | |
|
297 | return p | |
|
298 | ||
|
275 | 299 | |
|
276 | 300 | class IndexObject2(Index2Mixin, IndexObject): |
|
277 | 301 | pass |
@@ -268,6 +268,24 b' class revlogoldindex(list):' | |||
|
268 | 268 | return (0, 0, 0, -1, -1, -1, -1, sha1nodeconstants.nullid) |
|
269 | 269 | return list.__getitem__(self, i) |
|
270 | 270 | |
|
271 | def entry_binary(self, rev, header): | |
|
272 | """return the raw binary string representing a revision""" | |
|
273 | entry = self[rev] | |
|
274 | if gettype(entry[0]): | |
|
275 | raise error.RevlogError( | |
|
276 | _(b'index entry flags need revlog version 1') | |
|
277 | ) | |
|
278 | e2 = ( | |
|
279 | getoffset(entry[0]), | |
|
280 | entry[1], | |
|
281 | entry[3], | |
|
282 | entry[4], | |
|
283 | self[entry[5]][7], | |
|
284 | self[entry[6]][7], | |
|
285 | entry[7], | |
|
286 | ) | |
|
287 | return INDEX_ENTRY_V0.pack(*e2) | |
|
288 | ||
|
271 | 289 | |
|
272 | 290 | class revlogoldio(object): |
|
273 | 291 | def parseindex(self, data, inline): |
@@ -298,29 +316,6 b' class revlogoldio(object):' | |||
|
298 | 316 | index = revlogoldindex(index) |
|
299 | 317 | return index, None |
|
300 | 318 | |
|
301 | def packentry(self, entry, node, version, rev): | |
|
302 | """return the binary representation of an entry | |
|
303 | ||
|
304 | entry: a tuple containing all the values (see index.__getitem__) | |
|
305 | node: a callback to convert a revision to nodeid | |
|
306 | version: the changelog version | |
|
307 | rev: the revision number | |
|
308 | """ | |
|
309 | if gettype(entry[0]): | |
|
310 | raise error.RevlogError( | |
|
311 | _(b'index entry flags need revlog version 1') | |
|
312 | ) | |
|
313 | e2 = ( | |
|
314 | getoffset(entry[0]), | |
|
315 | entry[1], | |
|
316 | entry[3], | |
|
317 | entry[4], | |
|
318 | node(entry[5]), | |
|
319 | node(entry[6]), | |
|
320 | entry[7], | |
|
321 | ) | |
|
322 | return INDEX_ENTRY_V0.pack(*e2) | |
|
323 | ||
|
324 | 319 | |
|
325 | 320 | # corresponds to uncompressed length of indexformatng (2 gigs, 4-byte |
|
326 | 321 | # signed integer) |
@@ -333,24 +328,12 b' class revlogio(object):' | |||
|
333 | 328 | index, cache = parsers.parse_index2(data, inline) |
|
334 | 329 | return index, cache |
|
335 | 330 | |
|
336 | def packentry(self, entry, node, version, rev): | |
|
337 | p = INDEX_ENTRY_V1.pack(*entry) | |
|
338 | if rev == 0: | |
|
339 | p = INDEX_HEADER.pack(version) + p[4:] | |
|
340 | return p | |
|
341 | ||
|
342 | 331 | |
|
343 | 332 | class revlogv2io(object): |
|
344 | 333 | def parseindex(self, data, inline): |
|
345 | 334 | index, cache = parsers.parse_index2(data, inline, revlogv2=True) |
|
346 | 335 | return index, cache |
|
347 | 336 | |
|
348 | def packentry(self, entry, node, version, rev): | |
|
349 | p = INDEX_ENTRY_V2.pack(*entry) | |
|
350 | if rev == 0: | |
|
351 | p = INDEX_HEADER.pack(version) + p[4:] | |
|
352 | return p | |
|
353 | ||
|
354 | 337 | |
|
355 | 338 | NodemapRevlogIO = None |
|
356 | 339 | |
@@ -2068,7 +2051,7 b' class revlog(object):' | |||
|
2068 | 2051 | self._inline = False |
|
2069 | 2052 | io = self._io |
|
2070 | 2053 | for i in self: |
|
2071 |
e = |
|
|
2054 | e = self.index.entry_binary(i, self.version) | |
|
2072 | 2055 | fp.write(e) |
|
2073 | 2056 | |
|
2074 | 2057 | # the temp file replace the real index when we exit the context |
@@ -2390,7 +2373,7 b' class revlog(object):' | |||
|
2390 | 2373 | e = e[:8] |
|
2391 | 2374 | |
|
2392 | 2375 | self.index.append(e) |
|
2393 |
entry = self. |
|
|
2376 | entry = self.index.entry_binary(curr, self.version) | |
|
2394 | 2377 | self._writeentry( |
|
2395 | 2378 | transaction, |
|
2396 | 2379 | ifh, |
@@ -3243,5 +3226,5 b' class revlog(object):' | |||
|
3243 | 3226 | for i, entry in enumerate(new_entries): |
|
3244 | 3227 | rev = startrev + i |
|
3245 | 3228 | self.index.replace_sidedata_info(rev, entry[8], entry[9]) |
|
3246 |
packed = self. |
|
|
3229 | packed = self.index.entry_binary(rev, self.version) | |
|
3247 | 3230 | fp.write(packed) |
@@ -172,6 +172,11 b' py_class!(pub class MixedIndex |py| {' | |||
|
172 | 172 | self.call_cindex(py, "clearcaches", args, kw) |
|
173 | 173 | } |
|
174 | 174 | |
|
175 | /// return the raw binary string representing a revision | |
|
176 | def entry_binary(&self, *args, **kw) -> PyResult<PyObject> { | |
|
177 | self.call_cindex(py, "entry_binary", args, kw) | |
|
178 | } | |
|
179 | ||
|
175 | 180 | /// get an index entry |
|
176 | 181 | def get(&self, *args, **kw) -> PyResult<PyObject> { |
|
177 | 182 | self.call_cindex(py, "get", args, kw) |
General Comments 0
You need to be logged in to leave comments.
Login now