deprecate the numeric --compression argument, rename null compression to none, update CHANGES

This commit is contained in:
Thomas Waldmann 2015-08-14 23:00:04 +02:00
parent b16dc03e36
commit a6b6712d6a
7 changed files with 54 additions and 37 deletions

View File

@ -1,6 +1,38 @@
Borg Changelog Borg Changelog
============== ==============
Compression branch
------------------
Compatibility notes:
- the new compression code is very compatible: as long as you stay with zlib
compression, older borg releases will still be able to read data from a
repo/archive made with the new code (note: this is not the case for the
default "none" compression, use "zlib,0" if you want a "no compression" mode
that can be read by older borg). Also the new code is able to read repos and
archives made with older borg versions (for all zlib levels 0..9).
Deprecations:
- --compression N (with N being a number, as in 0.24) is deprecated.
We keep the --compression 0..9 for now to not break scripts, but it is
deprecated and will be removed later, so better fix your scripts now:
--compression 0 (as in 0.24) is the same as --compression zlib,0 (now).
BUT: if you do not want compression, you rather want --compression none
(which is the default).
--compression 1 (in 0.24) is the same as --compression zlib,1 (now)
--compression 9 (in 0.24) is the same as --compression zlib,9 (now)
New features:
- create --compression none (default, means: do not compress, just pass through
data "as is". this is more efficient than zlib level 0 as used in borg 0.24)
- create --compression lz4 (super-fast, but not very high compression)
Please note that borgbackup needs lz4 library as additional requirement.
- create --compression zlib,N (slower, higher compression, default for N is 6)
- create --compression lzma,N (slowest, highest compression, default N is 6)
Version 0.24.0 Version 0.24.0
-------------- --------------

View File

