From: Peter Barada <peter.barada@logicpd.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [Patch v2] Fix hash table deletion to prevent lost entries
Date: Thu, 20 Jan 2011 10:53:35 -0500 [thread overview]
Message-ID: <4D385A7F.2070803@logicpd.com> (raw)
In-Reply-To: <20110119204755.B8D0DD301BF@gemini.denx.de>
On 01/19/2011 03:47 PM, Wolfgang Denk wrote:
> Dear Peter Barada,
>
> In message <4D371208.3090801@logicpd.com> you wrote:
>>>> The hash delete code is in error; instead of just removing the deleted
>>>> key, it should instead allocate a new hashtable, hash all the keys into
>>>> the new table except for the deleted key and then reclaim the old table
>>>> (and deleted key).
>>> Can you please come up with a patch?
>>
From: Peter Barada <peter.barada@logicpd.com>
Date: Thu, 20 Jan 2011 10:38:57 -0500
Subject: [PATCH] Fix hashtable to properly handle deletion.
Use negative used value to mark deleted entry. Search keeps probing past
deleted entries. Adding an entry uses first deleted entry when it hits
end of probe chain.
Signed-off-by: Peter Barada <peter.barada@logicpd.com>
---
lib/hashtable.c | 18 +++++++++++++-----
1 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/lib/hashtable.c b/lib/hashtable.c
index 9f069c0..fcdb53c 100644
--- a/lib/hashtable.c
+++ b/lib/hashtable.c
@@ -65,7 +65,7 @@
* which describes the current status.
*/
typedef struct _ENTRY {
- unsigned int used;
+ int used;
ENTRY entry;
} _ENTRY;
@@ -152,7 +152,7 @@ void hdestroy_r(struct hsearch_data *htab)
/* free used memory */
for (i = 1; i <= htab->size; ++i) {
- if (htab->table[i].used) {
+ if (htab->table[i].used > 0) {
ENTRY *ep = &htab->table[i].entry;
free(ep->key);
@@ -209,7 +209,7 @@ int hmatch_r(const char *match, int last_idx, ENTRY ** retval,
size_t key_len = strlen(match);
for (idx = last_idx + 1; idx < htab->size; ++idx) {
- if (!htab->table[idx].used)
+ if (htab->table[idx].used > 0)
continue;
if (!strncmp(match, htab->table[idx].entry.key, key_len)) {
*retval = &htab->table[idx].entry;
@@ -229,6 +229,7 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
unsigned int count;
unsigned int len = strlen(item.key);
unsigned int idx;
+ unsigned int first_deleted = 0;
/* Compute an value for the given string. Perhaps use a better method. */
hval = len;
@@ -256,6 +257,10 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
*/
unsigned hval2;
+ if (htab->table[idx].used == -1
+ && !first_deleted)
+ first_deleted = idx;
+
if (htab->table[idx].used == hval
&& strcmp(item.key, htab->table[idx].entry.key) == 0) {
/* Overwrite existing value? */
@@ -335,6 +340,9 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
* Create new entry;
* create copies of item.key and item.data
*/
+ if (first_deleted)
+ idx = first_deleted;
+
htab->table[idx].used = hval;
htab->table[idx].entry.key = strdup(item.key);
htab->table[idx].entry.data = strdup(item.data);
@@ -387,7 +395,7 @@ int hdelete_r(const char *key, struct hsearch_data *htab)
free(ep->key);
free(ep->data);
- htab->table[idx].used = 0;
+ htab->table[idx].used = -1;
--htab->filled;
@@ -467,7 +475,7 @@ ssize_t hexport_r(struct hsearch_data *htab, const char sep,
*/
for (i = 1, n = 0, totlen = 0; i <= htab->size; ++i) {
- if (htab->table[i].used) {
+ if (htab->table[i].used > 0) {
ENTRY *ep = &htab->table[i].entry;
list[n++] = ep;
--
1.7.0.4
--
Peter Barada
peter.barada at logicpd.com
next prev parent reply other threads:[~2011-01-20 15:53 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-01-17 22:53 [U-Boot] Hash problem Peter Barada
2011-01-19 8:32 ` Wolfgang Denk
2011-01-19 16:32 ` [U-Boot] [Patch] Fix hash table deletion to prevent lost entries Peter Barada
2011-01-19 20:47 ` Wolfgang Denk
2011-01-20 15:53 ` Peter Barada [this message]
2011-03-21 21:48 ` [U-Boot] [Patch v2] " Wolfgang Denk
2011-03-21 23:05 ` Peter Barada
2011-03-22 21:45 ` Wolfgang Denk
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4D385A7F.2070803@logicpd.com \
--to=peter.barada@logicpd.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox