xref: /aosp_15_r20/external/erofs-utils/include/erofs/hashmap.h (revision 33b1fccf6a0fada2c2875d400ed01119b7676ee5)
1*33b1fccfSAndroid Build Coastguard Worker /* SPDX-License-Identifier: GPL-2.0 */
2*33b1fccfSAndroid Build Coastguard Worker #ifndef __EROFS_HASHMAP_H
3*33b1fccfSAndroid Build Coastguard Worker #define __EROFS_HASHMAP_H
4*33b1fccfSAndroid Build Coastguard Worker 
5*33b1fccfSAndroid Build Coastguard Worker #ifdef __cplusplus
6*33b1fccfSAndroid Build Coastguard Worker extern "C"
7*33b1fccfSAndroid Build Coastguard Worker {
8*33b1fccfSAndroid Build Coastguard Worker #endif
9*33b1fccfSAndroid Build Coastguard Worker 
10*33b1fccfSAndroid Build Coastguard Worker /* Copied from https://github.com/git/git.git */
11*33b1fccfSAndroid Build Coastguard Worker #include <stdio.h>
12*33b1fccfSAndroid Build Coastguard Worker #include <stdlib.h>
13*33b1fccfSAndroid Build Coastguard Worker #include <string.h>
14*33b1fccfSAndroid Build Coastguard Worker 
15*33b1fccfSAndroid Build Coastguard Worker #include "flex-array.h"
16*33b1fccfSAndroid Build Coastguard Worker 
17*33b1fccfSAndroid Build Coastguard Worker /*
18*33b1fccfSAndroid Build Coastguard Worker  * Generic implementation of hash-based key-value mappings.
19*33b1fccfSAndroid Build Coastguard Worker  * See Documentation/technical/api-hashmap.txt.
20*33b1fccfSAndroid Build Coastguard Worker  */
21*33b1fccfSAndroid Build Coastguard Worker 
22*33b1fccfSAndroid Build Coastguard Worker /* FNV-1 functions */
23*33b1fccfSAndroid Build Coastguard Worker unsigned int strhash(const char *str);
24*33b1fccfSAndroid Build Coastguard Worker unsigned int strihash(const char *str);
25*33b1fccfSAndroid Build Coastguard Worker unsigned int memhash(const void *buf, size_t len);
26*33b1fccfSAndroid Build Coastguard Worker unsigned int memihash(const void *buf, size_t len);
27*33b1fccfSAndroid Build Coastguard Worker 
sha1hash(const unsigned char * sha1)28*33b1fccfSAndroid Build Coastguard Worker static inline unsigned int sha1hash(const unsigned char *sha1)
29*33b1fccfSAndroid Build Coastguard Worker {
30*33b1fccfSAndroid Build Coastguard Worker 	/*
31*33b1fccfSAndroid Build Coastguard Worker 	 * Equivalent to 'return *(unsigned int *)sha1;', but safe on
32*33b1fccfSAndroid Build Coastguard Worker 	 * platforms that don't support unaligned reads.
33*33b1fccfSAndroid Build Coastguard Worker 	 */
34*33b1fccfSAndroid Build Coastguard Worker 	unsigned int hash;
35*33b1fccfSAndroid Build Coastguard Worker 
36*33b1fccfSAndroid Build Coastguard Worker 	memcpy(&hash, sha1, sizeof(hash));
37*33b1fccfSAndroid Build Coastguard Worker 	return hash;
38*33b1fccfSAndroid Build Coastguard Worker }
39*33b1fccfSAndroid Build Coastguard Worker 
40*33b1fccfSAndroid Build Coastguard Worker /* data structures */
41*33b1fccfSAndroid Build Coastguard Worker struct hashmap_entry {
42*33b1fccfSAndroid Build Coastguard Worker 	struct hashmap_entry *next;
43*33b1fccfSAndroid Build Coastguard Worker 	unsigned int hash;
44*33b1fccfSAndroid Build Coastguard Worker };
45*33b1fccfSAndroid Build Coastguard Worker 
46*33b1fccfSAndroid Build Coastguard Worker typedef int (*hashmap_cmp_fn)(const void *entry, const void *entry_or_key,
47*33b1fccfSAndroid Build Coastguard Worker 		const void *keydata);
48*33b1fccfSAndroid Build Coastguard Worker 
49*33b1fccfSAndroid Build Coastguard Worker struct hashmap {
50*33b1fccfSAndroid Build Coastguard Worker 	struct hashmap_entry **table;
51*33b1fccfSAndroid Build Coastguard Worker 	hashmap_cmp_fn cmpfn;
52*33b1fccfSAndroid Build Coastguard Worker 	unsigned int size, tablesize, grow_at, shrink_at;
53*33b1fccfSAndroid Build Coastguard Worker };
54*33b1fccfSAndroid Build Coastguard Worker 
55*33b1fccfSAndroid Build Coastguard Worker struct hashmap_iter {
56*33b1fccfSAndroid Build Coastguard Worker 	struct hashmap *map;
57*33b1fccfSAndroid Build Coastguard Worker 	struct hashmap_entry *next;
58*33b1fccfSAndroid Build Coastguard Worker 	unsigned int tablepos;
59*33b1fccfSAndroid Build Coastguard Worker };
60*33b1fccfSAndroid Build Coastguard Worker 
61*33b1fccfSAndroid Build Coastguard Worker /* hashmap functions */
62*33b1fccfSAndroid Build Coastguard Worker void hashmap_init(struct hashmap *map, hashmap_cmp_fn equals_function,
63*33b1fccfSAndroid Build Coastguard Worker 		  size_t initial_size);
64*33b1fccfSAndroid Build Coastguard Worker int hashmap_free(struct hashmap *map);
65*33b1fccfSAndroid Build Coastguard Worker 
66*33b1fccfSAndroid Build Coastguard Worker /* hashmap_entry functions */
hashmap_entry_init(void * entry,unsigned int hash)67*33b1fccfSAndroid Build Coastguard Worker static inline void hashmap_entry_init(void *entry, unsigned int hash)
68*33b1fccfSAndroid Build Coastguard Worker {
69*33b1fccfSAndroid Build Coastguard Worker 	struct hashmap_entry *e = entry;
70*33b1fccfSAndroid Build Coastguard Worker 
71*33b1fccfSAndroid Build Coastguard Worker 	e->hash = hash;
72*33b1fccfSAndroid Build Coastguard Worker 	e->next = NULL;
73*33b1fccfSAndroid Build Coastguard Worker }
74*33b1fccfSAndroid Build Coastguard Worker 
75*33b1fccfSAndroid Build Coastguard Worker void *hashmap_get(const struct hashmap *map, const void *key, const void *keydata);
76*33b1fccfSAndroid Build Coastguard Worker void *hashmap_get_next(const struct hashmap *map, const void *entry);
77*33b1fccfSAndroid Build Coastguard Worker void hashmap_add(struct hashmap *map, void *entry);
78*33b1fccfSAndroid Build Coastguard Worker void *hashmap_remove(struct hashmap *map, const void *key);
79*33b1fccfSAndroid Build Coastguard Worker 
hashmap_get_from_hash(const struct hashmap * map,unsigned int hash,const void * keydata)80*33b1fccfSAndroid Build Coastguard Worker static inline void *hashmap_get_from_hash(const struct hashmap *map,
81*33b1fccfSAndroid Build Coastguard Worker 					  unsigned int hash,
82*33b1fccfSAndroid Build Coastguard Worker 					  const void *keydata)
83*33b1fccfSAndroid Build Coastguard Worker {
84*33b1fccfSAndroid Build Coastguard Worker 	struct hashmap_entry key;
85*33b1fccfSAndroid Build Coastguard Worker 
86*33b1fccfSAndroid Build Coastguard Worker 	hashmap_entry_init(&key, hash);
87*33b1fccfSAndroid Build Coastguard Worker 	return hashmap_get(map, &key, keydata);
88*33b1fccfSAndroid Build Coastguard Worker }
89*33b1fccfSAndroid Build Coastguard Worker 
90*33b1fccfSAndroid Build Coastguard Worker /* hashmap_iter functions */
91*33b1fccfSAndroid Build Coastguard Worker void hashmap_iter_init(struct hashmap *map, struct hashmap_iter *iter);
92*33b1fccfSAndroid Build Coastguard Worker void *hashmap_iter_next(struct hashmap_iter *iter);
hashmap_iter_first(struct hashmap * map,struct hashmap_iter * iter)93*33b1fccfSAndroid Build Coastguard Worker static inline void *hashmap_iter_first(struct hashmap *map,
94*33b1fccfSAndroid Build Coastguard Worker 				       struct hashmap_iter *iter)
95*33b1fccfSAndroid Build Coastguard Worker {
96*33b1fccfSAndroid Build Coastguard Worker 	hashmap_iter_init(map, iter);
97*33b1fccfSAndroid Build Coastguard Worker 	return hashmap_iter_next(iter);
98*33b1fccfSAndroid Build Coastguard Worker }
99*33b1fccfSAndroid Build Coastguard Worker 
hashmap_disable_shrink(struct hashmap * map)100*33b1fccfSAndroid Build Coastguard Worker static inline void hashmap_disable_shrink(struct hashmap * map)
101*33b1fccfSAndroid Build Coastguard Worker {
102*33b1fccfSAndroid Build Coastguard Worker 	map->shrink_at = 0;
103*33b1fccfSAndroid Build Coastguard Worker }
104*33b1fccfSAndroid Build Coastguard Worker /* string interning */
105*33b1fccfSAndroid Build Coastguard Worker const void *memintern(const void *data, size_t len);
strintern(const char * string)106*33b1fccfSAndroid Build Coastguard Worker static inline const char *strintern(const char *string)
107*33b1fccfSAndroid Build Coastguard Worker {
108*33b1fccfSAndroid Build Coastguard Worker 	return memintern(string, strlen(string));
109*33b1fccfSAndroid Build Coastguard Worker }
110*33b1fccfSAndroid Build Coastguard Worker 
111*33b1fccfSAndroid Build Coastguard Worker #ifdef __cplusplus
112*33b1fccfSAndroid Build Coastguard Worker }
113*33b1fccfSAndroid Build Coastguard Worker #endif
114*33b1fccfSAndroid Build Coastguard Worker 
115*33b1fccfSAndroid Build Coastguard Worker #endif
116