| From 11819a872b0db016c4d9abacf226c9351105da95 Mon Sep 17 00:00:00 2001 |
| From: Hans Beckerus <hans.beckerus at gmail.com> |
| Date: Sat, 24 Jul 2021 22:53:12 +0200 |
| Subject: [PATCH] Fix directory cache invalidation |
| |
| Commit 99d7a61bfbe7a37628543f15f71f63e7681ae8b3 changed from a linear |
| search algorithm to a recursive approach. There was however a flaw in |
| the latter which has now hopefully been corrected. |
| |
| Resolves-issue: #162 |
| Signed-off-by: Hans Beckerus <hans.beckerus at gmail.com> |
| --- |
| src/hashtable.c | 21 +++++++++++++-------- |
| 1 file changed, 13 insertions(+), 8 deletions(-) |
| |
| diff --git a/src/hashtable.c b/src/hashtable.c |
| index 08180e9..2fb01fe 100644 |
| --- a/src/hashtable.c |
| +++ b/src/hashtable.c |
| @@ -1,4 +1,3 @@ |
| - |
| /* |
| Copyright (C) 2009 Hans Beckerus (hans.beckerus@gmail.com) |
| |
| @@ -208,6 +207,7 @@ static int __hashtable_entry_delete_subkeys(void *h, const char *key, |
| struct hash_table *ht = h; |
| struct hash_table_entry *p; |
| struct hash_table_entry *b; |
| + struct hash_table_entry *n; |
| |
| if (++level > MAX_SUBKEY_LEVELS) |
| return level; |
| @@ -217,25 +217,28 @@ static int __hashtable_entry_delete_subkeys(void *h, const char *key, |
| |
| /* Search collision chain first to reduce bucket updates */ |
| while (p->next) { |
| + n = p; |
| p = p->next; |
| - if ((hash == p->hash) && (strstr(p->key, key) == p->key)) { |
| + if ((hash == b->hash) && (strstr(p->key, key) == p->key)) { |
| level = __hashtable_entry_delete_subkeys(h, key, |
| get_hash(p->key, 0), |
| level); |
| + if (level >= MAX_SUBKEY_LEVELS) |
| + return level; |
| hashtable_entry_delete_hash(h, p->key, hash); |
| - if (level > MAX_SUBKEY_LEVELS) |
| - goto out; |
| - p = b; |
| + p = n; |
| } |
| } |
| /* Finally check the bucket */ |
| if (b->key && (hash == b->hash) && (strstr(b->key, key) == b->key)) { |
| level = __hashtable_entry_delete_subkeys(h, key, |
| - get_hash(b->key, 0), level); |
| + get_hash(b->key, 0), |
| + level); |
| + if (level >= MAX_SUBKEY_LEVELS) |
| + return level; |
| hashtable_entry_delete_hash(h, b->key, hash); |
| } |
| |
| -out: |
| --level; |
| return level; |
| } |
| @@ -250,6 +253,7 @@ void hashtable_entry_delete_subkeys(void *h, const char *key, uint32_t hash) |
| struct hash_table *ht = h; |
| struct hash_table_entry *p; |
| struct hash_table_entry *b; |
| + struct hash_table_entry *n; |
| size_t i; |
| |
| if (!__hashtable_entry_delete_subkeys(h, key, hash, 0)) |
| @@ -261,10 +265,11 @@ void hashtable_entry_delete_subkeys(void *h, const char *key, uint32_t hash) |
| p = b; |
| /* Search collision chain first to reduce bucket updates */ |
| while (p->next) { |
| + n = p; |
| p = p->next; |
| if (strstr(p->key, key) == p->key) { |
| hashtable_entry_delete_hash(h, p->key, p->hash); |
| - p = b; |
| + p = n; |
| } |
| } |
| /* Finally check the bucket */ |
| -- |
| 2.33.0.rc1.237.g0d66db33f3-goog |
| |