Show More
@@ -3000,6 +3000,8 b' class compressormanager(object):' | |||||
3000 | self._bundlenames = {} |
|
3000 | self._bundlenames = {} | |
3001 | # Internal bundle identifier to engine name. |
|
3001 | # Internal bundle identifier to engine name. | |
3002 | self._bundletypes = {} |
|
3002 | self._bundletypes = {} | |
|
3003 | # Revlog header to engine name. | |||
|
3004 | self._revlogheaders = {} | |||
3003 | # Wire proto identifier to engine name. |
|
3005 | # Wire proto identifier to engine name. | |
3004 | self._wiretypes = {} |
|
3006 | self._wiretypes = {} | |
3005 |
|
3007 | |||
@@ -3053,6 +3055,14 b' class compressormanager(object):' | |||||
3053 |
|
3055 | |||
3054 | self._wiretypes[wiretype] = name |
|
3056 | self._wiretypes[wiretype] = name | |
3055 |
|
3057 | |||
|
3058 | revlogheader = engine.revlogheader() | |||
|
3059 | if revlogheader and revlogheader in self._revlogheaders: | |||
|
3060 | raise error.Abort(_('revlog header %s already registered by %s') % | |||
|
3061 | (revlogheader, self._revlogheaders[revlogheader])) | |||
|
3062 | ||||
|
3063 | if revlogheader: | |||
|
3064 | self._revlogheaders[revlogheader] = name | |||
|
3065 | ||||
3056 | self._engines[name] = engine |
|
3066 | self._engines[name] = engine | |
3057 |
|
3067 | |||
3058 | @property |
|
3068 | @property | |
@@ -3121,6 +3131,13 b' class compressormanager(object):' | |||||
3121 | engine.name()) |
|
3131 | engine.name()) | |
3122 | return engine |
|
3132 | return engine | |
3123 |
|
3133 | |||
|
3134 | def forrevlogheader(self, header): | |||
|
3135 | """Obtain a compression engine registered to a revlog header. | |||
|
3136 | ||||
|
3137 | Will raise KeyError if the revlog header value isn't registered. | |||
|
3138 | """ | |||
|
3139 | return self._engines[self._revlogheaders[header]] | |||
|
3140 | ||||
3124 | compengines = compressormanager() |
|
3141 | compengines = compressormanager() | |
3125 |
|
3142 | |||
3126 | class compressionengine(object): |
|
3143 | class compressionengine(object): | |
@@ -3186,6 +3203,16 b' class compressionengine(object):' | |||||
3186 | """ |
|
3203 | """ | |
3187 | return None |
|
3204 | return None | |
3188 |
|
3205 | |||
|
3206 | def revlogheader(self): | |||
|
3207 | """Header added to revlog chunks that identifies this engine. | |||
|
3208 | ||||
|
3209 | If this engine can be used to compress revlogs, this method should | |||
|
3210 | return the bytes used to identify chunks compressed with this engine. | |||
|
3211 | Else, the method should return ``None`` to indicate it does not | |||
|
3212 | participate in revlog compression. | |||
|
3213 | """ | |||
|
3214 | return None | |||
|
3215 | ||||
3189 | def compressstream(self, it, opts=None): |
|
3216 | def compressstream(self, it, opts=None): | |
3190 | """Compress an iterator of chunks. |
|
3217 | """Compress an iterator of chunks. | |
3191 |
|
3218 | |||
@@ -3215,6 +3242,13 b' class compressionengine(object):' | |||||
3215 | the data could not be compressed (too small, not compressible, etc). |
|
3242 | the data could not be compressed (too small, not compressible, etc). | |
3216 | The returned data should have a header uniquely identifying this |
|
3243 | The returned data should have a header uniquely identifying this | |
3217 | compression format so decompression can be routed to this engine. |
|
3244 | compression format so decompression can be routed to this engine. | |
|
3245 | This header should be identified by the ``revlogheader()`` return | |||
|
3246 | value. | |||
|
3247 | ||||
|
3248 | The object has a ``decompress(data)`` method that decompresses | |||
|
3249 | data. The method will only be called if ``data`` begins with | |||
|
3250 | ``revlogheader()``. The method should return the raw, uncompressed | |||
|
3251 | data or raise a ``RevlogError``. | |||
3218 |
|
3252 | |||
3219 | The object is reusable but is not thread safe. |
|
3253 | The object is reusable but is not thread safe. | |
3220 | """ |
|
3254 | """ | |
@@ -3230,6 +3264,9 b' class _zlibengine(compressionengine):' | |||||
3230 | def wireprotosupport(self): |
|
3264 | def wireprotosupport(self): | |
3231 | return compewireprotosupport('zlib', 20, 20) |
|
3265 | return compewireprotosupport('zlib', 20, 20) | |
3232 |
|
3266 | |||
|
3267 | def revlogheader(self): | |||
|
3268 | return 'x' | |||
|
3269 | ||||
3233 | def compressstream(self, it, opts=None): |
|
3270 | def compressstream(self, it, opts=None): | |
3234 | opts = opts or {} |
|
3271 | opts = opts or {} | |
3235 |
|
3272 | |||
@@ -3286,6 +3323,13 b' class _zlibengine(compressionengine):' | |||||
3286 | return ''.join(parts) |
|
3323 | return ''.join(parts) | |
3287 | return None |
|
3324 | return None | |
3288 |
|
3325 | |||
|
3326 | def decompress(self, data): | |||
|
3327 | try: | |||
|
3328 | return zlib.decompress(data) | |||
|
3329 | except zlib.error as e: | |||
|
3330 | raise error.RevlogError(_('revlog decompress error: %s') % | |||
|
3331 | str(e)) | |||
|
3332 | ||||
3289 | def revlogcompressor(self, opts=None): |
|
3333 | def revlogcompressor(self, opts=None): | |
3290 | return self.zlibrevlogcompressor() |
|
3334 | return self.zlibrevlogcompressor() | |
3291 |
|
3335 | |||
@@ -3357,6 +3401,9 b' class _noopengine(compressionengine):' | |||||
3357 | def wireprotosupport(self): |
|
3401 | def wireprotosupport(self): | |
3358 | return compewireprotosupport('none', 0, 10) |
|
3402 | return compewireprotosupport('none', 0, 10) | |
3359 |
|
3403 | |||
|
3404 | # We don't implement revlogheader because it is handled specially | |||
|
3405 | # in the revlog class. | |||
|
3406 | ||||
3360 | def compressstream(self, it, opts=None): |
|
3407 | def compressstream(self, it, opts=None): | |
3361 | return it |
|
3408 | return it | |
3362 |
|
3409 | |||
@@ -3397,6 +3444,9 b' class _zstdengine(compressionengine):' | |||||
3397 | def wireprotosupport(self): |
|
3444 | def wireprotosupport(self): | |
3398 | return compewireprotosupport('zstd', 50, 50) |
|
3445 | return compewireprotosupport('zstd', 50, 50) | |
3399 |
|
3446 | |||
|
3447 | def revlogheader(self): | |||
|
3448 | return '\x28' | |||
|
3449 | ||||
3400 | def compressstream(self, it, opts=None): |
|
3450 | def compressstream(self, it, opts=None): | |
3401 | opts = opts or {} |
|
3451 | opts = opts or {} | |
3402 | # zstd level 3 is almost always significantly faster than zlib |
|
3452 | # zstd level 3 is almost always significantly faster than zlib | |
@@ -3425,7 +3475,9 b' class _zstdengine(compressionengine):' | |||||
3425 | # pre-allocate a buffer to hold the result. |
|
3475 | # pre-allocate a buffer to hold the result. | |
3426 | self._cctx = zstd.ZstdCompressor(level=level, |
|
3476 | self._cctx = zstd.ZstdCompressor(level=level, | |
3427 | write_content_size=True) |
|
3477 | write_content_size=True) | |
|
3478 | self._dctx = zstd.ZstdDecompressor() | |||
3428 | self._compinsize = zstd.COMPRESSION_RECOMMENDED_INPUT_SIZE |
|
3479 | self._compinsize = zstd.COMPRESSION_RECOMMENDED_INPUT_SIZE | |
|
3480 | self._decompinsize = zstd.DECOMPRESSION_RECOMMENDED_INPUT_SIZE | |||
3429 |
|
3481 | |||
3430 | def compress(self, data): |
|
3482 | def compress(self, data): | |
3431 | insize = len(data) |
|
3483 | insize = len(data) | |
@@ -3456,6 +3508,28 b' class _zstdengine(compressionengine):' | |||||
3456 | return ''.join(chunks) |
|
3508 | return ''.join(chunks) | |
3457 | return None |
|
3509 | return None | |
3458 |
|
3510 | |||
|
3511 | def decompress(self, data): | |||
|
3512 | insize = len(data) | |||
|
3513 | ||||
|
3514 | try: | |||
|
3515 | # This was measured to be faster than other streaming | |||
|
3516 | # decompressors. | |||
|
3517 | dobj = self._dctx.decompressobj() | |||
|
3518 | chunks = [] | |||
|
3519 | pos = 0 | |||
|
3520 | while pos < insize: | |||
|
3521 | pos2 = pos + self._decompinsize | |||
|
3522 | chunk = dobj.decompress(data[pos:pos2]) | |||
|
3523 | if chunk: | |||
|
3524 | chunks.append(chunk) | |||
|
3525 | pos = pos2 | |||
|
3526 | # Frame should be exhausted, so no finish() API. | |||
|
3527 | ||||
|
3528 | return ''.join(chunks) | |||
|
3529 | except Exception as e: | |||
|
3530 | raise error.RevlogError(_('revlog decompress error: %s') % | |||
|
3531 | str(e)) | |||
|
3532 | ||||
3459 | def revlogcompressor(self, opts=None): |
|
3533 | def revlogcompressor(self, opts=None): | |
3460 | opts = opts or {} |
|
3534 | opts = opts or {} | |
3461 | return self.zstdrevlogcompressor(self._module, |
|
3535 | return self.zstdrevlogcompressor(self._module, |
General Comments 0
You need to be logged in to leave comments.
Login now