##// END OF EJS Templates
revlog: implement a "default compression" mode...
marmoute -
r48029:ff9fd710 default
parent child Browse files
Show More
@@ -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_DEFAULT,
38 COMP_MODE_INLINE,
39 COMP_MODE_INLINE,
39 COMP_MODE_PLAIN,
40 COMP_MODE_PLAIN,
40 FEATURES_BY_VERSION,
41 FEATURES_BY_VERSION,
@@ -708,6 +709,15 b' class revlog(object):'
708 engine = util.compengines[self._compengine]
709 engine = util.compengines[self._compengine]
709 return engine.revlogcompressor(self._compengineopts)
710 return engine.revlogcompressor(self._compengineopts)
710
711
712 @util.propertycache
713 def _decompressor(self):
714 """the default decompressor"""
715 if self._docket is None:
716 return None
717 t = self._docket.default_compression_header
718 c = self._get_decompressor(t)
719 return c.decompress
720
711 def _indexfp(self):
721 def _indexfp(self):
712 """file object for the revlog's index file"""
722 """file object for the revlog's index file"""
713 return self.opener(self._indexfile, mode=b"r")
723 return self.opener(self._indexfile, mode=b"r")
@@ -1776,6 +1786,8 b' class revlog(object):'
1776 data = self._getsegmentforrevs(rev, rev, df=df)[1]
1786 data = self._getsegmentforrevs(rev, rev, df=df)[1]
1777 if compression_mode == COMP_MODE_PLAIN:
1787 if compression_mode == COMP_MODE_PLAIN:
1778 return data
1788 return data
1789 elif compression_mode == COMP_MODE_DEFAULT:
1790 return self._decompressor(data)
1779 elif compression_mode == COMP_MODE_INLINE:
1791 elif compression_mode == COMP_MODE_INLINE:
1780 return self.decompress(data)
1792 return self.decompress(data)
1781 else:
1793 else:
@@ -1829,6 +1841,8 b' class revlog(object):'
1829 return [self._chunk(rev, df=df) for rev in revschunk]
1841 return [self._chunk(rev, df=df) for rev in revschunk]
1830
1842
1831 decomp = self.decompress
1843 decomp = self.decompress
1844 # self._decompressor might be None, but will not be used in that case
1845 def_decomp = self._decompressor
1832 for rev in revschunk:
1846 for rev in revschunk:
1833 chunkstart = start(rev)
1847 chunkstart = start(rev)
1834 if inline:
1848 if inline:
@@ -1840,6 +1854,8 b' class revlog(object):'
1840 ladd(c)
1854 ladd(c)
1841 elif comp_mode == COMP_MODE_INLINE:
1855 elif comp_mode == COMP_MODE_INLINE:
1842 ladd(decomp(c))
1856 ladd(decomp(c))
1857 elif comp_mode == COMP_MODE_DEFAULT:
1858 ladd(def_decomp(c))
1843 else:
1859 else:
1844 msg = 'unknown compression mode %d'
1860 msg = 'unknown compression mode %d'
1845 msg %= comp_mode
1861 msg %= comp_mode
@@ -2489,8 +2505,12 b' class revlog(object):'
2489 if not h and not d:
2505 if not h and not d:
2490 # not data to store at all... declare them uncompressed
2506 # not data to store at all... declare them uncompressed
2491 compression_mode = COMP_MODE_PLAIN
2507 compression_mode = COMP_MODE_PLAIN
2492 elif not h and d[0:1] == b'\0':
2508 elif not h:
2493 compression_mode = COMP_MODE_PLAIN
2509 t = d[0:1]
2510 if t == b'\0':
2511 compression_mode = COMP_MODE_PLAIN
2512 elif t == self._docket.default_compression_header:
2513 compression_mode = COMP_MODE_DEFAULT
2494 elif h == b'u':
2514 elif h == b'u':
2495 # we have a more efficient way to declare uncompressed
2515 # we have a more efficient way to declare uncompressed
2496 h = b''
2516 h = b''
@@ -123,6 +123,16 b' REVIDX_RAWTEXT_CHANGING_FLAGS = REVIDX_I'
123 # chunk value. Without any header information prefixed.
123 # chunk value. Without any header information prefixed.
124 COMP_MODE_PLAIN = 0
124 COMP_MODE_PLAIN = 0
125
125
126 # Chunk use the "default compression" for the revlog (usually defined in the
127 # revlog docket). A header is still used.
128 #
129 # XXX: keeping a header is probably not useful and we should probably drop it.
130 #
131 # XXX: The value of allow mixed type of compression in the revlog is unclear
132 # and we should consider making PLAIN/DEFAULT the only available mode for
133 # revlog v2, disallowing INLINE mode.
134 COMP_MODE_DEFAULT = 1
135
126 # Chunk use a compression mode stored "inline" at the start of the chunk
136 # Chunk use a compression mode stored "inline" at the start of the chunk
127 # itself. This is the mode always used for revlog version "0" and "1"
137 # itself. This is the mode always used for revlog version "0" and "1"
128 COMP_MODE_INLINE = 2
138 COMP_MODE_INLINE = 2
@@ -21,6 +21,7 b' import struct'
21
21
22 from .. import (
22 from .. import (
23 error,
23 error,
24 util,
24 )
25 )
25
26
26 from . import (
27 from . import (
@@ -36,7 +37,8 b' from . import ('
36 # * 8 bytes: pending size of index-data
37 # * 8 bytes: pending size of index-data
37 # * 8 bytes: size of data
38 # * 8 bytes: size of data
38 # * 8 bytes: pending size of data
39 # * 8 bytes: pending size of data
39 S_HEADER = struct.Struct(constants.INDEX_HEADER.format + 'LLLL')
40 # * 1 bytes: default compression header
41 S_HEADER = struct.Struct(constants.INDEX_HEADER.format + 'LLLLc')
40
42
41
43
42 class RevlogDocket(object):
44 class RevlogDocket(object):
@@ -51,6 +53,7 b' class RevlogDocket(object):'
51 pending_index_end=0,
53 pending_index_end=0,
52 data_end=0,
54 data_end=0,
53 pending_data_end=0,
55 pending_data_end=0,
56 default_compression_header=None,
54 ):
57 ):
55 self._version_header = version_header
58 self._version_header = version_header
56 self._read_only = bool(use_pending)
59 self._read_only = bool(use_pending)
@@ -71,6 +74,7 b' class RevlogDocket(object):'
71 else:
74 else:
72 self._index_end = self._initial_index_end
75 self._index_end = self._initial_index_end
73 self._data_end = self._initial_data_end
76 self._data_end = self._initial_data_end
77 self.default_compression_header = default_compression_header
74
78
75 def index_filepath(self):
79 def index_filepath(self):
76 """file path to the current index file associated to this docket"""
80 """file path to the current index file associated to this docket"""
@@ -134,6 +138,7 b' class RevlogDocket(object):'
134 self._index_end,
138 self._index_end,
135 official_data_end,
139 official_data_end,
136 self._data_end,
140 self._data_end,
141 self.default_compression_header,
137 )
142 )
138 return S_HEADER.pack(*data)
143 return S_HEADER.pack(*data)
139
144
@@ -142,7 +147,12 b' def default_docket(revlog, version_heade'
142 """given a revlog version a new docket object for the given revlog"""
147 """given a revlog version a new docket object for the given revlog"""
143 if (version_header & 0xFFFF) != constants.REVLOGV2:
148 if (version_header & 0xFFFF) != constants.REVLOGV2:
144 return None
149 return None
145 docket = RevlogDocket(revlog, version_header=version_header)
150 comp = util.compengines[revlog._compengine].revlogheader()
151 docket = RevlogDocket(
152 revlog,
153 version_header=version_header,
154 default_compression_header=comp,
155 )
146 docket._dirty = True
156 docket._dirty = True
147 return docket
157 return docket
148
158
@@ -155,6 +165,7 b' def parse_docket(revlog, data, use_pendi'
155 pending_index_size = header[2]
165 pending_index_size = header[2]
156 data_size = header[3]
166 data_size = header[3]
157 pending_data_size = header[4]
167 pending_data_size = header[4]
168 default_compression_header = header[5]
158 docket = RevlogDocket(
169 docket = RevlogDocket(
159 revlog,
170 revlog,
160 use_pending=use_pending,
171 use_pending=use_pending,
@@ -163,5 +174,6 b' def parse_docket(revlog, data, use_pendi'
163 pending_index_end=pending_index_size,
174 pending_index_end=pending_index_size,
164 data_end=data_size,
175 data_end=data_size,
165 pending_data_end=pending_data_size,
176 pending_data_end=pending_data_size,
177 default_compression_header=default_compression_header,
166 )
178 )
167 return docket
179 return docket
General Comments 0
You need to be logged in to leave comments. Login now