@ -668,17 +668,13 @@ def run(self, args=None):
metavar='CHUNK_MIN_EXP,CHUNK_MAX_EXP,HASH_MASK_BITS,HASH_WINDOW_SIZE', metavar='CHUNK_MIN_EXP,CHUNK_MAX_EXP,HASH_MASK_BITS,HASH_WINDOW_SIZE',
help='specify the chunker parameters. default: %d,%d,%d,%d' % CHUNKER_PARAMS) help='specify the chunker parameters. default: %d,%d,%d,%d' % CHUNKER_PARAMS)
subparser.add_argument('-C', '--compression', dest='compression', subparser.add_argument('-C', '--compression', dest='compression',
type=CompressionSpec, default=dict(name='null'), metavar='COMPRESSION', type=CompressionSpec, default=dict(name='none'), metavar='COMPRESSION',
help='select compression algorithm and level, by giving a number: ' help='select compression algorithm (and level): '
'0 == no compression [default], ' 'none == no compression (default), '
'1..9 == zlib level 1..9, ' 'lz4 == lz4, '
'10 == lz4, '
'20-29 == lzma level 0..9.'
'Alternatively, you can also give a name and optionally additional args: '
'null == no compression, '
'zlib == zlib (default level 6), ' 'zlib == zlib (default level 6), '
'zlib,0 .. zlib,9 == zlib (with level 0..9), ' 'zlib,0 .. zlib,9 == zlib (with level 0..9), '
'lz4 == lz4, ' 'lzma == lzma (default level 6), '
'lzma,0 .. lzma,9 == lzma (with level 0..9).') 'lzma,0 .. lzma,9 == lzma (with level 0..9).')
subparser.add_argument('archive', metavar='ARCHIVE', subparser.add_argument('archive', metavar='ARCHIVE',
type=location_validator(archive=True), type=location_validator(archive=True),

View File

@ -35,12 +35,12 @@ cdef class CompressorBase:
return data[2:] return data[2:]
class CNULL(CompressorBase): class CNONE(CompressorBase):
""" """
null compression, just pass through data none - no compression, just pass through data
""" """
ID = b'\x00\x00' ID = b'\x00\x00'
name = 'null' name = 'none'
def compress(self, data): def compress(self, data):
return super().compress(data) return super().compress(data)
@ -161,12 +161,12 @@ class ZLIB(CompressorBase):
COMPRESSOR_TABLE = { COMPRESSOR_TABLE = {
CNULL.name: CNULL, CNONE.name: CNONE,
LZ4.name: LZ4, LZ4.name: LZ4,
ZLIB.name: ZLIB, ZLIB.name: ZLIB,
LZMA.name: LZMA, LZMA.name: LZMA,
} }
COMPRESSOR_LIST = [LZ4, CNULL, ZLIB, LZMA, ] # check fast stuff first COMPRESSOR_LIST = [LZ4, CNONE, ZLIB, LZMA, ] # check fast stuff first
def get_compressor(name, **kwargs): def get_compressor(name, **kwargs):
cls = COMPRESSOR_TABLE[name] cls = COMPRESSOR_TABLE[name]

View File

@ -295,20 +295,14 @@ def CompressionSpec(s):
compression = int(compression) compression = int(compression)
if count > 1: if count > 1:
raise ValueError raise ValueError
# it is just --compression N # DEPRECATED: it is just --compression N
if compression == 0: if 0 <= compression <= 9:
return dict(name='null')
if 1 <= compression <= 9:
return dict(name='zlib', level=compression) return dict(name='zlib', level=compression)
if compression == 10:
return dict(name='lz4')
if 20 <= compression <= 29:
return dict(name='lzma', level=compression-20)
raise ValueError raise ValueError
except ValueError: except ValueError:
# --compression algo[,...] # --compression algo[,...]
name = compression name = compression
if name in ('null', 'lz4', ): if name in ('none', 'lz4', ):
return dict(name=name) return dict(name=name)
if name in ('zlib', 'lzma', ): if name in ('zlib', 'lzma', ):
if count < 2: if count < 2:

View File

@ -68,7 +68,7 @@ def __init__(self, repository):
self.TYPE_STR = bytes([self.TYPE]) self.TYPE_STR = bytes([self.TYPE])
self.repository = repository self.repository = repository
self.target = None # key location file path / repo obj self.target = None # key location file path / repo obj
self.compressor = Compressor('null', buffer=COMPR_BUFFER) self.compressor = Compressor('none', buffer=COMPR_BUFFER)
def id_hash(self, data): def id_hash(self, data):
"""Return HMAC hash using the "id" HMAC key """Return HMAC hash using the "id" HMAC key

View File

@ -6,7 +6,7 @@
import pytest import pytest
from ..compress import get_compressor, Compressor, CNULL, ZLIB, LZ4 from ..compress import get_compressor, Compressor, CNONE, ZLIB, LZ4
buffer = bytes(2**16) buffer = bytes(2**16)
@ -15,8 +15,8 @@
def test_get_compressor(): def test_get_compressor():
c = get_compressor(name='null') c = get_compressor(name='none')
assert isinstance(c, CNULL) assert isinstance(c, CNONE)
c = get_compressor(name='lz4', buffer=buffer) c = get_compressor(name='lz4', buffer=buffer)
assert isinstance(c, LZ4) assert isinstance(c, LZ4)
c = get_compressor(name='zlib') c = get_compressor(name='zlib')
@ -26,7 +26,7 @@ def test_get_compressor():
def test_cnull(): def test_cnull():
c = get_compressor(name='null') c = get_compressor(name='none')
cdata = c.compress(data) cdata = c.compress(data)
assert len(cdata) > len(data) assert len(cdata) > len(data)
assert data in cdata # it's not compressed and just in there 1:1 assert data in cdata # it's not compressed and just in there 1:1
@ -83,7 +83,7 @@ def test_zlib_compat():
def test_compressor(): def test_compressor():
params_list = [ params_list = [
dict(name='null', buffer=buffer), dict(name='none', buffer=buffer),
dict(name='lz4', buffer=buffer), dict(name='lz4', buffer=buffer),
dict(name='zlib', level=0, buffer=buffer), dict(name='zlib', level=0, buffer=buffer),
dict(name='zlib', level=6, buffer=buffer), dict(name='zlib', level=6, buffer=buffer),

View File

@ -108,17 +108,12 @@ def test(self):
def test_compression_specs(): def test_compression_specs():
with pytest.raises(ValueError): with pytest.raises(ValueError):
CompressionSpec('') CompressionSpec('')
assert CompressionSpec('0') == dict(name='null') assert CompressionSpec('0') == dict(name='zlib', level=0)
assert CompressionSpec('1') == dict(name='zlib', level=1) assert CompressionSpec('1') == dict(name='zlib', level=1)
assert CompressionSpec('9') == dict(name='zlib', level=9) assert CompressionSpec('9') == dict(name='zlib', level=9)
assert CompressionSpec('10') == dict(name='lz4')
with pytest.raises(ValueError): with pytest.raises(ValueError):
CompressionSpec('11') CompressionSpec('10')
assert CompressionSpec('20') == dict(name='lzma', level=0) assert CompressionSpec('none') == dict(name='none')
assert CompressionSpec('29') == dict(name='lzma', level=9)
with pytest.raises(ValueError):
CompressionSpec('30')
assert CompressionSpec('null') == dict(name='null')
assert CompressionSpec('lz4') == dict(name='lz4') assert CompressionSpec('lz4') == dict(name='lz4')
assert CompressionSpec('zlib') == dict(name='zlib', level=6) assert CompressionSpec('zlib') == dict(name='zlib', level=6)
assert CompressionSpec('zlib,0') == dict(name='zlib', level=0) assert CompressionSpec('zlib,0') == dict(name='zlib', level=0)