diff --git a/.vscode/settings.json b/.vscode/settings.json index 0df7e95..bda7a87 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -30,6 +30,7 @@ "assert.h": "c", "limits.h": "c", "cstdint": "c", - "unicstl_internal.h": "c" + "unicstl_internal.h": "c", + "map.h": "c" } } \ No newline at end of file diff --git a/include/map.h b/include/map.h index 639a502..a8f0bc3 100644 --- a/include/map.h +++ b/include/map.h @@ -18,17 +18,16 @@ struct _map_node { char* key; void* value; + size_t key_sz; + size_t value_sz; }; +typedef struct _map_node * map_node_t; struct _map { // -------------------- private -------------------- tree_t _tree; - - // uint32_t _size; uint32_t _obj_size; - // uint32_t _capacity; - // uint32_t _ratio; // -------------------- public -------------------- // kernel @@ -46,9 +45,6 @@ struct _map // iter iterator_t(*iter)(struct _map* self, enum _tree_order); - // config - compare_fun_t compare; // !!! you have to implement this function - // -------------------- debug -------------------- void (*print_obj)(void* obj); }; diff --git a/src/map.c b/src/map.c index c2b2cf5..2df2e1e 100644 --- a/src/map.c +++ b/src/map.c @@ -17,24 +17,22 @@ struct _map_node* map_node_new(struct _map *self, const char* key, void* value) { return NULL; } - uint32_t keylen = strlen(key) + 1; - node->key = (char*)malloc(sizeof(char) * keylen); + + // Allocating memory for key and value only once can improve performance. + node->key_sz = strlen(key) + 1; + node->value_sz = self->_obj_size; + node->key = (char*)malloc(node->key_sz + node->value_sz); if (!node->key) { free(node); return NULL; } + node->value = node->key + node->key_sz; - node->value = malloc(self->_obj_size); - if (!node->value) - { - free(node->key); - free(node); - return NULL; - } - - memcpy(node->key, key, keylen); - memcpy(node->value, value, self->_obj_size); + // copy + memcpy(node->key, key, node->key_sz); + node->key[node->key_sz] = '\0'; + memcpy(node->value, value, node->value_sz); return node; } @@ -46,29 +44,11 @@ static void map_node_free(struct _map_node** node) { free((*node)->key); } - if ((*node)->value != NULL) - { - free((*node)->value); - } free(*node); *node = NULL; } } -bool map_clear(struct _map* self) -{ - struct _map_node* node = NULL; - iterator_t iter = self->_tree->iter(self->_tree, TREE_DFS_IN); - while(iter->hasnext(&iter)) - { - // tree & map malloc memory independently, so free them one by one. - node = (struct _map_node*)iter->next(&iter); - map_node_free(&node); - } - - return self->_tree->clear(self->_tree); -} - bool map_empty(struct _map* self) { return self->_tree->empty(self->_tree); @@ -79,6 +59,20 @@ uint32_t map_size(struct _map* self) return self->_tree->size(self->_tree); } +bool map_clear(struct _map* self) +{ + struct _map_node* node = NULL; + iterator_t iter = self->_tree->iter(self->_tree, TREE_DFS_IN); + while(iter->hasnext(iter)) + { + // tree & map malloc memory independently, so free them one by one. + node = (struct _map_node*)iter->next(iter); + map_node_free(&node); + } + + return self->_tree->clear(self->_tree); +} + bool map_insert(struct _map* self, const char* key, void* value) { struct _map_node* node = NULL; @@ -92,8 +86,8 @@ bool map_insert(struct _map* self, const char* key, void* value) bool map_delete(struct _map* self, const char* key, void* value) { - struct _map_node node = {.key = key, .value = value}; - return self->_tree->delete(self->_tree, &node); + // struct _map_node node = {.key = key, .value = value}; + // return self->_tree->delete(self->_tree, &node); } void map_contains(struct _map* self, const char* key) @@ -113,6 +107,15 @@ bool map_set(struct _map* self, const char* key, void* value) return false; } +static int map_compare(void* obj1, void* obj2) +{ + assert(obj1 != NULL && obj2 != NULL); + + map_node_t node1 = (map_node_t)obj1; + map_node_t node2 = (map_node_t)obj2; + return strcmp(node1->key, node2->key); +} + bool map_init(struct _map* self, uint32_t obj_size) { assert(self != NULL); @@ -129,6 +132,7 @@ bool map_init(struct _map* self, uint32_t obj_size) { return false; } + self->_tree->compare = map_compare; // -------------------- public -------------------- // kernel @@ -145,9 +149,8 @@ bool map_init(struct _map* self, uint32_t obj_size) self->size = map_size; // -------------------- default -------------------- - self->compare = default_compare; + // self->compare = default_compare; self->print_obj = default_print_obj; - self->_tree->compare = self->compare; return true; } @@ -157,7 +160,7 @@ bool map_destory(struct _map* self) self->clear(self); if(self->_tree != NULL) { - tree_rb_free(self->_tree); + tree_free(&self->_tree); self->_tree = NULL; } return true;