feat: added HashMap type
This commit is contained in:
		
							parent
							
								
									172d1ee10e
								
							
						
					
					
						commit
						c4ec92fa82
					
				
							
								
								
									
										58
									
								
								hash_map.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								hash_map.c
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,58 @@ | |||
| #include "hash_map.h" | ||||
| #include "string.h" | ||||
| 
 | ||||
| HashMap hash_map_from_sizes(size_t key, size_t value, HashFunc hasher) { | ||||
|     HashMap self = { | ||||
|         .hasher = hasher, | ||||
|         .key_size = key, | ||||
|         .value_size = value | ||||
|     }; | ||||
|     for(size_t i = 0; i < CUTES_HASH_MAP_BUCKETS; ++i) | ||||
|         self.buckets[i] = list_init(sizeof(uintptr_t) + key + value); | ||||
|     return self; | ||||
| } | ||||
| 
 | ||||
| void hash_map_empty(HashMap *self) { | ||||
|     for(size_t i = 0; i < CUTES_HASH_MAP_BUCKETS; ++i) { | ||||
|         list_empty(self->buckets + i); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void *hash_map_get_raw(HashMap *self, void *key) { | ||||
|     uintptr_t hash = self->hasher(key); // hash the key first
 | ||||
|     List bucket = self->buckets[hash % CUTES_HASH_MAP_BUCKETS]; // get the bucket to search
 | ||||
|     // linear search through the bucket to find the element
 | ||||
|     for(size_t i = 0; i < bucket.len; ++i) { | ||||
|         uintptr_t *key_at = list_at(&bucket, i); | ||||
|         if(hash == *key_at) | ||||
|             return ++key_at; | ||||
|     } | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| void hash_map_insert(HashMap *self, void *key, void *value) { | ||||
|     uintptr_t hash = self->hasher(key); | ||||
|     // stage key-value-pair data
 | ||||
|     char data[sizeof(uintptr_t) + self->key_size + self->value_size]; | ||||
|     memcpy(data, &hash, sizeof(uintptr_t)); // copy key hash into start of data
 | ||||
|     memcpy(data + sizeof(uintptr_t), key, self->key_size); | ||||
|     memcpy(data + sizeof(uintptr_t) + self->key_size, value, self->value_size); // copy value into end of data
 | ||||
|     // insert staged data into list
 | ||||
|     list_add(self->buckets + (hash % CUTES_HASH_MAP_BUCKETS), data); | ||||
| } | ||||
| 
 | ||||
| List hash_map_keys(HashMap *self) { | ||||
|     List keys = list_init(self->key_size); | ||||
|     for(size_t bucket_index = 0; bucket_index < CUTES_HASH_MAP_BUCKETS; ++bucket_index) | ||||
|         for(size_t key_index = 0; key_index < self->buckets[bucket_index].len; ++key_index) | ||||
|             list_add(&keys, list_at(self->buckets + bucket_index, key_index)); | ||||
|     return keys; | ||||
| } | ||||
| 
 | ||||
| List hash_map_values(HashMap *self) { | ||||
|     List values = list_init(self->value_size); | ||||
|     for(size_t bucket_index = 0; bucket_index < CUTES_HASH_MAP_BUCKETS; ++bucket_index) | ||||
|         for(size_t value_index = 0; value_index < self->buckets[bucket_index].len; ++value_index) | ||||
|             list_add(&values, ((char*)list_at(self->buckets + bucket_index, value_index)) + (sizeof(uintptr_t) + self->key_size)); | ||||
|     return values; | ||||
| } | ||||
							
								
								
									
										29
									
								
								hash_map.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								hash_map.h
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,29 @@ | |||
| #ifndef CUTES_HASH_MAP_H | ||||
| #define CUTES_HASH_MAP_H | ||||
| 
 | ||||
| #include "list.h" | ||||
| #include "stdint.h" | ||||
| #include "typeclass_helpers.h" | ||||
| 
 | ||||
| #define CUTES_HASH_MAP_BUCKETS 24 | ||||
| 
 | ||||
| typedef uintptr_t (*HashFunc)(void *data); | ||||
| 
 | ||||
| typedef struct HashMap { | ||||
|     List buckets[CUTES_HASH_MAP_BUCKETS]; | ||||
|     HashFunc hasher; | ||||
|     size_t key_size; | ||||
|     size_t value_size; | ||||
| } HashMap; | ||||
| 
 | ||||
| HashMap hash_map_from_sizes(size_t key_size, size_t value_size, HashFunc hasher); | ||||
| void hash_map_empty(HashMap *self); | ||||
| void *hash_map_get_raw(HashMap *self, void *key); | ||||
| void hash_map_insert(HashMap *self, void *key, void *value); | ||||
| List hash_map_keys(HashMap *self); | ||||
| List hash_map_values(HashMap *self); | ||||
| 
 | ||||
| #define hash_map_from_types(TKey, TValue, KeyHasher) (hash_map_from_sizes(sizeof(TKey), sizeof(TValue), (HashFunc)KeyHasher)); TC_FN_TYPECHECK(uintptr_t, KeyHasher, TKey*) | ||||
| #define hash_map_get_as(TValue, Self, Key) ((TValue*)hash_map_get_raw(Self, Key)) | ||||
| 
 | ||||
| #endif // !CUTES_HASH_MAP_H
 | ||||
		Loading…
	
		Reference in a new issue
	
	 Sara
						Sara