From 96513af0d53dafc1dadd7152a0005902c881e508 Mon Sep 17 00:00:00 2001 From: icesky Date: Thu, 4 Aug 2016 18:52:23 +0800 Subject: [PATCH] Signed-off-by: icesky --- README.md | 5 ++ kmaplib/HashMap_test.c | 13 ++++- kmaplib/List_test.c | 4 +- kmaplib/XipHashMap.c | 101 ++++++++++++++++++++++++++++++++++--- kmaplib/XipList.c | 112 +++++++++++++++++++++++++++++++++-------- kmaplib/xiphashmap.h | 25 +++++++++ kmaplib/xiplist.h | 15 ++++++ 7 files changed, 245 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 01d93f5..f8f3233 100644 --- a/README.md +++ b/README.md @@ -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可能导致的内存泄漏问题。 diff --git a/kmaplib/HashMap_test.c b/kmaplib/HashMap_test.c index 6219864..cad4e54 100644 --- a/kmaplib/HashMap_test.c +++ b/kmaplib/HashMap_test.c @@ -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; } diff --git a/kmaplib/List_test.c b/kmaplib/List_test.c index 8350d0c..c982c83 100644 --- a/kmaplib/List_test.c +++ b/kmaplib/List_test.c @@ -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)); diff --git a/kmaplib/XipHashMap.c b/kmaplib/XipHashMap.c index 4bc48dd..0923ce9 100644 --- a/kmaplib/XipHashMap.c +++ b/kmaplib/XipHashMap.c @@ -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) { diff --git a/kmaplib/XipList.c b/kmaplib/XipList.c index 6778a2f..5c8e9ce 100644 --- a/kmaplib/XipList.c +++ b/kmaplib/XipList.c @@ -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++) diff --git a/kmaplib/xiphashmap.h b/kmaplib/xiphashmap.h index 9293ddd..88068c0 100644 --- a/kmaplib/xiphashmap.h +++ b/kmaplib/xiphashmap.h @@ -121,4 +121,29 @@ int XipHashmapRemove( void * TxipHashmap, char * key); *********************************************************************/ int XipHashmapPrint( void * hashmap, void (*ref_func)(int,char *,void *)); +/********************************************************************* + * ù: ȡǰhashmapеkeyvalueֵԵĸ + * ڲ: 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 diff --git a/kmaplib/xiplist.h b/kmaplib/xiplist.h index 016f672..67b9647 100644 --- a/kmaplib/xiplist.h +++ b/kmaplib/xiplist.h @@ -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