diff options
Diffstat (limited to 'src/std_gc')
-rw-r--r-- | src/std_gc/hash_map.c | 31 | ||||
-rw-r--r-- | src/std_gc/list.c | 67 |
2 files changed, 83 insertions, 15 deletions
diff --git a/src/std_gc/hash_map.c b/src/std_gc/hash_map.c index 1960ffc..4d4c026 100644 --- a/src/std_gc/hash_map.c +++ b/src/std_gc/hash_map.c @@ -1,4 +1,5 @@ #include "../../include/std_gc/hash_map.h" +#include "../../include/value.h" #include <assert.h> #include <string.h> #include <stdio.h> @@ -127,9 +128,6 @@ static int tsl_hash_map_ensure_bucket_capacity_for_one_new_item(TslHashMap *self } } - if(old_capacity == 0) - return 1; - tsl_hash_map_reorder_nodes(self, old_capacity); return 1; } @@ -169,23 +167,26 @@ TslValue* tsl_hash_map_get(TslHashMap *self, const TslValue *key) { TslValue* tsl_hash_map_get_or_create(TslHashMap *self, const TslValue *key) { uint64_t hash; size_t index; - TslHashMapNode **bucket; - TslHashMapNode *node; TslValue *value; - if(self->buckets_capacity == 0) { - if(!tsl_hash_map_ensure_bucket_capacity_for_one_new_item(self)) - return NULL; - } + TslHashMapNode **bucket; hash = tsl_value_hash(key); + if(self->buckets_capacity > 0) { + size_t index = tsl_hash_map_get_index(self, hash); + TslHashMapNode **bucket = (TslHashMapNode**)self->buckets_data + index; + TslHashMapNode *node = *bucket; + while(node) { + if(hash == node->hash && tsl_value_equals(key, &node->key)) + return &node->value; + node = node->next; + } + } + + if(!tsl_hash_map_ensure_bucket_capacity_for_one_new_item(self)) + return NULL; + index = tsl_hash_map_get_index(self, hash); bucket = (TslHashMapNode**)self->buckets_data + index; - node = *bucket; - while(node) { - if(hash == node->hash && tsl_value_equals(key, &node->key)) - return &node->value; - node = node->next; - } if(!tsl_hash_map_append_bucket(bucket, hash, key, NULL, &value)) return NULL; diff --git a/src/std_gc/list.c b/src/std_gc/list.c new file mode 100644 index 0000000..5b7c7b6 --- /dev/null +++ b/src/std_gc/list.c @@ -0,0 +1,67 @@ +#include "../../include/std_gc/list.h" +#include "../../include/value.h" +#include <stdio.h> +#include <string.h> +#include <assert.h> +#ifdef DEBUG +#define GC_DEBUG +#endif +#include <gc.h> + +void tsl_list_init(TslList *self) { + self->data = NULL; + self->size = 0; + self->capacity = 0; +} + +static int tsl_list_ensure_capacity(TslList *self, size_t new_size) { + void *new_ptr; + size_t new_capacity = self->capacity; + if(new_size <= self->capacity) + return 1; + + if(new_capacity == 0) + new_capacity = 8; + + while(new_capacity < new_size) { + new_capacity <<= 1; + } + + new_ptr = GC_REALLOC(self->data, new_capacity); + if(!new_ptr) { + fprintf(stderr, "Error: buffer append failed. Reason: out of memory\n"); + return 0; + } + + self->data = new_ptr; + self->capacity = new_capacity; + return 1; +} + +int tsl_list_append(TslList *self, const TslValue *data) { + if(!tsl_list_ensure_capacity(self, self->size + sizeof(TslValue))) + return 0; + memcpy((char*)self->data + self->size, data, sizeof(TslValue)); + self->size += sizeof(TslValue); + return 1; +} + +int tsl_list_set_capacity_hint(TslList *self, size_t capacity) { + return tsl_list_ensure_capacity(self, capacity); +} + +TslValue* tsl_list_begin(TslList *self) { + return self->data; +} + +TslValue* tsl_list_end(TslList *self) { + return (TslValue*)((char*)self->data + self->size); +} + +TslValue* tsl_list_get(TslList *self, double index) { + /* TODO: Verify if overflow check is needed */ + intptr_t index_i = index; + if(index_i >= 0 && index_i < (intptr_t)self->size / (intptr_t)sizeof(TslValue)) + return (TslValue*)self->data + index_i; + return NULL; +} |