Signed-off-by: icesky <icesky1stm@sina.com>

master
icesky 2016-08-04 18:52:23 +08:00
parent fc26a04d47
commit 96513af0d5
7 changed files with 245 additions and 30 deletions

View File

@ -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可能导致的内存泄漏问题。

View File

@ -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;
}

View File

@ -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));

View File

@ -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
* : hashmapkey: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)
{

View File

@ -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++)

View File

@ -121,4 +121,29 @@ int XipHashmapRemove( void * TxipHashmap, char * key);
*********************************************************************/
int XipHashmapPrint( void * hashmap, void (*ref_func)(int,char *,void *));
/*********************************************************************
* : hashmapkeyvalue
* : 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

View File

@ -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