mirror of
https://github.com/borgbackup/borg.git
synced 2024-12-23 00:07:38 +00:00
parent
0c278ad1fe
commit
baaeb7e060
3 changed files with 39 additions and 5 deletions
|
@ -110,6 +110,7 @@ static int
|
|||
hashindex_resize(HashIndex *index, int capacity)
|
||||
{
|
||||
char *new_path = malloc(strlen(index->path) + 5);
|
||||
int ret = 0;
|
||||
strcpy(new_path, index->path);
|
||||
strcat(new_path, ".tmp");
|
||||
HashIndex *new;
|
||||
|
@ -129,12 +130,20 @@ hashindex_resize(HashIndex *index, int capacity)
|
|||
index->lower_limit = new->lower_limit;
|
||||
index->upper_limit = new->upper_limit;
|
||||
index->buckets = new->buckets;
|
||||
unlink(index->path);
|
||||
rename(new_path, index->path);
|
||||
if(unlink(index->path) < 0) {
|
||||
EPRINTF("unlink failed");
|
||||
goto out;
|
||||
}
|
||||
if(rename(new_path, index->path) < 0) {
|
||||
EPRINTF_PATH(new_path, "rename failed");
|
||||
goto out;
|
||||
}
|
||||
ret = 1;
|
||||
out:
|
||||
free(new_path);
|
||||
free(new->path);
|
||||
free(new);
|
||||
return 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Public API */
|
||||
|
@ -237,10 +246,16 @@ hashindex_create(const char *path, int capacity, int key_size, int value_size)
|
|||
}
|
||||
if(fclose(fd) < 0) {
|
||||
EPRINTF_PATH(path, "fclose failed");
|
||||
if(unlink(path) < 0) {
|
||||
EPRINTF_PATH(path, "unlink failed");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
return hashindex_open(path, 0);
|
||||
error:
|
||||
if(unlink(path) < 0) {
|
||||
EPRINTF_PATH(path, "unlink failed");
|
||||
}
|
||||
EPRINTF_PATH(path, "fwrite failed");
|
||||
if(fclose(fd) < 0) {
|
||||
EPRINTF_PATH(path, "fclose failed");
|
||||
|
@ -338,7 +353,7 @@ hashindex_delete(HashIndex *index, const void *key)
|
|||
BUCKET_MARK_DELETED(index, idx);
|
||||
index->num_entries -= 1;
|
||||
if(index->num_entries < index->lower_limit) {
|
||||
if(!hashindex_resize(index, index->num_buckets * 2)) {
|
||||
if(!hashindex_resize(index, index->num_buckets / 2)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ class AtticTestCase(unittest.TestCase):
|
|||
assert_equal = unittest.TestCase.assertEqual
|
||||
assert_not_equal = unittest.TestCase.assertNotEqual
|
||||
assert_raises = unittest.TestCase.assertRaises
|
||||
assert_true = unittest.TestCase.assertTrue
|
||||
|
||||
def assert_dirs_equal(self, dir1, dir2):
|
||||
diff = filecmp.dircmp(dir1, dir2)
|
||||
|
@ -89,7 +90,7 @@ def get_tests(suite):
|
|||
"""
|
||||
for item in suite:
|
||||
try:
|
||||
# TODO: This could be "yield from..." with Python 3.3+
|
||||
# TODO: This could be "yield from..." with Python 3.3+
|
||||
for i in get_tests(item):
|
||||
yield i
|
||||
except TypeError:
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import hashlib
|
||||
import os
|
||||
import tempfile
|
||||
from attic.hashindex import NSIndex, ChunkIndex
|
||||
from attic.testsuite import AtticTestCase
|
||||
|
@ -46,3 +47,20 @@ def test_nsindex(self):
|
|||
def test_chunkindex(self):
|
||||
self._generic_test(ChunkIndex, lambda x: (x, x, x), 'ed22e8a883400453c0ee79a06c54df72c994a54eeefdc6c0989efdc5ee6d07b7')
|
||||
|
||||
def test_resize(self):
|
||||
n = 2000 # Must be >= MIN_BUCKETS
|
||||
idx_name = tempfile.NamedTemporaryFile()
|
||||
idx = NSIndex.create(idx_name.name)
|
||||
initial_size = os.path.getsize(idx_name.name)
|
||||
self.assert_equal(len(idx), 0)
|
||||
for x in range(n):
|
||||
idx[bytes('%-32d' % x, 'ascii')] = x, x
|
||||
idx.flush()
|
||||
self.assert_true(initial_size < os.path.getsize(idx_name.name))
|
||||
for x in range(n):
|
||||
del idx[bytes('%-32d' % x, 'ascii')]
|
||||
self.assert_equal(len(idx), 0)
|
||||
idx.flush()
|
||||
self.assert_equal(initial_size, os.path.getsize(idx_name.name))
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue