blob: a78580599ea023c8cd5897d1ee145d0a747e7f92 [file] [log] [blame]
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