@@ -231,27 +231,25 @@ int round_up_pow2(int v)
231
231
*
232
232
* Return: The pointer of created hashmap.
233
233
*/
234
- hashmap_t * hashmap_create (int size )
234
+ hashmap_t * hashmap_create (int cap )
235
235
{
236
236
hashmap_t * map = malloc (sizeof (hashmap_t ));
237
237
238
238
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 );
240
240
return NULL ;
241
241
}
242
242
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 * ));
245
246
246
247
if (!map -> buckets ) {
247
248
printf ("Failed to allocate buckets in hashmap_t\n" );
248
249
free (map );
249
250
return NULL ;
250
251
}
251
252
252
- for (int i = 0 ; i < map -> size ; i ++ )
253
- map -> buckets [i ] = 0 ;
254
-
255
253
return map ;
256
254
}
257
255
@@ -290,6 +288,47 @@ hashmap_node_t *hashmap_node_new(char *key, void *val)
290
288
return node ;
291
289
}
292
290
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
+
293
332
/**
294
333
* hashmap_put() - puts a key-value pair into given hashmap.
295
334
* 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)
304
343
if (!map )
305
344
return ;
306
345
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 );
309
349
310
350
if (!cur ) {
311
- map -> buckets [index ] = hashmap_node_new ( key , val ) ;
351
+ map -> buckets [index ] = new_node ;
312
352
} else {
313
353
while (cur -> next )
314
354
cur = cur -> next ;
315
- cur -> next = hashmap_node_new ( key , val ) ;
355
+ cur -> next = new_node ;
316
356
}
317
357
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 );
319
362
}
320
363
321
364
/**
322
- * hashmap_get () - gets value from hashmap from given key.
365
+ * hashmap_get_node () - gets key- value pair node from hashmap from given key.
323
366
* @map: The hashmap to be looked up. Must no be NULL.
324
367
* @key: The key string. May be NULL.
325
368
*
326
369
* 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.
328
371
*/
329
- void * hashmap_get (hashmap_t * map , char * key )
372
+ hashmap_node_t * hashmap_get_node (hashmap_t * map , char * key )
330
373
{
331
374
if (!map )
332
375
return NULL ;
333
376
334
- int index = hashmap_hash_index (map -> size , key );
377
+ int index = hashmap_hash_index (map -> cap , key );
335
378
336
379
for (hashmap_node_t * cur = map -> buckets [index ]; cur ; cur = cur -> next )
337
380
if (!strcmp (cur -> key , key ))
338
- return cur -> val ;
381
+ return cur ;
339
382
340
383
return NULL ;
341
384
}
342
385
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
+
343
400
/**
344
401
* hashmap_contains() - checks if the key-value pair entry exists
345
402
* from given key.
@@ -351,7 +408,7 @@ void *hashmap_get(hashmap_t *map, char *key)
351
408
*/
352
409
bool hashmap_contains (hashmap_t * map , char * key )
353
410
{
354
- return hashmap_get (map , key );
411
+ return hashmap_get_node (map , key );
355
412
}
356
413
357
414
/**
0 commit comments