|
@@ -91,8 +91,8 @@ class HashIndexTestCase(BaseTestCase):
|
|
|
'85f72b036c692c8266e4f51ccf0cff2147204282b5e316ae508d30a448d88fef')
|
|
|
|
|
|
def test_chunkindex(self):
|
|
|
- self._generic_test(ChunkIndex, lambda x: (x, x, x),
|
|
|
- 'c83fdf33755fc37879285f2ecfc5d1f63b97577494902126b6fb6f3e4d852488')
|
|
|
+ self._generic_test(ChunkIndex, lambda x: (x, x),
|
|
|
+ '85f72b036c692c8266e4f51ccf0cff2147204282b5e316ae508d30a448d88fef')
|
|
|
|
|
|
def test_resize(self):
|
|
|
n = 2000 # Must be >= MIN_BUCKETS
|
|
@@ -126,26 +126,26 @@ class HashIndexTestCase(BaseTestCase):
|
|
|
|
|
|
def test_chunkindex_merge(self):
|
|
|
idx1 = ChunkIndex()
|
|
|
- idx1[H(1)] = 1, 100, 100
|
|
|
- idx1[H(2)] = 2, 200, 200
|
|
|
- idx1[H(3)] = 3, 300, 300
|
|
|
+ idx1[H(1)] = 1, 100
|
|
|
+ idx1[H(2)] = 2, 200
|
|
|
+ idx1[H(3)] = 3, 300
|
|
|
# no H(4) entry
|
|
|
idx2 = ChunkIndex()
|
|
|
- idx2[H(1)] = 4, 100, 100
|
|
|
- idx2[H(2)] = 5, 200, 200
|
|
|
+ idx2[H(1)] = 4, 100
|
|
|
+ idx2[H(2)] = 5, 200
|
|
|
# no H(3) entry
|
|
|
- idx2[H(4)] = 6, 400, 400
|
|
|
+ idx2[H(4)] = 6, 400
|
|
|
idx1.merge(idx2)
|
|
|
- assert idx1[H(1)] == (5, 100, 100)
|
|
|
- assert idx1[H(2)] == (7, 200, 200)
|
|
|
- assert idx1[H(3)] == (3, 300, 300)
|
|
|
- assert idx1[H(4)] == (6, 400, 400)
|
|
|
+ assert idx1[H(1)] == (5, 100)
|
|
|
+ assert idx1[H(2)] == (7, 200)
|
|
|
+ assert idx1[H(3)] == (3, 300)
|
|
|
+ assert idx1[H(4)] == (6, 400)
|
|
|
|
|
|
def test_chunkindex_summarize(self):
|
|
|
idx = ChunkIndex()
|
|
|
- idx[H(1)] = 1, 1000, 100
|
|
|
- idx[H(2)] = 2, 2000, 200
|
|
|
- idx[H(3)] = 3, 3000, 300
|
|
|
+ idx[H(1)] = 1, 1000
|
|
|
+ idx[H(2)] = 2, 2000
|
|
|
+ idx[H(3)] = 3, 3000
|
|
|
|
|
|
size, unique_size, unique_chunks, chunks = idx.summarize()
|
|
|
assert size == 1000 + 2 * 2000 + 3 * 3000
|
|
@@ -167,14 +167,14 @@ class HashIndexExtraTestCase(BaseTestCase):
|
|
|
keys, to_delete_keys = all_keys[0:(2*key_count//3)], all_keys[(2*key_count//3):]
|
|
|
|
|
|
for i, key in enumerate(keys):
|
|
|
- index[key] = (i, i, i)
|
|
|
+ index[key] = (i, i)
|
|
|
for i, key in enumerate(to_delete_keys):
|
|
|
- index[key] = (i, i, i)
|
|
|
+ index[key] = (i, i)
|
|
|
|
|
|
for key in to_delete_keys:
|
|
|
del index[key]
|
|
|
for i, key in enumerate(keys):
|
|
|
- assert index[key] == (i, i, i)
|
|
|
+ assert index[key] == (i, i)
|
|
|
for key in to_delete_keys:
|
|
|
assert index.get(key) is None
|
|
|
|
|
@@ -188,12 +188,12 @@ class HashIndexExtraTestCase(BaseTestCase):
|
|
|
class HashIndexSizeTestCase(BaseTestCase):
|
|
|
def test_size_on_disk(self):
|
|
|
idx = ChunkIndex()
|
|
|
- assert idx.size() == 18 + 1031 * (32 + 3 * 4)
|
|
|
+ assert idx.size() == 18 + 1031 * (32 + 2 * 4)
|
|
|
|
|
|
def test_size_on_disk_accurate(self):
|
|
|
idx = ChunkIndex()
|
|
|
for i in range(1234):
|
|
|
- idx[H(i)] = i, i**2, i**3
|
|
|
+ idx[H(i)] = i, i**2
|
|
|
with tempfile.NamedTemporaryFile() as file:
|
|
|
idx.write(file.name)
|
|
|
size = os.path.getsize(file.name)
|
|
@@ -203,7 +203,7 @@ class HashIndexSizeTestCase(BaseTestCase):
|
|
|
class HashIndexRefcountingTestCase(BaseTestCase):
|
|
|
def test_chunkindex_limit(self):
|
|
|
idx = ChunkIndex()
|
|
|
- idx[H(1)] = ChunkIndex.MAX_VALUE - 1, 1, 2
|
|
|
+ idx[H(1)] = ChunkIndex.MAX_VALUE - 1, 1
|
|
|
|
|
|
# 5 is arbitrary, any number of incref/decrefs shouldn't move it once it's limited
|
|
|
for i in range(5):
|
|
@@ -217,9 +217,9 @@ class HashIndexRefcountingTestCase(BaseTestCase):
|
|
|
def _merge(self, refcounta, refcountb):
|
|
|
def merge(refcount1, refcount2):
|
|
|
idx1 = ChunkIndex()
|
|
|
- idx1[H(1)] = refcount1, 1, 2
|
|
|
+ idx1[H(1)] = refcount1, 1
|
|
|
idx2 = ChunkIndex()
|
|
|
- idx2[H(1)] = refcount2, 1, 2
|
|
|
+ idx2[H(1)] = refcount2, 1
|
|
|
idx1.merge(idx2)
|
|
|
refcount, *_ = idx1[H(1)]
|
|
|
return refcount
|
|
@@ -251,44 +251,44 @@ class HashIndexRefcountingTestCase(BaseTestCase):
|
|
|
|
|
|
def test_chunkindex_add(self):
|
|
|
idx1 = ChunkIndex()
|
|
|
- idx1.add(H(1), 5, 6, 7)
|
|
|
- assert idx1[H(1)] == (5, 6, 7)
|
|
|
- idx1.add(H(1), 1, 2, 3)
|
|
|
- assert idx1[H(1)] == (6, 2, 3)
|
|
|
+ idx1.add(H(1), 5, 6)
|
|
|
+ assert idx1[H(1)] == (5, 6)
|
|
|
+ idx1.add(H(1), 1, 2)
|
|
|
+ assert idx1[H(1)] == (6, 2)
|
|
|
|
|
|
def test_incref_limit(self):
|
|
|
idx1 = ChunkIndex()
|
|
|
- idx1[H(1)] = (ChunkIndex.MAX_VALUE, 6, 7)
|
|
|
+ idx1[H(1)] = ChunkIndex.MAX_VALUE, 6
|
|
|
idx1.incref(H(1))
|
|
|
refcount, *_ = idx1[H(1)]
|
|
|
assert refcount == ChunkIndex.MAX_VALUE
|
|
|
|
|
|
def test_decref_limit(self):
|
|
|
idx1 = ChunkIndex()
|
|
|
- idx1[H(1)] = ChunkIndex.MAX_VALUE, 6, 7
|
|
|
+ idx1[H(1)] = ChunkIndex.MAX_VALUE, 6
|
|
|
idx1.decref(H(1))
|
|
|
refcount, *_ = idx1[H(1)]
|
|
|
assert refcount == ChunkIndex.MAX_VALUE
|
|
|
|
|
|
def test_decref_zero(self):
|
|
|
idx1 = ChunkIndex()
|
|
|
- idx1[H(1)] = 0, 0, 0
|
|
|
+ idx1[H(1)] = 0, 0
|
|
|
with self.assert_raises(AssertionError):
|
|
|
idx1.decref(H(1))
|
|
|
|
|
|
def test_incref_decref(self):
|
|
|
idx1 = ChunkIndex()
|
|
|
- idx1.add(H(1), 5, 6, 7)
|
|
|
- assert idx1[H(1)] == (5, 6, 7)
|
|
|
+ idx1.add(H(1), 5, 6)
|
|
|
+ assert idx1[H(1)] == (5, 6)
|
|
|
idx1.incref(H(1))
|
|
|
- assert idx1[H(1)] == (6, 6, 7)
|
|
|
+ assert idx1[H(1)] == (6, 6)
|
|
|
idx1.decref(H(1))
|
|
|
- assert idx1[H(1)] == (5, 6, 7)
|
|
|
+ assert idx1[H(1)] == (5, 6)
|
|
|
|
|
|
def test_setitem_raises(self):
|
|
|
idx1 = ChunkIndex()
|
|
|
with self.assert_raises(AssertionError):
|
|
|
- idx1[H(1)] = ChunkIndex.MAX_VALUE + 1, 0, 0
|
|
|
+ idx1[H(1)] = ChunkIndex.MAX_VALUE + 1, 0
|
|
|
|
|
|
def test_keyerror(self):
|
|
|
idx = ChunkIndex()
|
|
@@ -299,14 +299,15 @@ class HashIndexRefcountingTestCase(BaseTestCase):
|
|
|
with self.assert_raises(KeyError):
|
|
|
idx[H(1)]
|
|
|
with self.assert_raises(OverflowError):
|
|
|
- idx.add(H(1), -1, 0, 0)
|
|
|
+ idx.add(H(1), -1, 0)
|
|
|
|
|
|
|
|
|
class HashIndexDataTestCase(BaseTestCase):
|
|
|
- # This bytestring was created with 1.0-maint at c2f9533
|
|
|
- HASHINDEX = b'eJzt0L0NgmAUhtHLT0LDEI6AuAEhMVYmVnSuYefC7AB3Aj9KNedJbnfyFne6P67P27w0EdG1Eac+Cm1ZybAsy7Isy7Isy7Isy7I' \
|
|
|
- b'sy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7Isy7LsL9nhc+cqTZ' \
|
|
|
- b'3XlO2Ys++Du5fX+l1/YFmWZVmWZVmWZVmWZVmWZVmWZVmWZVmWZVmWZVmWZVmWZVmWZVmWZVmWZVmWZVmWZVn2/+0O2rYccw=='
|
|
|
+ # This bytestring was created with borg2-pre 2022-06-10
|
|
|
+ HASHINDEX = b'eJzt0LEJg1AYhdE/JqBjOEJMNhBBrAQrO9ewc+HsoG+CPMsEz1cfbnHbceqXoZvvEVE+IuoqMu2pnOE4' \
|
|
|
+ b'juM4juM4juM4juM4juM4juM4juM4juM4juM4juM4juM4juM4juM4juM4juM4juM4juM4juM4juM4juM4' \
|
|
|
+ b'juM4juM4juM4jruie36vuSVT5N0rzW0n9t7r5z9+4TiO4ziO4ziO4ziO4ziO4ziO4ziO4ziO4ziO4ziO' \
|
|
|
+ b'4ziO4ziO4ziO4ziO4ziO437LHbSVHGw='
|
|
|
|
|
|
def _serialize_hashindex(self, idx):
|
|
|
with tempfile.TemporaryDirectory() as tempdir:
|
|
@@ -330,23 +331,23 @@ class HashIndexDataTestCase(BaseTestCase):
|
|
|
|
|
|
def test_identical_creation(self):
|
|
|
idx1 = ChunkIndex()
|
|
|
- idx1[H(1)] = 1, 2, 3
|
|
|
- idx1[H(2)] = 2**31 - 1, 0, 0
|
|
|
- idx1[H(3)] = 4294962296, 0, 0 # 4294962296 is -5000 interpreted as an uint32_t
|
|
|
+ idx1[H(1)] = 1, 2
|
|
|
+ idx1[H(2)] = 2**31 - 1, 0
|
|
|
+ idx1[H(3)] = 4294962296, 0 # 4294962296 is -5000 interpreted as an uint32_t
|
|
|
|
|
|
serialized = self._serialize_hashindex(idx1)
|
|
|
assert self._unpack(serialized) == self._unpack(self.HASHINDEX)
|
|
|
|
|
|
def test_read_known_good(self):
|
|
|
idx1 = self._deserialize_hashindex(self.HASHINDEX)
|
|
|
- assert idx1[H(1)] == (1, 2, 3)
|
|
|
- assert idx1[H(2)] == (2**31 - 1, 0, 0)
|
|
|
- assert idx1[H(3)] == (4294962296, 0, 0)
|
|
|
+ assert idx1[H(1)] == (1, 2)
|
|
|
+ assert idx1[H(2)] == (2**31 - 1, 0)
|
|
|
+ assert idx1[H(3)] == (4294962296, 0)
|
|
|
|
|
|
idx2 = ChunkIndex()
|
|
|
- idx2[H(3)] = 2**32 - 123456, 6, 7
|
|
|
+ idx2[H(3)] = 2**32 - 123456, 6
|
|
|
idx1.merge(idx2)
|
|
|
- assert idx1[H(3)] == (ChunkIndex.MAX_VALUE, 6, 7)
|
|
|
+ assert idx1[H(3)] == (ChunkIndex.MAX_VALUE, 6)
|
|
|
|
|
|
|
|
|
class HashIndexIntegrityTestCase(HashIndexDataTestCase):
|
|
@@ -497,16 +498,16 @@ class HashIndexCompactTestCase(HashIndexDataTestCase):
|
|
|
def test_merge(self):
|
|
|
master = ChunkIndex()
|
|
|
idx1 = ChunkIndex()
|
|
|
- idx1[H(1)] = 1, 100, 100
|
|
|
- idx1[H(2)] = 2, 200, 200
|
|
|
- idx1[H(3)] = 3, 300, 300
|
|
|
+ idx1[H(1)] = 1, 100
|
|
|
+ idx1[H(2)] = 2, 200
|
|
|
+ idx1[H(3)] = 3, 300
|
|
|
idx1.compact()
|
|
|
- assert idx1.size() == 18 + 3 * (32 + 3 * 4)
|
|
|
+ assert idx1.size() == 18 + 3 * (32 + 2 * 4)
|
|
|
|
|
|
master.merge(idx1)
|
|
|
- assert master[H(1)] == (1, 100, 100)
|
|
|
- assert master[H(2)] == (2, 200, 200)
|
|
|
- assert master[H(3)] == (3, 300, 300)
|
|
|
+ assert master[H(1)] == (1, 100)
|
|
|
+ assert master[H(2)] == (2, 200)
|
|
|
+ assert master[H(3)] == (3, 300)
|
|
|
|
|
|
|
|
|
class NSIndexTestCase(BaseTestCase):
|