添加map的比较函数

This commit is contained in:
建峰 2025-06-20 11:45:32 +08:00
parent 9d26afb817
commit 40071507c4
3 changed files with 43 additions and 43 deletions

View File

@ -30,6 +30,7 @@
"assert.h": "c", "assert.h": "c",
"limits.h": "c", "limits.h": "c",
"cstdint": "c", "cstdint": "c",
"unicstl_internal.h": "c" "unicstl_internal.h": "c",
"map.h": "c"
} }
} }

View File

@ -18,17 +18,16 @@ struct _map_node
{ {
char* key; char* key;
void* value; void* value;
size_t key_sz;
size_t value_sz;
}; };
typedef struct _map_node * map_node_t;
struct _map struct _map
{ {
// -------------------- private -------------------- // -------------------- private --------------------
tree_t _tree; tree_t _tree;
// uint32_t _size;
uint32_t _obj_size; uint32_t _obj_size;
// uint32_t _capacity;
// uint32_t _ratio;
// -------------------- public -------------------- // -------------------- public --------------------
// kernel // kernel
@ -46,9 +45,6 @@ struct _map
// iter // iter
iterator_t(*iter)(struct _map* self, enum _tree_order); iterator_t(*iter)(struct _map* self, enum _tree_order);
// config
compare_fun_t compare; // !!! you have to implement this function
// -------------------- debug -------------------- // -------------------- debug --------------------
void (*print_obj)(void* obj); void (*print_obj)(void* obj);
}; };

View File

@ -17,24 +17,22 @@ struct _map_node* map_node_new(struct _map *self, const char* key, void* value)
{ {
return NULL; 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) if (!node->key)
{ {
free(node); free(node);
return NULL; return NULL;
} }
node->value = node->key + node->key_sz;
node->value = malloc(self->_obj_size); // copy
if (!node->value) memcpy(node->key, key, node->key_sz);
{ node->key[node->key_sz] = '\0';
free(node->key); memcpy(node->value, value, node->value_sz);
free(node);
return NULL;
}
memcpy(node->key, key, keylen);
memcpy(node->value, value, self->_obj_size);
return node; return node;
} }
@ -46,29 +44,11 @@ static void map_node_free(struct _map_node** node)
{ {
free((*node)->key); free((*node)->key);
} }
if ((*node)->value != NULL)
{
free((*node)->value);
}
free(*node); free(*node);
*node = NULL; *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) bool map_empty(struct _map* self)
{ {
return self->_tree->empty(self->_tree); return self->_tree->empty(self->_tree);
@ -79,6 +59,20 @@ uint32_t map_size(struct _map* self)
return self->_tree->size(self->_tree); 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) bool map_insert(struct _map* self, const char* key, void* value)
{ {
struct _map_node* node = NULL; 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) bool map_delete(struct _map* self, const char* key, void* value)
{ {
struct _map_node node = {.key = key, .value = value}; // struct _map_node node = {.key = key, .value = value};
return self->_tree->delete(self->_tree, &node); // return self->_tree->delete(self->_tree, &node);
} }
void map_contains(struct _map* self, const char* key) 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; 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) bool map_init(struct _map* self, uint32_t obj_size)
{ {
assert(self != NULL); assert(self != NULL);
@ -129,6 +132,7 @@ bool map_init(struct _map* self, uint32_t obj_size)
{ {
return false; return false;
} }
self->_tree->compare = map_compare;
// -------------------- public -------------------- // -------------------- public --------------------
// kernel // kernel
@ -145,9 +149,8 @@ bool map_init(struct _map* self, uint32_t obj_size)
self->size = map_size; self->size = map_size;
// -------------------- default -------------------- // -------------------- default --------------------
self->compare = default_compare; // self->compare = default_compare;
self->print_obj = default_print_obj; self->print_obj = default_print_obj;
self->_tree->compare = self->compare;
return true; return true;
} }
@ -157,7 +160,7 @@ bool map_destory(struct _map* self)
self->clear(self); self->clear(self);
if(self->_tree != NULL) if(self->_tree != NULL)
{ {
tree_rb_free(self->_tree); tree_free(&self->_tree);
self->_tree = NULL; self->_tree = NULL;
} }
return true; return true;