зеркало из https://github.com/microsoft/git.git
124 строки
3.4 KiB
C
124 строки
3.4 KiB
C
#ifndef HASHMAP_H
|
|
#define HASHMAP_H
|
|
|
|
/*
|
|
* Generic implementation of hash-based key-value mappings.
|
|
* See Documentation/technical/api-hashmap.txt.
|
|
*/
|
|
|
|
/* FNV-1 functions */
|
|
|
|
extern unsigned int strhash(const char *buf);
|
|
extern unsigned int strihash(const char *buf);
|
|
extern unsigned int memhash(const void *buf, size_t len);
|
|
extern unsigned int memihash(const void *buf, size_t len);
|
|
extern unsigned int memihash_cont(unsigned int hash_seed, const void *buf, size_t len);
|
|
|
|
static inline unsigned int sha1hash(const unsigned char *sha1)
|
|
{
|
|
/*
|
|
* Equivalent to 'return *(unsigned int *)sha1;', but safe on
|
|
* platforms that don't support unaligned reads.
|
|
*/
|
|
unsigned int hash;
|
|
memcpy(&hash, sha1, sizeof(hash));
|
|
return hash;
|
|
}
|
|
|
|
/* data structures */
|
|
|
|
struct hashmap_entry {
|
|
struct hashmap_entry *next;
|
|
unsigned int hash;
|
|
};
|
|
|
|
typedef int (*hashmap_cmp_fn)(const void *entry, const void *entry_or_key,
|
|
const void *keydata);
|
|
|
|
struct hashmap {
|
|
struct hashmap_entry **table;
|
|
hashmap_cmp_fn cmpfn;
|
|
unsigned int size, tablesize, grow_at, shrink_at;
|
|
unsigned disallow_rehash : 1;
|
|
};
|
|
|
|
struct hashmap_iter {
|
|
struct hashmap *map;
|
|
struct hashmap_entry *next;
|
|
unsigned int tablepos;
|
|
};
|
|
|
|
/* hashmap functions */
|
|
|
|
extern void hashmap_init(struct hashmap *map, hashmap_cmp_fn equals_function,
|
|
size_t initial_size);
|
|
extern void hashmap_free(struct hashmap *map, int free_entries);
|
|
|
|
/* hashmap_entry functions */
|
|
|
|
static inline void hashmap_entry_init(void *entry, unsigned int hash)
|
|
{
|
|
struct hashmap_entry *e = entry;
|
|
e->hash = hash;
|
|
e->next = NULL;
|
|
}
|
|
extern void *hashmap_get(const struct hashmap *map, const void *key,
|
|
const void *keydata);
|
|
extern void *hashmap_get_next(const struct hashmap *map, const void *entry);
|
|
extern void hashmap_add(struct hashmap *map, void *entry);
|
|
extern void *hashmap_put(struct hashmap *map, void *entry);
|
|
extern void *hashmap_remove(struct hashmap *map, const void *key,
|
|
const void *keydata);
|
|
|
|
static inline void *hashmap_get_from_hash(const struct hashmap *map,
|
|
unsigned int hash, const void *keydata)
|
|
{
|
|
struct hashmap_entry key;
|
|
hashmap_entry_init(&key, hash);
|
|
return hashmap_get(map, &key, keydata);
|
|
}
|
|
|
|
int hashmap_bucket(const struct hashmap *map, unsigned int hash);
|
|
|
|
/*
|
|
* Disallow/allow rehashing of the hashmap.
|
|
* This is useful if the caller knows that the hashmap
|
|
* needs multi-threaded access. The caller is still
|
|
* required to guard/lock searches and inserts in a
|
|
* manner appropriate to their usage. This simply
|
|
* prevents the table from being unexpectedly re-mapped.
|
|
*
|
|
* If is up to the caller to ensure that the hashmap is
|
|
* initialized to a reasonable size to prevent poor
|
|
* performance.
|
|
*
|
|
* When value=1, prevent future rehashes on adds and deleted.
|
|
* When value=0, allow future rehahses. This DOES NOT force
|
|
* a rehash now.
|
|
*/
|
|
static inline void hashmap_disallow_rehash(struct hashmap *map, unsigned value)
|
|
{
|
|
map->disallow_rehash = value;
|
|
}
|
|
|
|
/* hashmap_iter functions */
|
|
|
|
extern void hashmap_iter_init(struct hashmap *map, struct hashmap_iter *iter);
|
|
extern void *hashmap_iter_next(struct hashmap_iter *iter);
|
|
static inline void *hashmap_iter_first(struct hashmap *map,
|
|
struct hashmap_iter *iter)
|
|
{
|
|
hashmap_iter_init(map, iter);
|
|
return hashmap_iter_next(iter);
|
|
}
|
|
|
|
/* string interning */
|
|
|
|
extern const void *memintern(const void *data, size_t len);
|
|
static inline const char *strintern(const char *string)
|
|
{
|
|
return memintern(string, strlen(string));
|
|
}
|
|
|
|
#endif
|