mirror of
https://github.com/borgbackup/borg.git
synced 2025-02-23 06:31:58 +00:00
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
This commit is contained in:
parent
27674d89e6
commit
a85cf75465
1 changed files with 12 additions and 12 deletions
|
@ -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,10 +134,14 @@ hashindex_lookup(HashIndex *index, const void *key, int *skip_hint)
|
|||
}
|
||||
idx = (idx + 1) % index->num_buckets;
|
||||
if(idx == start) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (start_idx != NULL) {
|
||||
(*start_idx) = (didx == -1) ? idx : didx;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
hashindex_resize(HashIndex *index, int capacity)
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue