1
0
Fork 0
mirror of https://github.com/borgbackup/borg.git synced 2024-12-23 00:07:38 +00:00

Fix hashindex resize issue

closes #6
This commit is contained in:
Jonas Borgström 2013-10-02 20:42:26 +02:00
parent 0c278ad1fe
commit baaeb7e060
3 changed files with 39 additions and 5 deletions

View file

@ -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;
}
}

View file

@ -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:

View file

@ -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))