hashindex: implement KeyError

This commit is contained in:
Thomas Waldmann 2017-06-17 20:00:06 +02:00
parent b7b6abca7a
commit 72ef24cbc0
4 changed files with 13 additions and 6 deletions

View file

@ -160,6 +160,8 @@ hashindex_lookup(HashIndex *index, const void *key, int *start_idx)
}
else if(BUCKET_MATCHES_KEY(index, idx, key)) {
if (didx != -1) {
// note: although lookup is logically a read-only operation,
// we optimize (change) the hashindex here "on the fly".
memcpy(BUCKET_ADDR(index, didx), BUCKET_ADDR(index, idx), index->bucket_size);
BUCKET_MARK_DELETED(index, idx);
idx = didx;
@ -592,7 +594,7 @@ hashindex_delete(HashIndex *index, const void *key)
{
int idx = hashindex_lookup(index, key, NULL);
if (idx < 0) {
return 1;
return -1;
}
BUCKET_MARK_DELETED(index, idx);
index->num_entries -= 1;

View file

@ -9,7 +9,7 @@ from libc.errno cimport errno
from cpython.exc cimport PyErr_SetFromErrnoWithFilename
from cpython.buffer cimport PyBUF_SIMPLE, PyObject_GetBuffer, PyBuffer_Release
API_VERSION = '1.1_04'
API_VERSION = '1.1_05'
cdef extern from "_hashindex.c":
@ -117,7 +117,12 @@ cdef class IndexBase:
def __delitem__(self, key):
assert len(key) == self.key_size
if not hashindex_delete(self.index, <char *>key):
rc = hashindex_delete(self.index, <char *>key)
if rc == 1:
return # success
if rc == -1:
raise KeyError(key)
if rc == 0:
raise Exception('hashindex_delete failed')
def get(self, key, default=None):

View file

@ -131,7 +131,7 @@ class MandatoryFeatureUnsupported(Error):
def check_extension_modules():
from . import platform, compress, item
if hashindex.API_VERSION != '1.1_04':
if hashindex.API_VERSION != '1.1_05':
raise ExtensionModuleError
if chunker.API_VERSION != '1.1_01':
raise ExtensionModuleError

View file

@ -73,11 +73,11 @@ class HashIndexTestCase(BaseTestCase):
def test_nsindex(self):
self._generic_test(NSIndex, lambda x: (x, x),
'b96ec1ddabb4278cc92261ee171f7efc979dc19397cc5e89b778f05fa25bf93f')
'85f72b036c692c8266e4f51ccf0cff2147204282b5e316ae508d30a448d88fef')
def test_chunkindex(self):
self._generic_test(ChunkIndex, lambda x: (x, x, x),
'9d437a1e145beccc790c69e66ba94fc17bd982d83a401c9c6e524609405529d8')
'c83fdf33755fc37879285f2ecfc5d1f63b97577494902126b6fb6f3e4d852488')
def test_resize(self):
n = 2000 # Must be >= MIN_BUCKETS