##// END OF EJS Templates
revlog: add a "data compression mode" entry in the index tuple...
marmoute -
r48023:130c9f7e default
parent child Browse files
Show More
@@ -105,6 +105,7 b' class bundlerevlog(revlog.revlog):'
105 node,
105 node,
106 0,
106 0,
107 0,
107 0,
108 revlog_constants.COMP_MODE_INLINE,
108 )
109 )
109 self.index.append(e)
110 self.index.append(e)
110 self.bundlerevs.add(n)
111 self.bundlerevs.add(n)
@@ -668,7 +668,7 b' void dirs_module_init(PyObject *mod);'
668 void manifest_module_init(PyObject *mod);
668 void manifest_module_init(PyObject *mod);
669 void revlog_module_init(PyObject *mod);
669 void revlog_module_init(PyObject *mod);
670
670
671 static const int version = 18;
671 static const int version = 19;
672
672
673 static void module_init(PyObject *mod)
673 static void module_init(PyObject *mod)
674 {
674 {
@@ -118,9 +118,9 b' static Py_ssize_t inline_scan(indexObjec'
118 static int index_find_node(indexObject *self, const char *node);
118 static int index_find_node(indexObject *self, const char *node);
119
119
120 #if LONG_MAX == 0x7fffffffL
120 #if LONG_MAX == 0x7fffffffL
121 static const char *const tuple_format = PY23("Kiiiiiis#Ki", "Kiiiiiiy#Ki");
121 static const char *const tuple_format = PY23("Kiiiiiis#KiB", "Kiiiiiiy#KiB");
122 #else
122 #else
123 static const char *const tuple_format = PY23("kiiiiiis#ki", "kiiiiiiy#ki");
123 static const char *const tuple_format = PY23("kiiiiiis#kiB", "kiiiiiiy#kiB");
124 #endif
124 #endif
125
125
126 /* A RevlogNG v1 index entry is 64 bytes long. */
126 /* A RevlogNG v1 index entry is 64 bytes long. */
@@ -132,6 +132,8 b' static const long v2_entry_size = 96;'
132 static const long format_v1 = 1; /* Internal only, could be any number */
132 static const long format_v1 = 1; /* Internal only, could be any number */
133 static const long format_v2 = 2; /* Internal only, could be any number */
133 static const long format_v2 = 2; /* Internal only, could be any number */
134
134
135 static const char comp_mode_inline = 2;
136
135 static void raise_revlog_error(void)
137 static void raise_revlog_error(void)
136 {
138 {
137 PyObject *mod = NULL, *dict = NULL, *errclass = NULL;
139 PyObject *mod = NULL, *dict = NULL, *errclass = NULL;
@@ -294,6 +296,7 b' static PyObject *index_get(indexObject *'
294 uint64_t offset_flags, sidedata_offset;
296 uint64_t offset_flags, sidedata_offset;
295 int comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2,
297 int comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2,
296 sidedata_comp_len;
298 sidedata_comp_len;
299 char data_comp_mode;
297 const char *c_node_id;
300 const char *c_node_id;
298 const char *data;
301 const char *data;
299 Py_ssize_t length = index_length(self);
302 Py_ssize_t length = index_length(self);
@@ -340,9 +343,11 b' static PyObject *index_get(indexObject *'
340 sidedata_comp_len = getbe32(data + 72);
343 sidedata_comp_len = getbe32(data + 72);
341 }
344 }
342
345
346 data_comp_mode = comp_mode_inline;
343 return Py_BuildValue(tuple_format, offset_flags, comp_len, uncomp_len,
347 return Py_BuildValue(tuple_format, offset_flags, comp_len, uncomp_len,
344 base_rev, link_rev, parent_1, parent_2, c_node_id,
348 base_rev, link_rev, parent_1, parent_2, c_node_id,
345 self->nodelen, sidedata_offset, sidedata_comp_len);
349 self->nodelen, sidedata_offset, sidedata_comp_len,
350 data_comp_mode);
346 }
351 }
347 /*
352 /*
348 * Pack header information in binary
353 * Pack header information in binary
@@ -443,6 +448,7 b' static PyObject *index_append(indexObjec'
443 {
448 {
444 uint64_t offset_flags, sidedata_offset;
449 uint64_t offset_flags, sidedata_offset;
445 int rev, comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2;
450 int rev, comp_len, uncomp_len, base_rev, link_rev, parent_1, parent_2;
451 char data_comp_mode;
446 Py_ssize_t c_node_id_len, sidedata_comp_len;
452 Py_ssize_t c_node_id_len, sidedata_comp_len;
447 const char *c_node_id;
453 const char *c_node_id;
448 char *data;
454 char *data;
@@ -450,8 +456,9 b' static PyObject *index_append(indexObjec'
450 if (!PyArg_ParseTuple(obj, tuple_format, &offset_flags, &comp_len,
456 if (!PyArg_ParseTuple(obj, tuple_format, &offset_flags, &comp_len,
451 &uncomp_len, &base_rev, &link_rev, &parent_1,
457 &uncomp_len, &base_rev, &link_rev, &parent_1,
452 &parent_2, &c_node_id, &c_node_id_len,
458 &parent_2, &c_node_id, &c_node_id_len,
453 &sidedata_offset, &sidedata_comp_len)) {
459 &sidedata_offset, &sidedata_comp_len,
454 PyErr_SetString(PyExc_TypeError, "10-tuple required");
460 &data_comp_mode)) {
461 PyErr_SetString(PyExc_TypeError, "11-tuple required");
455 return NULL;
462 return NULL;
456 }
463 }
457
464
@@ -459,6 +466,12 b' static PyObject *index_append(indexObjec'
459 PyErr_SetString(PyExc_TypeError, "invalid node");
466 PyErr_SetString(PyExc_TypeError, "invalid node");
460 return NULL;
467 return NULL;
461 }
468 }
469 if (data_comp_mode != comp_mode_inline) {
470 PyErr_Format(PyExc_ValueError,
471 "invalid data compression mode: %i",
472 data_comp_mode);
473 return NULL;
474 }
462
475
463 if (self->new_length == self->added_length) {
476 if (self->new_length == self->added_length) {
464 size_t new_added_length =
477 size_t new_added_length =
@@ -2761,9 +2774,9 b' static int index_init(indexObject *self,'
2761 self->entry_size = v1_entry_size;
2774 self->entry_size = v1_entry_size;
2762 }
2775 }
2763
2776
2764 self->nullentry =
2777 self->nullentry = Py_BuildValue(PY23("iiiiiiis#iiB", "iiiiiiiy#iiB"), 0,
2765 Py_BuildValue(PY23("iiiiiiis#ii", "iiiiiiiy#ii"), 0, 0, 0, -1, -1,
2778 0, 0, -1, -1, -1, -1, nullid,
2766 -1, -1, nullid, self->nodelen, 0, 0);
2779 self->nodelen, 0, 0, comp_mode_inline);
2767
2780
2768 if (!self->nullentry)
2781 if (!self->nullentry)
2769 return -1;
2782 return -1;
@@ -80,7 +80,7 b' def _importfrom(pkgname, modname):'
80 ('cext', 'bdiff'): 3,
80 ('cext', 'bdiff'): 3,
81 ('cext', 'mpatch'): 1,
81 ('cext', 'mpatch'): 1,
82 ('cext', 'osutil'): 4,
82 ('cext', 'osutil'): 4,
83 ('cext', 'parsers'): 18,
83 ('cext', 'parsers'): 19,
84 }
84 }
85
85
86 # map import request to other package or module
86 # map import request to other package or module
@@ -54,7 +54,19 b' class BaseIndexObject(object):'
54 # Size of a C long int, platform independent
54 # Size of a C long int, platform independent
55 int_size = struct.calcsize(b'>i')
55 int_size = struct.calcsize(b'>i')
56 # An empty index entry, used as a default value to be overridden, or nullrev
56 # An empty index entry, used as a default value to be overridden, or nullrev
57 null_item = (0, 0, 0, -1, -1, -1, -1, sha1nodeconstants.nullid, 0, 0)
57 null_item = (
58 0,
59 0,
60 0,
61 -1,
62 -1,
63 -1,
64 -1,
65 sha1nodeconstants.nullid,
66 0,
67 0,
68 revlog_constants.COMP_MODE_INLINE,
69 )
58
70
59 @util.propertycache
71 @util.propertycache
60 def entry_size(self):
72 def entry_size(self):
@@ -135,7 +147,7 b' class BaseIndexObject(object):'
135
147
136 def _unpack_entry(self, data):
148 def _unpack_entry(self, data):
137 r = self.index_format.unpack(data)
149 r = self.index_format.unpack(data)
138 r = r + (0, 0)
150 r = r + (0, 0, revlog_constants.COMP_MODE_INLINE)
139 return r
151 return r
140
152
141 def pack_header(self, header):
153 def pack_header(self, header):
@@ -303,16 +315,17 b' class Index2Mixin(object):'
303 self._extra[rev - self._lgt] = new
315 self._extra[rev - self._lgt] = new
304
316
305 def _unpack_entry(self, data):
317 def _unpack_entry(self, data):
306 return self.index_format.unpack(data)
318 return self.index_format.unpack(data) + (
319 revlog_constants.COMP_MODE_INLINE,
320 )
307
321
308 def _pack_entry(self, entry):
322 def _pack_entry(self, entry):
309 return self.index_format.pack(*entry)
323 return self.index_format.pack(*entry[:10])
310
324
311 def entry_binary(self, rev):
325 def entry_binary(self, rev):
312 """return the raw binary string representing a revision"""
326 """return the raw binary string representing a revision"""
313 entry = self[rev]
327 entry = self[rev]
314 p = revlog_constants.INDEX_ENTRY_V2.pack(*entry)
328 return self._pack_entry(entry)
315 return p
316
329
317 def pack_header(self, header):
330 def pack_header(self, header):
318 """pack header information as binary"""
331 """pack header information as binary"""
@@ -35,6 +35,7 b' from .i18n import _'
35 from .pycompat import getattr
35 from .pycompat import getattr
36 from .revlogutils.constants import (
36 from .revlogutils.constants import (
37 ALL_KINDS,
37 ALL_KINDS,
38 COMP_MODE_INLINE,
38 FEATURES_BY_VERSION,
39 FEATURES_BY_VERSION,
39 FLAG_GENERALDELTA,
40 FLAG_GENERALDELTA,
40 FLAG_INLINE_DATA,
41 FLAG_INLINE_DATA,
@@ -336,6 +337,12 b' class revlog(object):'
336
337
337 [9] sidedata chunk length:
338 [9] sidedata chunk length:
338 The size, in bytes, of the revision's side-data chunk.
339 The size, in bytes, of the revision's side-data chunk.
340
341 [10] data compression mode:
342 two bits that detail the way the data chunk is compressed on disk.
343 (see "COMP_MODE_*" constants for details). For revlog version 0 and
344 1 this will always be COMP_MODE_INLINE.
345
339 """
346 """
340
347
341 _flagserrorclass = error.RevlogError
348 _flagserrorclass = error.RevlogError
@@ -2474,6 +2481,7 b' class revlog(object):'
2474 node,
2481 node,
2475 sidedata_offset,
2482 sidedata_offset,
2476 len(serialized_sidedata),
2483 len(serialized_sidedata),
2484 COMP_MODE_INLINE,
2477 )
2485 )
2478
2486
2479 self.index.append(e)
2487 self.index.append(e)
@@ -1,4 +1,4 b''
1 # revlogdeltas.py - constant used for revlog logic
1 # revlogdeltas.py - constant used for revlog logic.
2 #
2 #
3 # Copyright 2005-2007 Olivia Mackall <olivia@selenic.com>
3 # Copyright 2005-2007 Olivia Mackall <olivia@selenic.com>
4 # Copyright 2018 Octobus <contact@octobus.net>
4 # Copyright 2018 Octobus <contact@octobus.net>
@@ -114,6 +114,14 b' REVIDX_FLAGS_ORDER = ['
114 # bitmark for flags that could cause rawdata content change
114 # bitmark for flags that could cause rawdata content change
115 REVIDX_RAWTEXT_CHANGING_FLAGS = REVIDX_ISCENSORED | REVIDX_EXTSTORED
115 REVIDX_RAWTEXT_CHANGING_FLAGS = REVIDX_ISCENSORED | REVIDX_EXTSTORED
116
116
117 ## chunk compression mode constants:
118 # These constants are used in revlog version >=2 to denote the compression used
119 # for a chunk.
120
121 # Chunk use a compression mode stored "inline" at the start of the chunk
122 # itself. This is the mode always used for revlog version "0" and "1"
123 COMP_MODE_INLINE = 2
124
117 SUPPORTED_FLAGS = {
125 SUPPORTED_FLAGS = {
118 REVLOGV0: REVLOGV0_FLAGS,
126 REVLOGV0: REVLOGV0_FLAGS,
119 REVLOGV1: REVLOGV1_FLAGS,
127 REVLOGV1: REVLOGV1_FLAGS,
@@ -152,4 +160,5 b' FEATURES_BY_VERSION = {'
152 },
160 },
153 }
161 }
154
162
163
155 SPARSE_REVLOG_MAX_CHAIN_LENGTH = 1000
164 SPARSE_REVLOG_MAX_CHAIN_LENGTH = 1000
@@ -9,6 +9,7 b' from __future__ import absolute_import'
9
9
10 from ..node import sha1nodeconstants
10 from ..node import sha1nodeconstants
11 from .constants import (
11 from .constants import (
12 COMP_MODE_INLINE,
12 INDEX_ENTRY_V0,
13 INDEX_ENTRY_V0,
13 )
14 )
14 from ..i18n import _
15 from ..i18n import _
@@ -42,7 +43,19 b' def offset_type(offset, type):'
42
43
43 class revlogoldindex(list):
44 class revlogoldindex(list):
44 entry_size = INDEX_ENTRY_V0.size
45 entry_size = INDEX_ENTRY_V0.size
45 null_item = (0, 0, 0, -1, -1, -1, -1, sha1nodeconstants.nullid, 0, 0)
46 null_item = (
47 0,
48 0,
49 0,
50 -1,
51 -1,
52 -1,
53 -1,
54 sha1nodeconstants.nullid,
55 0,
56 0,
57 COMP_MODE_INLINE,
58 )
46
59
47 @property
60 @property
48 def nodemap(self):
61 def nodemap(self):
@@ -138,6 +151,7 b' def parse_index_v0(data, inline):'
138 e[6],
151 e[6],
139 0, # no side data support
152 0, # no side data support
140 0, # no side data support
153 0, # no side data support
154 COMP_MODE_INLINE,
141 )
155 )
142 index.append(e2)
156 index.append(e2)
143 nodemap[e[6]] = n
157 nodemap[e[6]] = n
@@ -31,6 +31,10 b' from . import ('
31 vfs as vfsmod,
31 vfs as vfsmod,
32 )
32 )
33
33
34 from .revlogutils import (
35 constants as revlog_constants,
36 )
37
34
38
35 class unionrevlog(revlog.revlog):
39 class unionrevlog(revlog.revlog):
36 def __init__(self, opener, radix, revlog2, linkmapper):
40 def __init__(self, opener, radix, revlog2, linkmapper):
@@ -65,6 +69,7 b' class unionrevlog(revlog.revlog):'
65 node,
69 node,
66 _sdo,
70 _sdo,
67 _sds,
71 _sds,
72 _dcm,
68 ) = rev
73 ) = rev
69 flags = _start & 0xFFFF
74 flags = _start & 0xFFFF
70
75
@@ -99,6 +104,7 b' class unionrevlog(revlog.revlog):'
99 node,
104 node,
100 0, # sidedata offset
105 0, # sidedata offset
101 0, # sidedata size
106 0, # sidedata size
107 revlog_constants.COMP_MODE_INLINE,
102 )
108 )
103 self.index.append(e)
109 self.index.append(e)
104 self.bundlerevs.add(n)
110 self.bundlerevs.add(n)
@@ -21,6 +21,9 b' from mercurial import ('
21 policy,
21 policy,
22 pycompat,
22 pycompat,
23 )
23 )
24 from mercurial.revlogutils import (
25 constants,
26 )
24
27
25 parsers = policy.importmod('parsers')
28 parsers = policy.importmod('parsers')
26
29
@@ -49,7 +52,7 b' def py_parseindex(data, inline):'
49 cache = (0, data)
52 cache = (0, data)
50 while off <= l:
53 while off <= l:
51 e = struct.unpack(indexformatng, data[off : off + s])
54 e = struct.unpack(indexformatng, data[off : off + s])
52 e = e + (0, 0)
55 e = e + (0, 0, constants.COMP_MODE_INLINE)
53 nodemap[e[7]] = n
56 nodemap[e[7]] = n
54 append(e)
57 append(e)
55 n += 1
58 n += 1
@@ -59,7 +62,7 b' def py_parseindex(data, inline):'
59 else:
62 else:
60 while off <= l:
63 while off <= l:
61 e = struct.unpack(indexformatng, data[off : off + s])
64 e = struct.unpack(indexformatng, data[off : off + s])
62 e = e + (0, 0)
65 e = e + (0, 0, constants.COMP_MODE_INLINE)
63 nodemap[e[7]] = n
66 nodemap[e[7]] = n
64 append(e)
67 append(e)
65 n += 1
68 n += 1
@@ -242,7 +245,19 b' class parseindex2tests(unittest.TestCase'
242 break
245 break
243
246
244 def testminusone(self):
247 def testminusone(self):
245 want = (0, 0, 0, -1, -1, -1, -1, sha1nodeconstants.nullid, 0, 0)
248 want = (
249 0,
250 0,
251 0,
252 -1,
253 -1,
254 -1,
255 -1,
256 sha1nodeconstants.nullid,
257 0,
258 0,
259 constants.COMP_MODE_INLINE,
260 )
246 index, junk = parsers.parse_index2(data_inlined, True)
261 index, junk = parsers.parse_index2(data_inlined, True)
247 got = index[-1]
262 got = index[-1]
248 self.assertEqual(want, got) # inline data
263 self.assertEqual(want, got) # inline data
@@ -264,7 +279,20 b' class parseindex2tests(unittest.TestCase'
264 # node won't matter for this test, let's just make sure
279 # node won't matter for this test, let's just make sure
265 # they don't collide. Other data don't matter either.
280 # they don't collide. Other data don't matter either.
266 node = hexrev(p1) + hexrev(p2) + b'.' * 12
281 node = hexrev(p1) + hexrev(p2) + b'.' * 12
267 index.append((0, 0, 12, 1, 34, p1, p2, node, 0, 0))
282 e = (
283 0,
284 0,
285 12,
286 1,
287 34,
288 p1,
289 p2,
290 node,
291 0,
292 0,
293 constants.COMP_MODE_INLINE,
294 )
295 index.append(e)
268
296
269 appendrev(4)
297 appendrev(4)
270 appendrev(5)
298 appendrev(5)
General Comments 0
You need to be logged in to leave comments. Login now