[U-Boot] [PATCH v5 06/19] hashtable: support multiple env contexts
AKASHI Takahiro
takahiro.akashi at linaro.org
Thu Sep 5 08:21:20 UTC 2019
With this patch, variable's context is always honored in all operations,
FIND/ENTER (including delete).
Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
---
include/search.h | 6 +++++-
lib/hashtable.c | 14 +++++++++++---
2 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/include/search.h b/include/search.h
index 0469a852e07c..202cf652de5f 100644
--- a/include/search.h
+++ b/include/search.h
@@ -25,13 +25,16 @@ enum env_action {
ENV_ENTER,
};
+struct env_context;
+
/** struct env_entry - An entry in the environment hashtable */
struct env_entry {
const char *key;
char *data;
int (*callback)(const char *name, const char *value, enum env_op op,
- int flags);
+ int flags);
int flags;
+ struct env_context *ctx;
};
/*
@@ -45,6 +48,7 @@ struct hsearch_data {
struct env_entry_node *table;
unsigned int size;
unsigned int filled;
+ struct env_context *ctx;
/*
* Callback function which will check whether the given change for variable
* "item" to "newval" may be applied or not, and possibly apply such change.
diff --git a/lib/hashtable.c b/lib/hashtable.c
index 2caab0a4c6d3..8fe017470256 100644
--- a/lib/hashtable.c
+++ b/lib/hashtable.c
@@ -231,6 +231,7 @@ static inline int _compare_and_overwrite_entry(struct env_entry item,
unsigned int idx)
{
if (htab->table[idx].used == hval
+ && (item.ctx && (item.ctx == htab->table[idx].entry.ctx))
&& strcmp(item.key, htab->table[idx].entry.key) == 0) {
/* Overwrite existing value? */
if (action == ENV_ENTER && item.data) {
@@ -247,8 +248,9 @@ static inline int _compare_and_overwrite_entry(struct env_entry item,
/* If there is a callback, call it */
if (htab->table[idx].entry.callback &&
- htab->table[idx].entry.callback(item.key,
- item.data, env_op_overwrite, flag)) {
+ htab->table[idx].entry.callback(item.key, item.data,
+ env_op_overwrite,
+ flag)) {
debug("callback() rejected setting variable "
"%s, skipping it!\n", item.key);
__set_errno(EINVAL);
@@ -340,6 +342,9 @@ int hsearch_r(struct env_entry item, enum env_action action,
if (idx == hval)
break;
+ if (htab->table[idx].used == USED_FREE)
+ break;
+
if (htab->table[idx].used == USED_DELETED
&& !first_deleted)
first_deleted = idx;
@@ -381,6 +386,7 @@ int hsearch_r(struct env_entry item, enum env_action action,
*retval = NULL;
return 0;
}
+ htab->table[idx].entry.ctx = item.ctx;
++htab->filled;
@@ -403,7 +409,7 @@ int hsearch_r(struct env_entry item, enum env_action action,
/* If there is a callback, call it */
if (htab->table[idx].entry.callback &&
htab->table[idx].entry.callback(item.key, item.data,
- env_op_create, flag)) {
+ env_op_create, flag)) {
debug("callback() rejected setting variable "
"%s, skipping it!\n", item.key);
_hdelete(item.key, htab, &htab->table[idx].entry, idx);
@@ -454,6 +460,7 @@ int hdelete_r(const char *key, struct hsearch_data *htab, int flag)
debug("hdelete: DELETE key \"%s\"\n", key);
+ e.ctx = htab->ctx;
e.key = (char *)key;
idx = hsearch_r(e, ENV_FIND, &ep, htab, 0);
@@ -928,6 +935,7 @@ int himport_r(struct hsearch_data *htab,
continue;
/* enter into hash table */
+ e.ctx = htab->ctx;
e.key = name;
e.data = value;
--
2.21.0
More information about the U-Boot
mailing list