diff --git a/darc/hashindex.pyx b/darc/hashindex.pyx index d9e120dfa..f3ac5bcfe 100644 --- a/darc/hashindex.pyx +++ b/darc/hashindex.pyx @@ -1,4 +1,6 @@ # -*- coding: utf-8 -*- +import os + cdef extern from "_hashindex.c": ctypedef struct HashIndex: @@ -22,7 +24,7 @@ cdef class IndexBase: cdef HashIndex *index def __cinit__(self, path): - self.index = hashindex_open(path) + self.index = hashindex_open(os.fsencode(path)) if not self.index: raise Exception('Failed to open %s' % path) @@ -64,7 +66,7 @@ cdef class NSIndex(IndexBase): @classmethod def create(cls, path, capacity=16): - index = hashindex_create(path, capacity, 32, 8) + index = hashindex_create(os.fsencode(path), capacity, 32, 8) if not index: raise Exception('Failed to create %s' % path) hashindex_close(index) @@ -121,7 +123,7 @@ cdef class ChunkIndex(IndexBase): @classmethod def create(cls, path, capacity=16): - index = hashindex_create(path, capacity, 32, 12) + index = hashindex_create(os.fsencode(path), capacity, 32, 12) hashindex_close(index) return cls(path) @@ -171,55 +173,3 @@ cdef class ChunkKeyIterator: raise StopIteration cdef int *value = (self.key + 32) return self.key[:32], (value[0], value[1], value[2]) - - -cdef class BandIndex(IndexBase): - - @classmethod - def create(cls, path, capacity=16): - index = hashindex_create(path, capacity, 4, 4) - hashindex_close(index) - return cls(path) - - def __getitem__(self, key): - cdef int k = key - data = hashindex_get(self.index, &k) - if not data: - raise KeyError - return data[0] - - def __delitem__(self, key): - cdef int k = key - hashindex_delete(self.index, &k) - - def __setitem__(self, key, value): - cdef int k = key - cdef int v = value - hashindex_set(self.index, &k, &v) - - def __contains__(self, key): - cdef int k = key - data = hashindex_get(self.index, &k) - return data != NULL - - def iteritems(self, marker=None, limit=0): - iter = BandKeyIterator() - iter.index = self.index - return iter - - -cdef class BandKeyIterator: - cdef HashIndex *index - cdef int *key - - def __cinit__(self): - self.key = NULL - - def __iter__(self): - return self - - def __next__(self): - self.key = hashindex_next_key(self.index, self.key) - if not self.key: - raise StopIteration - return self.key[0], self.key[1] diff --git a/darc/testsuite/hashindex.py b/darc/testsuite/hashindex.py new file mode 100644 index 000000000..e517b0ecf --- /dev/null +++ b/darc/testsuite/hashindex.py @@ -0,0 +1,48 @@ +import hashlib +import tempfile +from darc.hashindex import NSIndex, ChunkIndex +from darc.testsuite import DarcTestCase + + +class HashIndexTestCase(DarcTestCase): + + def _generic_test(self, cls, make_value, sha): + idx_name = tempfile.NamedTemporaryFile() + idx = cls.create(idx_name.name) + self.assert_equal(len(idx), 0) + # Test set + for x in range(100): + idx[bytes('%-32d' % x, 'ascii')] = make_value(x) + self.assert_equal(len(idx), 100) + for x in range(100): + self.assert_equal(idx[bytes('%-32d' % x, 'ascii')], make_value(x)) + # Test update + for x in range(100): + idx[bytes('%-32d' % x, 'ascii')] = make_value(x * 2) + self.assert_equal(len(idx), 100) + for x in range(100): + self.assert_equal(idx[bytes('%-32d' % x, 'ascii')], make_value(x * 2)) + # Test delete + for x in range(50): + del idx[bytes('%-32d' % x, 'ascii')] + self.assert_equal(len(idx), 50) + del idx + # Verify file contents + with open(idx_name.name, 'rb') as fd: + self.assert_equal(hashlib.sha256(fd.read()).hexdigest(), sha) + # Make sure we can open the file + idx = cls(idx_name.name) + self.assert_equal(len(idx), 50) + for x in range(50, 100): + self.assert_equal(idx[bytes('%-32d' % x, 'ascii')], make_value(x * 2)) + idx.clear() + self.assert_equal(len(idx), 0) + del idx + self.assert_equal(len(cls(idx_name.name)), 0) + + def test_nsindex(self): + self._generic_test(NSIndex, lambda x: (x, x), '926af057de19a82903fab517e0813e6fa16e4129df5b7062e9b1f24bbe98fb24') + + def test_chunkindex(self): + self._generic_test(ChunkIndex, lambda x: (x, x, x), 'cc60ec9265d172b20c33b6c00160abda1a6e881d07088b9d1c5997a82e05f5a7') +