mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
Extend hash functions to handle non-null-terminated data.
This commit is contained in:
parent
b86ef8e2cb
commit
374df1cf8e
@ -1,5 +1,6 @@
|
|||||||
Version 2.00.17 -
|
Version 2.00.17 -
|
||||||
=============================
|
=============================
|
||||||
|
Extend hash functions to handle non-null-terminated data.
|
||||||
Add local activation support.
|
Add local activation support.
|
||||||
Tidy relative paths in makefile includes.
|
Tidy relative paths in makefile includes.
|
||||||
fsadm support for fsck and resizing - needs testing.
|
fsadm support for fsck and resizing - needs testing.
|
||||||
|
@ -19,7 +19,8 @@
|
|||||||
struct hash_node {
|
struct hash_node {
|
||||||
struct hash_node *next;
|
struct hash_node *next;
|
||||||
void *data;
|
void *data;
|
||||||
char key[1];
|
int keylen;
|
||||||
|
char key[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hash_table {
|
struct hash_table {
|
||||||
@ -56,22 +57,23 @@ static unsigned char _nums[] = {
|
|||||||
209
|
209
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct hash_node *_create_node(const char *str)
|
static struct hash_node *_create_node(const char *str, int len)
|
||||||
{
|
{
|
||||||
/* remember sizeof(n) includes an extra char from key[1],
|
struct hash_node *n = dbg_malloc(sizeof(*n) + len);
|
||||||
so not adding 1 to the strlen as you would expect */
|
|
||||||
struct hash_node *n = dbg_malloc(sizeof(*n) + strlen(str));
|
|
||||||
|
|
||||||
if (n)
|
if (n) {
|
||||||
strcpy(n->key, str);
|
memcpy(n->key, str, len);
|
||||||
|
n->keylen = len;
|
||||||
|
}
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned _hash(const char *str)
|
static unsigned _hash(const char *str, uint32_t len)
|
||||||
{
|
{
|
||||||
unsigned long h = 0, g;
|
unsigned long h = 0, g, i;
|
||||||
while (*str) {
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
h <<= 4;
|
h <<= 4;
|
||||||
h += _nums[(int) *str++];
|
h += _nums[(int) *str++];
|
||||||
g = h & ((unsigned long) 0xf << 16u);
|
g = h & ((unsigned long) 0xf << 16u);
|
||||||
@ -80,6 +82,7 @@ static unsigned _hash(const char *str)
|
|||||||
h ^= g >> 5u;
|
h ^= g >> 5u;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,32 +137,35 @@ void hash_destroy(struct hash_table *t)
|
|||||||
dbg_free(t);
|
dbg_free(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct hash_node **_find(struct hash_table *t, const char *key)
|
static inline struct hash_node **_find(struct hash_table *t, const char *key,
|
||||||
|
uint32_t len)
|
||||||
{
|
{
|
||||||
unsigned h = _hash(key) & (t->num_slots - 1);
|
unsigned h = _hash(key, len) & (t->num_slots - 1);
|
||||||
struct hash_node **c;
|
struct hash_node **c;
|
||||||
|
|
||||||
for (c = &t->slots[h]; *c; c = &((*c)->next))
|
for (c = &t->slots[h]; *c; c = &((*c)->next))
|
||||||
if (!strcmp(key, (*c)->key))
|
if (!memcmp(key, (*c)->key, len))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *hash_lookup(struct hash_table *t, const char *key)
|
void *hash_lookup_binary(struct hash_table *t, const char *key,
|
||||||
|
uint32_t len)
|
||||||
{
|
{
|
||||||
struct hash_node **c = _find(t, key);
|
struct hash_node **c = _find(t, key, len);
|
||||||
return *c ? (*c)->data : 0;
|
return *c ? (*c)->data : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hash_insert(struct hash_table *t, const char *key, void *data)
|
int hash_insert_binary(struct hash_table *t, const char *key,
|
||||||
|
uint32_t len, void *data)
|
||||||
{
|
{
|
||||||
struct hash_node **c = _find(t, key);
|
struct hash_node **c = _find(t, key, len);
|
||||||
|
|
||||||
if (*c)
|
if (*c)
|
||||||
(*c)->data = data;
|
(*c)->data = data;
|
||||||
else {
|
else {
|
||||||
struct hash_node *n = _create_node(key);
|
struct hash_node *n = _create_node(key, len);
|
||||||
|
|
||||||
if (!n)
|
if (!n)
|
||||||
return 0;
|
return 0;
|
||||||
@ -173,9 +179,10 @@ int hash_insert(struct hash_table *t, const char *key, void *data)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void hash_remove(struct hash_table *t, const char *key)
|
void hash_remove_binary(struct hash_table *t, const char *key,
|
||||||
|
uint32_t len)
|
||||||
{
|
{
|
||||||
struct hash_node **c = _find(t, key);
|
struct hash_node **c = _find(t, key, len);
|
||||||
|
|
||||||
if (*c) {
|
if (*c) {
|
||||||
struct hash_node *old = *c;
|
struct hash_node *old = *c;
|
||||||
@ -185,6 +192,21 @@ void hash_remove(struct hash_table *t, const char *key)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *hash_lookup(struct hash_table *t, const char *key)
|
||||||
|
{
|
||||||
|
return hash_lookup_binary(t, key, strlen(key) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int hash_insert(struct hash_table *t, const char *key, void *data)
|
||||||
|
{
|
||||||
|
return hash_insert_binary(t, key, strlen(key) + 1, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void hash_remove(struct hash_table *t, const char *key)
|
||||||
|
{
|
||||||
|
hash_remove_binary(t, key, strlen(key) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned hash_get_num_entries(struct hash_table *t)
|
unsigned hash_get_num_entries(struct hash_table *t)
|
||||||
{
|
{
|
||||||
return t->num_nodes;
|
return t->num_nodes;
|
||||||
@ -235,6 +257,6 @@ struct hash_node *hash_get_first(struct hash_table *t)
|
|||||||
|
|
||||||
struct hash_node *hash_get_next(struct hash_table *t, struct hash_node *n)
|
struct hash_node *hash_get_next(struct hash_table *t, struct hash_node *n)
|
||||||
{
|
{
|
||||||
unsigned h = _hash(n->key) & (t->num_slots - 1);
|
unsigned h = _hash(n->key, n->keylen) & (t->num_slots - 1);
|
||||||
return n->next ? n->next : _next_slot(t, h + 1);
|
return n->next ? n->next : _next_slot(t, h + 1);
|
||||||
}
|
}
|
||||||
|
@ -26,10 +26,14 @@ void hash_destroy(struct hash_table *t);
|
|||||||
void hash_wipe(struct hash_table *t);
|
void hash_wipe(struct hash_table *t);
|
||||||
|
|
||||||
void *hash_lookup(struct hash_table *t, const char *key);
|
void *hash_lookup(struct hash_table *t, const char *key);
|
||||||
void *hash_lookup_fixed(struct hash_table *t, const char *key, uint32_t len);
|
|
||||||
int hash_insert(struct hash_table *t, const char *key, void *data);
|
int hash_insert(struct hash_table *t, const char *key, void *data);
|
||||||
void hash_remove(struct hash_table *t, const char *key);
|
void hash_remove(struct hash_table *t, const char *key);
|
||||||
|
|
||||||
|
void *hash_lookup_binary(struct hash_table *t, const char *key, uint32_t len);
|
||||||
|
int hash_insert_binary(struct hash_table *t, const char *key, uint32_t len,
|
||||||
|
void *data);
|
||||||
|
void hash_remove_binary(struct hash_table *t, const char *key, uint32_t len);
|
||||||
|
|
||||||
unsigned hash_get_num_entries(struct hash_table *t);
|
unsigned hash_get_num_entries(struct hash_table *t);
|
||||||
void hash_iter(struct hash_table *t, iterate_fn f);
|
void hash_iter(struct hash_table *t, iterate_fn f);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user