@@ -231,27 +231,25 @@ int round_up_pow2(int v)
231231 *
232232 * Return: The pointer of created hashmap.
233233 */
234- hashmap_t * hashmap_create (int size )
234+ hashmap_t * hashmap_create (int cap )
235235{
236236 hashmap_t * map = malloc (sizeof (hashmap_t ));
237237
238238 if (!map ) {
239- printf ("Failed to allocate hashmap_t with size %d\n" , size );
239+ printf ("Failed to allocate hashmap_t with capacity %d\n" , cap );
240240 return NULL ;
241241 }
242242
243- map -> size = round_up_pow2 (size );
244- map -> buckets = malloc (map -> size * sizeof (hashmap_node_t * ));
243+ map -> size = 0 ;
244+ map -> cap = round_up_pow2 (cap );
245+ map -> buckets = calloc (map -> cap , sizeof (hashmap_node_t * ));
245246
246247 if (!map -> buckets ) {
247248 printf ("Failed to allocate buckets in hashmap_t\n" );
248249 free (map );
249250 return NULL ;
250251 }
251252
252- for (int i = 0 ; i < map -> size ; i ++ )
253- map -> buckets [i ] = 0 ;
254-
255253 return map ;
256254}
257255
@@ -290,6 +288,47 @@ hashmap_node_t *hashmap_node_new(char *key, void *val)
290288 return node ;
291289}
292290
291+ void hashmap_rehash (hashmap_t * map )
292+ {
293+ if (!map )
294+ return ;
295+
296+ int old_cap = map -> cap ;
297+ hashmap_node_t * * old_buckets = map -> buckets ;
298+
299+ map -> cap <<= 1 ;
300+ map -> buckets = calloc (map -> cap , sizeof (hashmap_node_t * ));
301+
302+ if (!map -> buckets ) {
303+ printf ("Failed to allocate new buckets in hashmap_t\n" );
304+ map -> buckets = old_buckets ;
305+ map -> cap = old_cap ;
306+ return ;
307+ }
308+
309+ for (int i = 0 ; i < old_cap ; i ++ ) {
310+ hashmap_node_t * cur = old_buckets [i ], * next , * target_cur ;
311+
312+ while (cur ) {
313+ next = cur -> next ;
314+ cur -> next = NULL ;
315+ int index = hashmap_hash_index (map -> cap , cur -> key );
316+ target_cur = map -> buckets [index ];
317+
318+ if (!target_cur ) {
319+ map -> buckets [index ] = cur ;
320+ } else {
321+ cur -> next = target_cur ;
322+ map -> buckets [index ] = cur ;
323+ }
324+
325+ cur = next ;
326+ }
327+ }
328+
329+ free (old_buckets );
330+ }
331+
293332/**
294333 * hashmap_put() - puts a key-value pair into given hashmap.
295334 * If key already contains a value, then replace it with new
@@ -304,42 +343,60 @@ void hashmap_put(hashmap_t *map, char *key, void *val)
304343 if (!map )
305344 return ;
306345
307- int index = hashmap_hash_index (map -> size , key );
308- hashmap_node_t * cur = map -> buckets [index ];
346+ int index = hashmap_hash_index (map -> cap , key );
347+ hashmap_node_t * cur = map -> buckets [index ],
348+ * new_node = hashmap_node_new (key , val );
309349
310350 if (!cur ) {
311- map -> buckets [index ] = hashmap_node_new ( key , val ) ;
351+ map -> buckets [index ] = new_node ;
312352 } else {
313353 while (cur -> next )
314354 cur = cur -> next ;
315- cur -> next = hashmap_node_new ( key , val ) ;
355+ cur -> next = new_node ;
316356 }
317357
318- /* TODO: Rehash if size exceeds size * load factor */
358+ map -> size ++ ;
359+ /* Check if size of map exceeds load factor 75% (or 3/4 of capacity) */
360+ if ((map -> cap >> 2 ) + (map -> cap >> 1 ) <= map -> size )
361+ hashmap_rehash (map );
319362}
320363
321364/**
322- * hashmap_get () - gets value from hashmap from given key.
365+ * hashmap_get_node () - gets key- value pair node from hashmap from given key.
323366 * @map: The hashmap to be looked up. Must no be NULL.
324367 * @key: The key string. May be NULL.
325368 *
326369 * Return: The look up result, if the key-value pair entry
327- * exists, then returns its value's address , NULL otherwise.
370+ * exists, then returns address of itself , NULL otherwise.
328371 */
329- void * hashmap_get (hashmap_t * map , char * key )
372+ hashmap_node_t * hashmap_get_node (hashmap_t * map , char * key )
330373{
331374 if (!map )
332375 return NULL ;
333376
334- int index = hashmap_hash_index (map -> size , key );
377+ int index = hashmap_hash_index (map -> cap , key );
335378
336379 for (hashmap_node_t * cur = map -> buckets [index ]; cur ; cur = cur -> next )
337380 if (!strcmp (cur -> key , key ))
338- return cur -> val ;
381+ return cur ;
339382
340383 return NULL ;
341384}
342385
386+ /**
387+ * hashmap_get() - gets value from hashmap from given key.
388+ * @map: The hashmap to be looked up. Must no be NULL.
389+ * @key: The key string. May be NULL.
390+ *
391+ * Return: The look up result, if the key-value pair entry
392+ * exists, then returns its value's address, NULL otherwise.
393+ */
394+ void * hashmap_get (hashmap_t * map , char * key )
395+ {
396+ hashmap_node_t * node = hashmap_get_node (map , key );
397+ return node ? node -> val : NULL ;
398+ }
399+
343400/**
344401 * hashmap_contains() - checks if the key-value pair entry exists
345402 * from given key.
@@ -351,7 +408,7 @@ void *hashmap_get(hashmap_t *map, char *key)
351408 */
352409bool hashmap_contains (hashmap_t * map , char * key )
353410{
354- return hashmap_get (map , key );
411+ return hashmap_get_node (map , key );
355412}
356413
357414/**
0 commit comments