-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhashmap.h
144 lines (127 loc) · 4.72 KB
/
hashmap.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#ifndef HASHMAP_H_
#define HASHMAP_H_
#include <stdlib.h>
#include "vector.h"
#include "pair.h"
/**
* @def HASH_MAP_INITIAL_CAP
* The initial capacity of the hash map.
* It means, the initial number of <b> vectors </b> the hash map has.
*/
#define HASH_MAP_INITIAL_CAP 16UL
/**
* @def HASH_MAP_GROWTH_FACTOR
* The growth factor of the hash map.
* Example: hash_map(size=16),
* hash_map.add([16 elements]) ->
* hash_map(size=32)
*/
#define HASH_MAP_GROWTH_FACTOR 2UL
/**
* @def HASH_MAP_MIN_LOAD_FACTOR
* The minimal load factor the hash map can be in.
* Example: if the hash_map capacity is 16,
* and it has 4 elements in it (size is 4),
* if an element is erased, the load factor drops below 0.25,
* so the hash map should be minimized (to 8 vectors).
*/
#define HASH_MAP_MIN_LOAD_FACTOR 0.25
/**
* @def HASH_MAP_MAX_LOAD_FACTOR
* The maximal load factor the hash map can be in.
* Example: if the hash_map capacity is 16,
* and it has 12 elements in it (size is 12),
* if another element is added, the load factor goes above 0.75,
* so the hash map should be extended (to 32 vectors).
*/
#define HASH_MAP_MAX_LOAD_FACTOR 0.75
/**
* @typedef hash_func
* This type of function receives a keyT and returns
* a representational number of it.
* Example: lets say we have a pair ('Joe', 78) that we want to store in the hash map,
* the key is 'Joe' so it determines the bucket in the hash map,
* his index would be: size_t ind = hash_func('Joe') & (capacity - 1);
*/
typedef size_t (*hash_func) (const_keyT);
/**
* @typedef keyT_func
* A function that receives a const_keyT, and returns 1 if it fulfills some condition, and 0 else
*/
typedef int (*keyT_func) (const_keyT);
/**
* @typedef valueT_func
* A function that changes the value of a valueT, in-place
*/
typedef void (*valueT_func) (valueT);
/**
* @struct hashmap
* @param buckets dynamic array of vectors which stores the values.
* @param size the number of elements (pairs) stored in the hash map.
* @param capacity the number of buckets in the hash map.
* @param hash_func a function which "hashes" keys.
*/
typedef struct hashmap {
vector **buckets;
size_t size;
size_t capacity; // num of buckets
hash_func hash_func;
} hashmap;
/**
* Allocates dynamically new hash map element.
* @param func a function which "hashes" keys.
* @return pointer to dynamically allocated hashmap.
* @if_fail return NULL.
*/
hashmap *hashmap_alloc (hash_func func);
/**
* Frees a hash map and the elements the hash map itself allocated.
* @param p_hash_map pointer to dynamically allocated pointer to hash_map.
*/
void hashmap_free (hashmap **p_hash_map);
/**
* Inserts a new in_pair to the hash map.
* The function inserts *new*, *copied*, *dynamically allocated* in_pair,
* NOT the in_pair it receives as a parameter.
* @param hash_map the hash map to be inserted with new element.
* @param in_pair a in_pair the hash map would contain.
* @return returns 1 for successful insertion, 0 otherwise.
*/
int hashmap_insert (hashmap *hash_map, const pair *in_pair);
/**
* The function returns the value associated with the given key.
* @param hash_map a hash map.
* @param key the key to be checked.
* @return the value associated with key if exists, NULL otherwise (the value itself,
* not a copy of it).
*/
valueT hashmap_at (const hashmap *hash_map, const_keyT key);
/**
* The function erases the pair associated with key.
* @param hash_map a hash map.
* @param key a key of the pair to be erased.
* @return 1 if the erasing was done successfully, 0 otherwise. (if key not in map,
* considered fail).
*/
int hashmap_erase (hashmap *hash_map, const_keyT key);
/**
* This function returns the load factor of the hash map.
* @param hash_map a hash map.
* @return the hash map's load factor, -1 if the function failed.
*/
double hashmap_get_load_factor (const hashmap *hash_map);
/**
* This function receives a hashmap and 2 functions, the first checks a condition on the keys,
* and the seconds apply some modification on the values. The function should apply the modification
* only on the values that are associated with keys that meet the condition.
*
* Example: if the hashmap maps char->int, keyT_func checks if the char is a capital letter (A-Z),
* and val_t_func multiples the number by 2, hashmap_apply_if will change the map:
* {('C',2),('#',3),('X',5)}, to: {('C',4),('#',3),('X',10)}, and the return value will be 2.
* @param hash_map a hashmap
* @param keyT_func a function that checks a condition on keyT and return 1 if true, 0 else
* @param valT_func a function that modifies valueT, in-place
* @return number of changed values
*/
int hashmap_apply_if (const hashmap *hash_map, keyT_func keyT_func, valueT_func valT_func);//const
#endif //HASHMAP_H_