mirror of
https://github.com/VincentWei/MiniGUI.git
synced 2026-02-08 11:52:02 +08:00
improve the implementation of map based on rbtree to having the alternative free function per entry
This commit is contained in:
@@ -72,6 +72,7 @@ typedef struct _map_entry_t {
|
||||
struct rb_node node;
|
||||
void* key;
|
||||
void* val;
|
||||
free_val_fn free_val_alt; // alternative free function per entry
|
||||
} map_entry_t;
|
||||
|
||||
map_t* __mg_map_create (copy_key_fn copy_key, free_key_fn free_key,
|
||||
@@ -82,10 +83,29 @@ int __mg_map_clear (map_t* map);
|
||||
int __mg_map_get_size (map_t* map);
|
||||
|
||||
map_entry_t* __mg_map_find (map_t* map, const void* key);
|
||||
int __mg_map_insert (map_t* map, const void* key, const void* val);
|
||||
void* __mg_map_find_or_insert (map_t* map, const void* key, const void* val);
|
||||
int __mg_map_erase (map_t* map, void* key);
|
||||
int __mg_map_get_size (map_t* map);
|
||||
|
||||
int __mg_map_insert_ex (map_t* map, const void* key,
|
||||
const void* val, free_val_fn free_val_alt);
|
||||
static inline int __mg_map_insert (map_t* map, const void* key,
|
||||
const void* val)
|
||||
{
|
||||
return __mg_map_insert_ex (map, key, val, NULL);
|
||||
}
|
||||
|
||||
void* __mg_map_find_or_insert_ex (map_t* map, const void* key,
|
||||
const void* val, free_val_fn free_val_alt);
|
||||
|
||||
static inline void* __mg_map_find_or_insert (map_t* map, const void* key,
|
||||
const void* val)
|
||||
{
|
||||
return __mg_map_find_or_insert_ex (map, key, val, NULL);
|
||||
}
|
||||
|
||||
int __mg_map_replace (map_t* map, const void* key,
|
||||
const void* val, free_val_fn free_val_alt);
|
||||
|
||||
int __mg_map_erase (map_t* map, void* key);
|
||||
int __mg_map_get_size (map_t* map);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -129,7 +129,8 @@ int __mg_map_destroy (map_t* map)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static map_entry_t* new_entry (map_t* map, const void* key, const void* val)
|
||||
static map_entry_t* new_entry (map_t* map, const void* key,
|
||||
const void* val, free_val_fn free_val_alt)
|
||||
{
|
||||
map_entry_t* entry;
|
||||
|
||||
@@ -146,6 +147,8 @@ static map_entry_t* new_entry (map_t* map, const void* key, const void* val)
|
||||
}
|
||||
else
|
||||
entry->val = (void*)val;
|
||||
|
||||
entry->free_val_alt = free_val_alt;
|
||||
}
|
||||
|
||||
return entry;
|
||||
@@ -160,7 +163,10 @@ static void clear_node (map_t* map, struct rb_node* node)
|
||||
map->free_key (entry->key);
|
||||
}
|
||||
|
||||
if (map->free_val) {
|
||||
if (entry->free_val_alt) {
|
||||
entry->free_val_alt (entry->val);
|
||||
}
|
||||
else if (map->free_val) {
|
||||
map->free_val (entry->val);
|
||||
}
|
||||
|
||||
@@ -236,7 +242,42 @@ map_entry_t* __mg_map_find (map_t* map, const void* key)
|
||||
return entry;
|
||||
}
|
||||
|
||||
int __mg_map_insert (map_t* map, const void* key, const void* val)
|
||||
int __mg_map_replace (map_t* map, const void* key,
|
||||
const void* val, free_val_fn free_val_alt)
|
||||
{
|
||||
map_entry_t* entry = NULL;
|
||||
|
||||
entry = __mg_map_find (map, key);
|
||||
if (entry == NULL)
|
||||
return -1;
|
||||
|
||||
if (val == entry->val)
|
||||
return 0;
|
||||
|
||||
WRLOCK_MAP (map);
|
||||
|
||||
if (entry->free_val_alt) {
|
||||
entry->free_val_alt (entry->val);
|
||||
}
|
||||
else if (map->free_val) {
|
||||
map->free_val (entry->val);
|
||||
}
|
||||
|
||||
if (map->copy_val) {
|
||||
entry->val = map->copy_val (val);
|
||||
}
|
||||
else
|
||||
entry->val = (void*)val;
|
||||
|
||||
entry->free_val_alt = free_val_alt;
|
||||
|
||||
UNLOCK_MAP (map);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __mg_map_insert_ex (map_t* map, const void* key,
|
||||
const void* val, free_val_fn free_val_alt)
|
||||
{
|
||||
map_entry_t **pentry;
|
||||
map_entry_t *entry;
|
||||
@@ -271,7 +312,7 @@ int __mg_map_insert (map_t* map, const void* key, const void* val)
|
||||
}
|
||||
|
||||
if (!entry) {
|
||||
entry = new_entry (map, key, val);
|
||||
entry = new_entry (map, key, val, free_val_alt);
|
||||
rb_link_node (&entry->node,
|
||||
(struct rb_node*)parent, (struct rb_node**)pentry);
|
||||
__mg_rb_insert_color (&entry->node, &map->root);
|
||||
@@ -293,8 +334,8 @@ int __mg_map_insert (map_t* map, const void* key, const void* val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* __mg_map_find_or_insert (map_t* map, const void* key,
|
||||
const void* val)
|
||||
void* __mg_map_find_or_insert_ex (map_t* map, const void* key,
|
||||
const void* val, free_val_fn free_val_alt)
|
||||
{
|
||||
map_entry_t **pentry;
|
||||
map_entry_t *entry;
|
||||
@@ -331,7 +372,7 @@ void* __mg_map_find_or_insert (map_t* map, const void* key,
|
||||
UNLOCK_MAP (map);
|
||||
|
||||
if (entry == NULL) {
|
||||
entry = new_entry (map, key, val);
|
||||
entry = new_entry (map, key, val, free_val_alt);
|
||||
|
||||
WRLOCK_MAP (map);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user