mirror of
https://gitee.com/apaki/unicstl.git
synced 2025-07-04 08:06:52 +08:00
添加map相关函数实现,底层多关注内存的问题
This commit is contained in:
parent
1f2e4e56bb
commit
3c2ecd52b1
@ -23,24 +23,28 @@ struct _map_node
|
||||
struct _map
|
||||
{
|
||||
// -------------------- private --------------------
|
||||
tree_t tree;
|
||||
tree_t _tree;
|
||||
|
||||
// uint32_t _size;
|
||||
uint32_t _obj_size;
|
||||
// uint32_t _capacity;
|
||||
// uint32_t _ratio;
|
||||
|
||||
// -------------------- public --------------------
|
||||
// kernel
|
||||
bool (*insert)(struct _tree* self, const char* key, void* value);
|
||||
bool (*erase)(struct _tree* self, const char* key);
|
||||
void* (*find)(struct _tree* self, const char* key);
|
||||
|
||||
bool (*get)(struct _tree* self, const char* key, void* value);
|
||||
bool (*set)(struct _tree* self, const char* key, void* value);
|
||||
bool (*insert)(struct _map* self, const char* key, void* value);
|
||||
bool (*delete)(struct _map* self, const char* key, void* value);
|
||||
void (*contains)(struct _map* self, const char* key);
|
||||
bool (*get)(struct _map* self, const char* key, void* value);
|
||||
// bool (*set)(struct _map* self, const char* key, void* value);
|
||||
|
||||
// base
|
||||
bool (*clear)(struct _tree* self);
|
||||
bool (*empty)(struct _tree* self);
|
||||
uint32_t(*size)(struct _tree* self);
|
||||
bool (*clear)(struct _map* self);
|
||||
bool (*empty)(struct _map* self);
|
||||
uint32_t(*size)(struct _map* self);
|
||||
|
||||
// iter
|
||||
iterator_t(*iter)(struct _tree* self, enum _tree_order);
|
||||
iterator_t(*iter)(struct _map* self, enum _tree_order);
|
||||
|
||||
// config
|
||||
compare_fun_t compare; // !!! you have to implement this function
|
||||
@ -50,7 +54,7 @@ struct _map
|
||||
};
|
||||
typedef struct _map* map_t;
|
||||
|
||||
map_t map_new(uint32_t obj_size);
|
||||
map_t map_new(uint32_t obj_size); // obj_size is the size of value
|
||||
map_t unordered_map_new(uint32_t obj_size);
|
||||
|
||||
void map_free(map_t self);
|
||||
|
191
src/map.c
Normal file
191
src/map.c
Normal file
@ -0,0 +1,191 @@
|
||||
/**
|
||||
* @file map.c
|
||||
* @author wenjf (Orig5826@163.com)
|
||||
* @brief
|
||||
* @version 0.1
|
||||
* @date 2025-05-19
|
||||
*
|
||||
* @copyright Copyright (c) 2025
|
||||
*
|
||||
*/
|
||||
#include "map.h"
|
||||
|
||||
struct _map_node* map_node_new(struct _map *self, const char* key, void* value)
|
||||
{
|
||||
struct _map_node* node = (struct _map_node*)malloc(sizeof(struct _map_node));
|
||||
if (!node)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
uint32_t keylen = strlen(key) + 1;
|
||||
node->key = (char*)malloc(sizeof(char) * keylen);
|
||||
if (!node->key)
|
||||
{
|
||||
free(node);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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);
|
||||
return node;
|
||||
}
|
||||
|
||||
static void map_node_free(struct _map_node** node)
|
||||
{
|
||||
if (node != NULL && (*node) != NULL)
|
||||
{
|
||||
if ((*node)->key != NULL)
|
||||
{
|
||||
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, ORDER_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);
|
||||
}
|
||||
|
||||
uint32_t map_size(struct _map* self)
|
||||
{
|
||||
return self->_tree->size(self->_tree);
|
||||
}
|
||||
|
||||
bool map_insert(struct _map* self, const char* key, void* value)
|
||||
{
|
||||
struct _map_node* node = NULL;
|
||||
node = map_node_new(self, key, value);
|
||||
if(node == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return self->_tree->insert(self->_tree, &node);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void map_contains(struct _map* self, const char* key)
|
||||
{
|
||||
// struct _map_node node = {.key = key, .value = NULL};
|
||||
// return self->_tree->find(self->_tree, &node);
|
||||
}
|
||||
|
||||
bool map_get(struct _map* self, const char* key, void* value)
|
||||
{
|
||||
// struct _map_node node = {.key = key, .value = NULL};
|
||||
// return self->_tree->find(self->_tree, &node);
|
||||
}
|
||||
|
||||
bool map_set(struct _map* self, const char* key, void* value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool map_init(struct _map* self, uint32_t obj_size)
|
||||
{
|
||||
assert(self != NULL);
|
||||
if(obj_size == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// -------------------- private --------------------
|
||||
self->_obj_size = obj_size;
|
||||
|
||||
self->_tree = tree_rb_new(sizeof(struct _map_node));
|
||||
if(self->_tree == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// -------------------- public --------------------
|
||||
// kernel
|
||||
self->insert = map_insert;
|
||||
self->delete = map_delete;
|
||||
self->contains = map_contains;
|
||||
|
||||
self->get = map_get;
|
||||
// self->set = map_set;
|
||||
|
||||
// base
|
||||
self->clear = map_clear;
|
||||
self->empty = map_empty;
|
||||
self->size = map_size;
|
||||
|
||||
// -------------------- default --------------------
|
||||
self->compare = default_compare;
|
||||
self->print_obj = default_print_obj;
|
||||
self->_tree->compare = self->compare;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool map_destory(struct _map* self)
|
||||
{
|
||||
self->clear(self);
|
||||
if(self->_tree != NULL)
|
||||
{
|
||||
tree_rb_free(self->_tree);
|
||||
self->_tree = NULL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
map_t map_new(uint32_t obj_size)
|
||||
{
|
||||
map_t map = NULL;
|
||||
map = (map_t)malloc(sizeof(struct _map));
|
||||
if(map == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if(map_init(map, obj_size) != true)
|
||||
{
|
||||
free(map);
|
||||
return NULL;
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
map_t unordered_map_new(uint32_t obj_size)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void map_free(map_t self)
|
||||
{
|
||||
map_destory(self);
|
||||
free(self);
|
||||
}
|
Loading…
Reference in New Issue
Block a user