From a85cf75465bbd15e016a2c73afbab98ee272e98a Mon Sep 17 00:00:00 2001 From: Radu Ciorba Date: Mon, 30 Jan 2017 23:29:08 +0200 Subject: [PATCH] fix wrong skip_hint on hashindex_set when encountering tombstones hashindex_lookup would always hint at skipping whatever it's probe length had been with no regard for tombstones it had encountered. This meant new keys would not overwrite first tombstones, but would always land on empty buckets. The regression was introduced in #1748 --- src/borg/_hashindex.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/borg/_hashindex.c b/src/borg/_hashindex.c index 7847cc5ca..5fea18f79 100644 --- a/src/borg/_hashindex.c +++ b/src/borg/_hashindex.c @@ -109,19 +109,15 @@ hashindex_index(HashIndex *index, const void *key) } static int -hashindex_lookup(HashIndex *index, const void *key, int *skip_hint) +hashindex_lookup(HashIndex *index, const void *key, int *start_idx) { int didx = -1; int start = hashindex_index(index, key); int idx = start; - int offset; - for(offset=0;;offset++) { - if (skip_hint != NULL) { - (*skip_hint) = offset; - } + for(;;) { if(BUCKET_IS_EMPTY(index, idx)) { - return -1; + break; } if(BUCKET_IS_DELETED(index, idx)) { if(didx == -1) { @@ -138,9 +134,13 @@ hashindex_lookup(HashIndex *index, const void *key, int *skip_hint) } idx = (idx + 1) % index->num_buckets; if(idx == start) { - return -1; + break; } } + if (start_idx != NULL) { + (*start_idx) = (didx == -1) ? idx : didx; + } + return -1; } static int @@ -383,8 +383,8 @@ hashindex_get(HashIndex *index, const void *key) static int hashindex_set(HashIndex *index, const void *key, const void *value) { - int offset = 0; - int idx = hashindex_lookup(index, key, &offset); + int start_idx; + int idx = hashindex_lookup(index, key, &start_idx); uint8_t *ptr; if(idx < 0) { @@ -392,9 +392,9 @@ hashindex_set(HashIndex *index, const void *key, const void *value) if(!hashindex_resize(index, grow_size(index->num_buckets))) { return 0; } - offset = 0; + start_idx = hashindex_index(index, key); } - idx = (hashindex_index(index, key) + offset) % index->num_buckets; + idx = start_idx; while(!BUCKET_IS_EMPTY(index, idx) && !BUCKET_IS_DELETED(index, idx)) { idx = (idx + 1) % index->num_buckets; }