X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fshared%2Fhashmap.c;h=dbf91c439ef1ad7d9e5b73901acb2d859180b150;hb=de99c9dcbaf6e474551266d8f0b519bf2d8d0522;hp=b1dccaf4e7d34bcb67afca93d6f8e2ae799b9aff;hpb=9bf3b53533cdc9b95c921b71da755401f223f765;p=elogind.git diff --git a/src/shared/hashmap.c b/src/shared/hashmap.c index b1dccaf4e..dbf91c439 100644 --- a/src/shared/hashmap.c +++ b/src/shared/hashmap.c @@ -164,6 +164,21 @@ int uint64_compare_func(const void *_a, const void *_b) { return a < b ? -1 : (a > b ? 1 : 0); } +#if SIZEOF_DEV_T != 8 +unsigned long devt_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) { + uint64_t u; + siphash24((uint8_t*) &u, p, sizeof(dev_t), hash_key); + return (unsigned long) u; +} + +int devt_compare_func(const void *_a, const void *_b) { + dev_t a, b; + a = *(const dev_t*) _a; + b = *(const dev_t*) _b; + return a < b ? -1 : (a > b ? 1 : 0); +} +#endif + static unsigned bucket_hash(Hashmap *h, const void *p) { return (unsigned) (h->hash_func(p, h->hash_key) % h->n_buckets); } @@ -201,7 +216,7 @@ Hashmap *hashmap_new(hash_func_t hash_func, compare_func_t compare_func) { if (!h) return NULL; - memset(h, 0, size); + memzero(h, size); } else { h = malloc0(size); @@ -582,6 +597,34 @@ void* hashmap_remove(Hashmap *h, const void *key) { return data; } +void* hashmap_remove2(Hashmap *h, const void *key, void **rkey) { + struct hashmap_entry *e; + unsigned hash; + void *data; + + if (!h) { + if (rkey) + *rkey = NULL; + return NULL; + } + + hash = bucket_hash(h, key); + e = hash_scan(h, hash, key); + if (!e) { + if (rkey) + *rkey = NULL; + return NULL; + } + + data = e->value; + if (rkey) + *rkey = (void*) e->key; + + remove_entry(h, e); + + return data; +} + int hashmap_remove_and_put(Hashmap *h, const void *old_key, const void *new_key, void *value) { struct hashmap_entry *e; unsigned old_hash, new_hash;