libmya 0.1.0
Library to parse Mya language.
Loading...
Searching...
No Matches
hashtable.c
Go to the documentation of this file.
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include "dstring.h"
6#include "hashtable.h"
7
8static void
9_hashtable_add_collision(hashitem_t* item, const char* key, int64_t value);
10
11static hashitem_t*
12_hashtable_find_collision(hashitem_t* item, const char* key);
13
14static hash_t
15_hash_djb2(const char* key);
16
17void
19{
20 hashtable->_size = size;
21
22 hashtable->items = calloc(size, sizeof(hashitem_t));
23}
24
25void
27{
28 for (int i = 0; i < hashtable->_size; i++) {
29 if (! hashtable->items[i].is_set) {
30 continue;
31 }
32
34
35 if (hashtable->items[i]._collisions_length == 0) {
36 continue;
37 }
38
39 for (int j = 0; j < hashtable->items[i]._collisions_length; j++) {
41 }
42
43 free(hashtable->items[i]._collisions);
44 }
45
46 free(hashtable->items);
47 hashtable->items = NULL;
48}
49
50void
51hashtable_set(hashtable_t* hashtable, const char* key, int64_t value)
52{
53 hash_t index = _hash_djb2(key) % hashtable->_size;
54 hashitem_t* item = &hashtable->items[index];
55
56 if (! item->is_set) {
57 item->is_set = true;
58 item->value = value;
59 dstring_init(&item->key, 0);
60 dstring_copy(&item->key, key);
61 return;
62 }
63
64 if (strcmp(item->key.data, key) == 0) {
65 item->value = value;
66 return;
67 }
68
69 _hashtable_add_collision(item, key, value);
70}
71
73hashtable_get(hashtable_t* hashtable, const char* key, int64_t* value)
74{
75 hash_t index = _hash_djb2(key) % hashtable->_size;
76 hashitem_t* item = &hashtable->items[index];
77
78 if (! item->is_set) {
79 return ERR_INVALID_INDEX;
80 }
81
82 if (strcmp(item->key.data, key) == 0) {
83 *value = item->value;
84 return ERR_OK;
85 }
86
87 item = _hashtable_find_collision(item, key);
88 if (item == NULL) {
89 return ERR_INVALID_INDEX;
90 }
91
92 *value = item->value;
93 return ERR_OK;
94}
95
96static void
97_hashtable_add_collision(hashitem_t* item, const char* key, int64_t value)
98{
99 hashitem_t* collision = _hashtable_find_collision(item, key);
100
101 if (collision != NULL) {
102 collision->value = value;
103 return;
104 }
105
106 if (item->_collisions_size < item->_collisions_length + 1) {
108 item->_collisions = realloc(item->_collisions, sizeof(hashitem_t) * item->_collisions_size);
109 }
110
111 collision = &item->_collisions[item->_collisions_length++];
112 collision->is_set = true;
113 collision->value = value;
114
115 dstring_init(&collision->key, 0);
116 dstring_copy(&collision->key, key);
117}
118
119static hashitem_t*
120_hashtable_find_collision(hashitem_t* item, const char* key)
121{
122 for (int i = 0; i < item->_collisions_length; i++) {
123 if (strcmp(item->_collisions[i].key.data, key) == 0) {
124 return &item->_collisions[i];
125 }
126 }
127
128 return NULL;
129}
130
131static hash_t
132_hash_djb2(const char* key)
133{
134 hash_t hash = 5381;
135
136 while (*key) {
137 hash = (hash * 33) ^ *key++;
138 }
139
140 return hash;
141}
void dstring_init(dstring_t *string, unsigned int buffer_size)
Initializes a dynamic string (dstring).
Definition dstring.c:10
void dstring_copy(dstring_t *string, const char *source)
Copies the content of source to the dstring.
Definition dstring.c:50
void dstring_close(dstring_t *string)
Closes the dynamic string.
Definition dstring.c:18
enum error_code error_code_t
Enumeration of error codes.
@ ERR_INVALID_INDEX
Definition err.h:19
@ ERR_OK
Definition err.h:15
void hashtable_init(hashtable_t *hashtable, unsigned int size)
Initializes a hashtable.
Definition hashtable.c:18
error_code_t hashtable_get(hashtable_t *hashtable, const char *key, int64_t *value)
Get the value of the specified key inside the hashtable.
Definition hashtable.c:73
void hashtable_close(hashtable_t *hashtable)
Close the given hashtable.
Definition hashtable.c:26
void hashtable_set(hashtable_t *hashtable, const char *key, int64_t value)
Set the value of the specified key inside the hashtable.
Definition hashtable.c:51
char * data
Pointer for the raw string content (a normal C string).
Definition dstring.h:12
struct hashitem * _collisions
List of another items with hash colliding with this.
Definition hashtable.h:21
unsigned int _collisions_size
The number of item slots allocated to _collisions memory.
Definition hashtable.h:24
bool is_set
Is true if this item has set.
Definition hashtable.h:18
int64_t value
The value of the item.
Definition hashtable.h:20
dstring_t key
The item's key.
Definition hashtable.h:19
unsigned int _collisions_length
The number of items on the _collisions list.
Definition hashtable.h:23
A hashtable.
Definition hashtable.h:31
unsigned int _size
The number of item slots of the items allocated memory.
Definition hashtable.h:33
hashitem_t * items
List of items on the hashtable.
Definition hashtable.h:32
struct hashitem hashitem_t
An item inside a hashtable.
#define HASHTABLE_COLLISION_CHUNK_SIZE
The number of collisions items to (re)alloc when a collision occurs.
Definition hashtable.h:9
struct hashtable hashtable_t
A hashtable.
uint64_t hash_t
Definition hashtable.h:11