Browse Source

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
Radu Ciorba 8 năm trước cách đây
mục cha
commit
a85cf75465
1 tập tin đã thay đổi với 12 bổ sung12 xóa
  1. 12 12
      src/borg/_hashindex.c

+ 12 - 12
src/borg/_hashindex.c

@@ -109,19 +109,15 @@ hashindex_index(HashIndex *index, const void *key)
 }
 }
 
 
 static int
 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 didx = -1;
     int start = hashindex_index(index, key);
     int start = hashindex_index(index, key);
     int idx = start;
     int idx = start;
-    int offset;
-    for(offset=0;;offset++) {
-        if (skip_hint != NULL) {
-            (*skip_hint) = offset;
-        }
+    for(;;) {
         if(BUCKET_IS_EMPTY(index, idx))
         if(BUCKET_IS_EMPTY(index, idx))
         {
         {
-            return -1;
+            break;
         }
         }
         if(BUCKET_IS_DELETED(index, idx)) {
         if(BUCKET_IS_DELETED(index, idx)) {
             if(didx == -1) {
             if(didx == -1) {
@@ -138,9 +134,13 @@ hashindex_lookup(HashIndex *index, const void *key, int *skip_hint)
         }
         }
         idx = (idx + 1) % index->num_buckets;
         idx = (idx + 1) % index->num_buckets;
         if(idx == start) {
         if(idx == start) {
-            return -1;
+            break;
         }
         }
     }
     }
+    if (start_idx != NULL) {
+        (*start_idx) = (didx == -1) ? idx : didx;
+    }
+    return -1;
 }
 }
 
 
 static int
 static int
@@ -383,8 +383,8 @@ hashindex_get(HashIndex *index, const void *key)
 static int
 static int
 hashindex_set(HashIndex *index, const void *key, const void *value)
 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;
     uint8_t *ptr;
     if(idx < 0)
     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))) {
             if(!hashindex_resize(index, grow_size(index->num_buckets))) {
                 return 0;
                 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)) {
         while(!BUCKET_IS_EMPTY(index, idx) && !BUCKET_IS_DELETED(index, idx)) {
             idx = (idx + 1) % index->num_buckets;
             idx = (idx + 1) % index->num_buckets;
         }
         }