Signed-off-by: icesky <icesky1stm@sina.com>
parent
fc26a04d47
commit
96513af0d5
|
|
@ -41,3 +41,8 @@ HashMap_test.c和List_test.c 可以使用mk来编译成可执行程序
|
|||
2)扩展了printf,支持回调函数自己定义打印格式。
|
||||
3)增加了hashmap和list的malloc_flag字段,可以控制是否在map或list中额外分配内存保存value
|
||||
4)在linux下测试,使用valgrind进行了内存泄漏测试,并修正了所有内存泄漏问题。
|
||||
|
||||
2016.08.04更新:
|
||||
1)为hashmap增加了XipHashMapNum和XipHashMapSize外部函数,可以检查当前元素个数,以及当前hashmap占用空间大小
|
||||
2)修改list,增加element节点,增加每个value的size保存。同时新增XipListSize外部函数,检查当前list占用空间大小
|
||||
3)修正了某些异常情况下,hashmap可能导致的内存泄漏问题。
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ int main()
|
|||
int i = 0;
|
||||
int length = 15;
|
||||
char tmpname[51];
|
||||
/*初始化put*/
|
||||
for ( i = 0; i < length ; i++)
|
||||
{
|
||||
strcpy( tmpname, name[i]);
|
||||
|
|
@ -28,20 +29,28 @@ int main()
|
|||
XipHashmapPut( hashmap, tmpname, tmpname, strlen(tmpname)+1);
|
||||
}
|
||||
|
||||
/*打印和检查*/
|
||||
XipHashmapPrint(hashmap, NULL);
|
||||
|
||||
/*查看set是否好用*/
|
||||
printf("GetSize--[%d]", XipHashmapSize(hashmap, NULL, NULL, NULL, NULL, NULL));
|
||||
XipHashmapPut( hashmap, "panzi", "iceskyiceskyicesky", strlen("iceskyiceskyicesky")+1);
|
||||
XipHashmapPrint(hashmap, name_print);
|
||||
printf("GetNum--[%d]", XipHashmapNum(hashmap));
|
||||
printf("GetSize--[%d]", XipHashmapSize(hashmap, NULL, NULL, NULL, NULL, NULL));
|
||||
|
||||
/*查看get是否好用*/
|
||||
for ( i = 0; i< length; i++)
|
||||
printf("get(%15s): %15s\n", name[i], (char *)XipHashmapGet(hashmap, name[i]));
|
||||
|
||||
XipHashmapPrint(hashmap, NULL);
|
||||
|
||||
/*查看remove是否好用*/
|
||||
printf("remove(%15s): %d\n", "lionsoul", XipHashmapRemove(hashmap, "lionsoul"));
|
||||
|
||||
XipHashmapPrint(hashmap, NULL);
|
||||
|
||||
/*查看destory*/
|
||||
XipHashmapDestory(hashmap);
|
||||
hashmap = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,10 +28,10 @@ int main()
|
|||
strcpy( tmp_name, name[i]);
|
||||
printf("Add(value:[%s]--[%s]);\n", name[i], XipListAdd( list, tmp_name,strlen(tmp_name)+1));
|
||||
}
|
||||
printf("Len--[%d],threshold[%d]\n", XipListLen(list), XipListThreshold(list));
|
||||
printf("Len--[%d],threshold[%d]memsize[%d]\n", XipListLen(list), XipListThreshold(list), XipListSize(list, NULL, NULL,NULL,NULL));
|
||||
|
||||
XipListPrint(list, name_printf);
|
||||
XipListPrint(list, NULL);
|
||||
XipListPrint(list, name_printf);
|
||||
|
||||
for ( i = 0; i< length; i++)
|
||||
printf("get(%d): [%s], [%x]\n", i, (char *)XipListGet(list, i), XipListGet(list, i));
|
||||
|
|
|
|||
|
|
@ -37,10 +37,10 @@
|
|||
typedef struct st_xip_hashmap_node
|
||||
{
|
||||
char * key;
|
||||
union
|
||||
struct
|
||||
{
|
||||
void *ptr; /*注意ptr本身没有分配内存,只是指针*/
|
||||
int num; /*ihashmap使用*/
|
||||
void *ptr; /*注意ptr本身,只是指针*/
|
||||
int size; /*内存大小*/
|
||||
}value;
|
||||
struct st_xip_hashmap_node *next;
|
||||
unsigned int hash;
|
||||
|
|
@ -51,7 +51,7 @@ typedef struct
|
|||
{
|
||||
TxipHashmapNode ** table; /*T表*/
|
||||
unsigned int length; /*桶大小*/
|
||||
unsigned int size; /*实际大小*/
|
||||
unsigned int size; /*实际个数*/
|
||||
unsigned int threshold; /*加载临界值*/
|
||||
int malloc_flag; /*是否为value分配内存*/
|
||||
float factor; /*加载因子,默认为0.75(0-1)*/
|
||||
|
|
@ -115,8 +115,8 @@ int XipHashmapPrint( void * hashmap, void (*ref_func)(int,char *, void *))
|
|||
next = e->next;
|
||||
if( ref_func == NULL)
|
||||
{
|
||||
HMAPLOG("I", "Node[%d]:hash[%d],key[%s],value[%x][%s]",
|
||||
idx, e->hash, e->key, e->value.ptr, (char *)e->value.ptr);
|
||||
HMAPLOG("I", "Node[%d]:hash[%d],key[%s],value[%d][%x][%s]",
|
||||
idx, e->hash, e->key, e->value.size, e->value.ptr, (char *)e->value.ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -146,7 +146,93 @@ int XipHashmapPrint( void * hashmap, void (*ref_func)(int,char *, void *))
|
|||
|
||||
return 0;
|
||||
}
|
||||
/********************************************************************
|
||||
* 函数名称: XipHashmapGetNum
|
||||
* 函数功能: 输出hashmap中的key:value对的个数
|
||||
* 函数作者: icesky
|
||||
* 创建日期: 2016.08.04
|
||||
* 调用说明: 外部调用函数,参见xiphashmap.h中描述
|
||||
*********************************************************************/
|
||||
int XipHashmapNum( void * hashmap)
|
||||
{
|
||||
TxipHashmap * map = ( TxipHashmap *)hashmap;
|
||||
if( map == NULL)
|
||||
return 0;
|
||||
|
||||
return map->size;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* 函数名称: XipHashmapGetSize
|
||||
* 函数功能: 打印hashmap中所有的元素,主要用于调试和检查散列分布
|
||||
* 函数作者: icesky
|
||||
* 创建日期: 2016.07.28
|
||||
* 调用说明: 外部调用函数,参见xiphashmap.h中描述
|
||||
*********************************************************************/
|
||||
int XipHashmapSize( void * hashmap, int * mapsize, int * tablesize, int * nodesize, int * keysize, int * valuesize)
|
||||
{
|
||||
TxipHashmap * map = ( TxipHashmap *)hashmap;
|
||||
if( map == NULL)
|
||||
return 0;
|
||||
|
||||
int total_size = 0; /*总内存大小*/
|
||||
int map_size = 0; /*map结构体大小*/
|
||||
int table_size = 0; /*散列表大小*/
|
||||
int node_size = 0; /*总节点大小*/
|
||||
int key_size = 0; /*总key大小--当不分配内存为0*/
|
||||
int value_size = 0; /*总值大小--当不分配内存为0*/
|
||||
|
||||
int idx = 0;
|
||||
|
||||
map_size = sizeof(TxipHashmap);
|
||||
table_size = sizeof(TxipHashmapNode*) * map->length;
|
||||
|
||||
TxipHashmapNode * e = NULL;
|
||||
TxipHashmapNode * next = NULL;
|
||||
if( map != NULL)
|
||||
{
|
||||
for( idx = 0; idx < map->length; idx++)
|
||||
{
|
||||
for( e= map->table[idx] ; e!= NULL; )
|
||||
{
|
||||
next = e->next;
|
||||
/*计算大小*/
|
||||
node_size += sizeof(TxipHashmapNode);
|
||||
if ( map->malloc_flag == MALLOC_FLAG_NO) /*不分配内存*/
|
||||
{
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
key_size += strlen(e->key)+1;
|
||||
value_size += e->value.size;
|
||||
}
|
||||
|
||||
e = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
total_size = map_size + table_size + node_size + key_size + value_size;
|
||||
|
||||
HMAPLOG("D","total_size[%d] = map_size[%d]+table_size[%d]+node_size[%d]+key_size[%d]+value_size[%d]",
|
||||
total_size, map_size, table_size, node_size, key_size, value_size);
|
||||
|
||||
if( mapsize != NULL)
|
||||
*mapsize = map_size;
|
||||
if( tablesize != NULL)
|
||||
*tablesize = table_size;
|
||||
if( nodesize != NULL)
|
||||
*nodesize = node_size;
|
||||
if( keysize != NULL)
|
||||
*keysize = key_size;
|
||||
if( valuesize != NULL)
|
||||
*valuesize = value_size;
|
||||
|
||||
|
||||
return total_size;
|
||||
}
|
||||
/********************************************************************
|
||||
* 函数名称: XipHashmapNew
|
||||
* 函数功能: 以所有的默认参数,创建一个hashmap
|
||||
|
|
@ -322,10 +408,12 @@ void * XipHashmapPut( void * hashmap, char * key, void * value, int size)
|
|||
if( map->malloc_flag == MALLOC_FLAG_NO) /*不分配内存*/
|
||||
{
|
||||
e->value.ptr = value;
|
||||
e->value.size = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
HMAPFREE(e->value.ptr);
|
||||
e->value.size = size;
|
||||
e->value.ptr = NULL;
|
||||
e->value.ptr = hmap_malloc(size);
|
||||
if( e->value.ptr == NULL)
|
||||
|
|
@ -578,6 +666,7 @@ static TxipHashmapNode * create_hashmap_node( char * key, void * value, TxipHash
|
|||
memset(node->key, 0x00, strlen(key)+1);
|
||||
memcpy( node->key, key, strlen(key)+1);
|
||||
|
||||
node->value.size = size;
|
||||
node->value.ptr = hmap_malloc(size);
|
||||
if( node->value.ptr == NULL)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27,13 +27,20 @@
|
|||
#define XIP_LIST_MAX_THRESHOLD 1<<30
|
||||
#define MALLOC_FLAG_NO 1 /*不分配内存*/
|
||||
|
||||
/*element结构*/
|
||||
typedef struct
|
||||
{
|
||||
void * value;
|
||||
int size;
|
||||
} TxipListElement;
|
||||
|
||||
/*list 结构*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned int length; /*实际大小*/
|
||||
unsigned int threshold; /*临界值*/
|
||||
int malloc_flag; /*不分配内存*/
|
||||
void ** ele_table; /*element数组*/
|
||||
unsigned int length; /*实际大小*/
|
||||
unsigned int threshold; /*临界值*/
|
||||
int malloc_flag; /*不分配内存*/
|
||||
TxipListElement * * ele_table; /*element数组*/
|
||||
|
||||
} TxipList;
|
||||
|
||||
|
|
@ -80,12 +87,13 @@ int XipListPrint( void * list, void (*ref_func)(void *))
|
|||
{
|
||||
if( ref_func == NULL)
|
||||
{
|
||||
LISTLOG("I", "Length[%d], Element[%d]:[%x][%s]",
|
||||
lst->length, idx, lst->ele_table[idx], (char * )lst->ele_table[idx]);
|
||||
|
||||
LISTLOG("I", "Length[%d], Element[%d]:[%d]-[%x][%s]",
|
||||
lst->length, idx, lst->ele_table[idx]->size, lst->ele_table[idx]->value, (char * )lst->ele_table[idx]->value);
|
||||
}
|
||||
else
|
||||
{
|
||||
ref_func(lst->ele_table[idx]);
|
||||
ref_func(lst->ele_table[idx]->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -93,6 +101,52 @@ int XipListPrint( void * list, void (*ref_func)(void *))
|
|||
return 0;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* 函数名称: XipListSize
|
||||
* 函数功能: 计算List所占内存的各个大小
|
||||
* 函数作者: icesky
|
||||
* 创建日期: 2016.08.04
|
||||
* 调用说明: 外部调用函数,参见xiplist.h中描述
|
||||
*********************************************************************/
|
||||
int XipListSize( void * list, int *listsize, int *tablesize, int *elesize, int *valuesize)
|
||||
{
|
||||
TxipList * lst = ( TxipList *)list;
|
||||
if( lst == NULL)
|
||||
return 0;
|
||||
|
||||
int total_size = 0;
|
||||
int list_size=0;
|
||||
int table_size = 0;
|
||||
int ele_size = 0;
|
||||
int value_size = 0;
|
||||
|
||||
|
||||
list_size = sizeof(TxipList);
|
||||
table_size = sizeof(TxipListElement *) * lst->threshold;
|
||||
|
||||
unsigned int idx = 0;
|
||||
for ( idx = 0; idx < lst->length; idx++)
|
||||
{
|
||||
ele_size += sizeof(TxipListElement);
|
||||
value_size += lst->ele_table[idx]->size;
|
||||
}
|
||||
|
||||
total_size = list_size + table_size + ele_size + value_size;
|
||||
LISTLOG("D","total_size[%d]=list_size[%d]+table_size[%d]+ele_size[%d]+value_size[%d]",
|
||||
total_size, list_size, table_size, ele_size, value_size);
|
||||
if( listsize != NULL)
|
||||
*listsize = list_size;
|
||||
if( tablesize != NULL)
|
||||
*tablesize = table_size;
|
||||
if( elesize != NULL)
|
||||
*elesize = ele_size;
|
||||
if( valuesize != NULL)
|
||||
*valuesize = ele_size;
|
||||
|
||||
return total_size;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* 函数名称: XipListNew
|
||||
* 函数功能: 以所有的默认参数,创建一个list
|
||||
|
|
@ -119,9 +173,9 @@ void * XipListInit(int malloc_flag)
|
|||
|
||||
lst->length = 0;
|
||||
lst->threshold = XIP_LIST_DEFAULT_THRESHOLD;
|
||||
lst->ele_table = (void * *)list_malloc(sizeof(void *) * lst->threshold);
|
||||
lst->ele_table = (TxipListElement * *)list_malloc(sizeof(TxipListElement *) * lst->threshold);
|
||||
lst->malloc_flag = malloc_flag;
|
||||
memset( lst->ele_table, 0x00, sizeof(void *)* lst->threshold);
|
||||
memset( lst->ele_table, 0x00, sizeof(TxipListElement *)* lst->threshold);
|
||||
|
||||
return (void *)lst;
|
||||
}
|
||||
|
|
@ -145,6 +199,9 @@ int XipListDestory( void * list)
|
|||
{
|
||||
for ( idx = 0; idx < lst->length; idx++)
|
||||
{
|
||||
/* 释放value 空间 */
|
||||
LISTFREE(lst->ele_table[idx]->value);
|
||||
lst->ele_table[idx]->value=NULL;
|
||||
/* 释放element 空间*/
|
||||
LISTFREE(lst->ele_table[idx]);
|
||||
lst->ele_table[idx] = NULL;
|
||||
|
|
@ -183,10 +240,10 @@ void * XipListAdd( void * list, void * element, unsigned int size)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
e = lst->ele_table[lst->length];
|
||||
if( e != NULL)
|
||||
if( lst->ele_table[lst->length] != NULL)
|
||||
{
|
||||
LISTLOG("E","要放入的指针不为空,请检查列表状态![%x],长度[%d],临界值[%d]", e, lst->length, lst->threshold);
|
||||
LISTLOG("E","要放入的指针不为空,请检查列表状态![%x],长度[%d],临界值[%d]",
|
||||
lst->ele_table[lst->length], lst->length, lst->threshold);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -196,9 +253,17 @@ void * XipListAdd( void * list, void * element, unsigned int size)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
lst->ele_table[lst->length] = (TxipListElement *)list_malloc(sizeof(TxipListElement));
|
||||
if( lst->ele_table[lst->length] == NULL)
|
||||
{
|
||||
LISTLOG("E","分配TxipListElement节点失败!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( lst->malloc_flag == MALLOC_FLAG_NO) /*不分配内存*/
|
||||
{
|
||||
lst->ele_table[lst->length] = element;
|
||||
lst->ele_table[lst->length]->value = element;
|
||||
lst->ele_table[lst->length]->size = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -207,11 +272,15 @@ void * XipListAdd( void * list, void * element, unsigned int size)
|
|||
if( e == NULL)
|
||||
{
|
||||
LISTLOG("E","分配value内存失败!!!");
|
||||
LISTFREE(lst->ele_table[lst->length]);
|
||||
lst->ele_table[lst->length]=NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset( e, 0x00, size);
|
||||
memcpy( e, element, size);
|
||||
lst->ele_table[lst->length] = e;
|
||||
lst->ele_table[lst->length]->value = e;
|
||||
lst->ele_table[lst->length]->size = size;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -229,15 +298,18 @@ void * XipListAdd( void * list, void * element, unsigned int size)
|
|||
}
|
||||
else
|
||||
{
|
||||
LISTFREE(lst->ele_table[lst->length]);
|
||||
lst->ele_table[lst->length] = NULL;
|
||||
LISTFREE(lst->ele_table[lst->length-1]->value);
|
||||
lst->ele_table[lst->length-1]->value = NULL;
|
||||
}
|
||||
|
||||
LISTFREE(lst->ele_table[lst->length-1]);
|
||||
lst->ele_table[lst->length-1]=NULL;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return lst->ele_table[lst->length];
|
||||
return lst->ele_table[lst->length-1]->value;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
|
|
@ -255,7 +327,7 @@ void * XipListGet( void * list, int idx)
|
|||
{
|
||||
if( idx <= lst->length)
|
||||
{
|
||||
return lst->ele_table[idx];
|
||||
return lst->ele_table[idx]->value;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -306,7 +378,7 @@ int XipListThreshold( void * list)
|
|||
static int rebuild_list( TxipList * lst)
|
||||
{
|
||||
register unsigned int i = 0;
|
||||
void * * newtable=NULL;
|
||||
TxipListElement * * newtable=NULL;
|
||||
|
||||
/*如果达到最大了,则不在rebuild*/
|
||||
if( lst->threshold == XIP_LIST_MAX_THRESHOLD)
|
||||
|
|
@ -321,7 +393,7 @@ static int rebuild_list( TxipList * lst)
|
|||
threshold = XIP_LIST_MAX_THRESHOLD;
|
||||
|
||||
/*创建新的ele_table*/
|
||||
newtable = (void * *)list_malloc(sizeof(void *) * threshold);
|
||||
newtable = (TxipListElement * *)list_malloc(sizeof(TxipListElement *) * threshold);
|
||||
|
||||
/*赋值和转移list->ele_table*/
|
||||
for( i = 0; i < lst->length; i++)
|
||||
|
|
|
|||
|
|
@ -121,4 +121,29 @@ int XipHashmapRemove( void * TxipHashmap, char * key);
|
|||
*********************************************************************/
|
||||
int XipHashmapPrint( void * hashmap, void (*ref_func)(int,char *,void *));
|
||||
|
||||
/*********************************************************************
|
||||
* 调用功能: 获取当前hashmap中的key:value键值对的个数
|
||||
* 入口参数: hashmap的指针
|
||||
* 出口参数: 无
|
||||
* 返回值 : 整型个数
|
||||
* 调用说明:
|
||||
*********************************************************************/
|
||||
int XipHashmapNum( void * hashmap );
|
||||
|
||||
/*********************************************************************
|
||||
* 函数功能: 获取当前hashmap所占的各种内存的大小
|
||||
* 入口参数: void * hashmap
|
||||
* 出口参数:
|
||||
* mapsize: hashmap结构的大小,可以为NULL
|
||||
* tablesize: 桶的大小 ,可以为NULL
|
||||
* nodesize: 节点总大小, 可以为NULL
|
||||
* keysize: key的总大小, 可以为NULL
|
||||
* valuesize: value的总大小, 可以为NULL
|
||||
*
|
||||
* 返回值 : int total_size,占用内存总大小
|
||||
* 调用说明:
|
||||
*********************************************************************/
|
||||
int XipHashmapSize( void * hashmap, int * mapsize, int * tablesize, int * nodesize, int * keysize, int * valuesize);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -100,4 +100,19 @@ int XipListLen( void * list);
|
|||
*********************************************************************/
|
||||
int XipListThreshold( void * list);
|
||||
|
||||
/*********************************************************************
|
||||
* 函数功能: 获取当前list所占的各种内存的大小
|
||||
* 入口参数: void * list
|
||||
* 出口参数:
|
||||
* listsize: hashmap结构的大小,可以为NULL
|
||||
* tablesize: 桶的大小 ,可以为NULL
|
||||
* elesize: 节点总大小, 可以为NULL
|
||||
* valuesize: value的总大小, 可以为NULL
|
||||
*
|
||||
* 返回值 : int total_size,占用内存总大小
|
||||
* 调用说明:
|
||||
**********************************************************************/
|
||||
int XipHashmapSize( void * hashmap, int * listsize, int * tablesize, int * elesize, int * valuesize);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue