Karsten Blees | 6a364ce | 2013-11-14 20:17:54 +0100 | [diff] [blame] | 1 | #ifndef HASHMAP_H |
| 2 | #define HASHMAP_H |
| 3 | |
| 4 | /* |
| 5 | * Generic implementation of hash-based key-value mappings. |
| 6 | * See Documentation/technical/api-hashmap.txt. |
| 7 | */ |
| 8 | |
| 9 | /* FNV-1 functions */ |
| 10 | |
| 11 | extern unsigned int strhash(const char *buf); |
| 12 | extern unsigned int strihash(const char *buf); |
| 13 | extern unsigned int memhash(const void *buf, size_t len); |
| 14 | extern unsigned int memihash(const void *buf, size_t len); |
| 15 | |
Karsten Blees | 039dc71 | 2014-07-03 00:20:20 +0200 | [diff] [blame] | 16 | static inline unsigned int sha1hash(const unsigned char *sha1) |
| 17 | { |
| 18 | /* |
| 19 | * Equivalent to 'return *(unsigned int *)sha1;', but safe on |
| 20 | * platforms that don't support unaligned reads. |
| 21 | */ |
| 22 | unsigned int hash; |
| 23 | memcpy(&hash, sha1, sizeof(hash)); |
| 24 | return hash; |
| 25 | } |
| 26 | |
Karsten Blees | 6a364ce | 2013-11-14 20:17:54 +0100 | [diff] [blame] | 27 | /* data structures */ |
| 28 | |
| 29 | struct hashmap_entry { |
| 30 | struct hashmap_entry *next; |
| 31 | unsigned int hash; |
| 32 | }; |
| 33 | |
| 34 | typedef int (*hashmap_cmp_fn)(const void *entry, const void *entry_or_key, |
| 35 | const void *keydata); |
| 36 | |
| 37 | struct hashmap { |
| 38 | struct hashmap_entry **table; |
| 39 | hashmap_cmp_fn cmpfn; |
| 40 | unsigned int size, tablesize, grow_at, shrink_at; |
| 41 | }; |
| 42 | |
| 43 | struct hashmap_iter { |
| 44 | struct hashmap *map; |
| 45 | struct hashmap_entry *next; |
| 46 | unsigned int tablepos; |
| 47 | }; |
| 48 | |
| 49 | /* hashmap functions */ |
| 50 | |
| 51 | extern void hashmap_init(struct hashmap *map, hashmap_cmp_fn equals_function, |
| 52 | size_t initial_size); |
| 53 | extern void hashmap_free(struct hashmap *map, int free_entries); |
| 54 | |
| 55 | /* hashmap_entry functions */ |
| 56 | |
Karsten Blees | b6aad99 | 2013-12-18 14:41:27 +0100 | [diff] [blame] | 57 | static inline void hashmap_entry_init(void *entry, unsigned int hash) |
Karsten Blees | 6a364ce | 2013-11-14 20:17:54 +0100 | [diff] [blame] | 58 | { |
| 59 | struct hashmap_entry *e = entry; |
| 60 | e->hash = hash; |
| 61 | e->next = NULL; |
| 62 | } |
| 63 | extern void *hashmap_get(const struct hashmap *map, const void *key, |
| 64 | const void *keydata); |
| 65 | extern void *hashmap_get_next(const struct hashmap *map, const void *entry); |
| 66 | extern void hashmap_add(struct hashmap *map, void *entry); |
| 67 | extern void *hashmap_put(struct hashmap *map, void *entry); |
| 68 | extern void *hashmap_remove(struct hashmap *map, const void *key, |
| 69 | const void *keydata); |
| 70 | |
Karsten Blees | ab73a9d | 2014-07-03 00:22:11 +0200 | [diff] [blame] | 71 | static inline void *hashmap_get_from_hash(const struct hashmap *map, |
| 72 | unsigned int hash, const void *keydata) |
| 73 | { |
| 74 | struct hashmap_entry key; |
| 75 | hashmap_entry_init(&key, hash); |
| 76 | return hashmap_get(map, &key, keydata); |
| 77 | } |
| 78 | |
Karsten Blees | 6a364ce | 2013-11-14 20:17:54 +0100 | [diff] [blame] | 79 | /* hashmap_iter functions */ |
| 80 | |
| 81 | extern void hashmap_iter_init(struct hashmap *map, struct hashmap_iter *iter); |
| 82 | extern void *hashmap_iter_next(struct hashmap_iter *iter); |
| 83 | static inline void *hashmap_iter_first(struct hashmap *map, |
| 84 | struct hashmap_iter *iter) |
| 85 | { |
| 86 | hashmap_iter_init(map, iter); |
| 87 | return hashmap_iter_next(iter); |
| 88 | } |
| 89 | |
Karsten Blees | 7b64d42 | 2014-07-03 00:22:54 +0200 | [diff] [blame] | 90 | /* string interning */ |
| 91 | |
| 92 | extern const void *memintern(const void *data, size_t len); |
| 93 | static inline const char *strintern(const char *string) |
| 94 | { |
| 95 | return memintern(string, strlen(string)); |
| 96 | } |
| 97 | |
Karsten Blees | 6a364ce | 2013-11-14 20:17:54 +0100 | [diff] [blame] | 98 | #endif |