Try not to let the compiler function parameter optimization, is the best solution, thank you





#include <stdio.h> #include <stdlib.h> #include <stddef.h> #include <stdint.h> #include <string.h> typedef struct ztl_hashmap_kv ztl_hashmap_kv_t; typedef ztl_hashmap_kv_t* ztl_hashmap_kv_p; struct ztl_hashmap_kv{ char* key; size_t value; ztl_hashmap_kv_p next; }; typedef struct ztl_hashmap ztl_hashmap_t; typedef ztl_hashmap_t* ztl_hashmap_p; struct ztl_hashmap{ int size; int capacity; ztl_hashmap_kv_p* array; }; ztl_hashmap_p ztl_hashmap_init(int capacity); void ztl_hashmap_put(ztl_hashmap_p map, char* key, size_t value); size_t ztl_hashmap_get(ztl_hashmap_p map,char* key); size_t ztl_hashmap_remove(ztl_hashmap_p map, char* key); static void ztl_hashmap_resize(ztl_hashmap_p map, int type); void ztl_hashmap_destory(ztl_hashmap_p map); size_t ztl_hashmap_fnv1a(char* buf); ztl_hashmap_p ztl_hashmap_init(int capacity) { ztl_hashmap_p map = calloc(1, sizeof(ztl_hashmap_t)); map->size = 0; map->capacity = capacity; map->array = calloc(capacity, sizeof(ztl_hashmap_kv_p)); return map; } void ztl_hashmap_put(ztl_hashmap_p map, char* key, size_t value) { int hash = ztl_hashmap_fnv1a(key) % map->capacity; ztl_hashmap_kv_p* kvp = map->array + hash; ztl_hashmap_kv_p kv = *kvp; if(kv){ while(kv){ if(0 == strcmp(key, kv->key)){ kv->value = value; return; } if(kv->next){ kv = kv->next; }else{ ztl_hashmap_kv_p nkv = calloc(1, sizeof(ztl_hashmap_kv_t)); nkv->key = key; nkv->value = value; kv->next = nkv; map->size++; break; } } }else{ ztl_hashmap_kv_p nkv = calloc(1, sizeof(ztl_hashmap_kv_t)); nkv->key = key; nkv->value = value; *kvp = nkv; map->size++; } ztl_hashmap_resize(map, 1); } int hashmap_getnum=0; size_t ztl_hashmap_get(ztl_hashmap_p map,char* key) { int hash = ztl_hashmap_fnv1a(key) % map->capacity; ztl_hashmap_kv_p* kvp = map->array+hash; ztl_hashmap_kv_p kv = *kvp; hashmap_getnum = 0; while(kv){ hashmap_getnum++; if(0 == strcmp(key, kv->key)){ printf("hashmap get num: %d\n", hashmap_getnum); return kv->value; } if(kv->next){ kv = kv->next; }else{ break; } } printf("hashmap get num: %d\n", hashmap_getnum); return -1; } size_t ztl_hashmap_remove(ztl_hashmap_p map, char* key) { int hash = ztl_hashmap_fnv1a(key) % map->capacity; ztl_hashmap_kv_p* kvp = map->array+hash; ztl_hashmap_kv_p kv = *kvp; ztl_hashmap_kv_p prev=0; while(kv){ if(0 == strcmp(key, kv->key)){ if(prev){ if(kv->next)prev->next = kv->next; else prev->next = 0; }else{ if(kv->next)*kvp = kv->next; else *kvp = 0; } size_t rv = kv->value; free(kv); map->size--; ztl_hashmap_resize(map, 0); return rv; } if(kv->next){ prev = kv; kv = kv->next; }else{ break; } } return -1; } //扩容与减容 static void ztl_hashmap_resize(ztl_hashmap_p map, int type) { int osiz = map->size; int ocap = map->capacity; ztl_hashmap_kv_p* oarray = map->array; float s = osiz * 1.0; float c = ocap * 1.0; int ncap; if(type){ if(s/c<0.8)return; ncap = ocap*1.51; }else{ if(s/c>0.3)return; ncap = ocap*0.57; } map->size = 0; map->capacity = ncap; map->array = calloc(ncap, sizeof(ztl_hashmap_kv_p)); //printf("ztl_hashmap_resize------->ocap: %d, osiz:%d, s/c: %f\n", ocap, osiz, s/c); for(int i=0; i<ocap; i++){ ztl_hashmap_kv_p okv = *(oarray + i); while(okv){ int hash = ztl_hashmap_fnv1a(okv->key) % map->capacity; ztl_hashmap_kv_p* kvp = map->array + hash; ztl_hashmap_kv_p kv = *kvp; if(kv){ while(kv->next){ kv = kv->next; } kv->next = okv; map->size++; }else{ *kvp = okv; map->size++; } ztl_hashmap_kv_p tkv = okv->next; okv->next = 0; okv = tkv; } } free(oarray); } void ztl_hashmap_destory(ztl_hashmap_p map) { for(int i=0; i<map->capacity; i++){ ztl_hashmap_kv_p kv = *(map->array + i); while(kv){ ztl_hashmap_kv_p tkv = kv->next; free(kv); kv = tkv; } } free(map->array); free(map); } size_t ztl_hashmap_fnv1a(char* buf) { size_t oft = 2166136261U; size_t prm = 16777619U; char* bp = buf; for(; *bp; ++bp) { oft ^= (size_t) *bp; oft *= prm; } return oft; } int main(int argc, char** argv) { ztl_hashmap_p map = ztl_hashmap_init(23); ztl_hashmap_put(map, "长烟一空", 111111); ztl_hashmap_put(map, "上下天光", 222222222); ztl_hashmap_put(map, "一碧万顷", 333333333); ztl_hashmap_put(map, "长烟一空", 7777777); ztl_hashmap_put(map, "abc", 1234); ztl_hashmap_put(map, "aac", 2345); ztl_hashmap_put(map, "acc", 3456); ztl_hashmap_put(map, "acca", 4567); printf("000----hashmap cap: %d, size: %d\n", map->capacity, map->size); int csn = 93; char cs[csn][16]; for(int i=0; i<csn; i++){ sprintf( cs[i], "mapkey%d", i); ztl_hashmap_put(map, cs[i], i+1); } printf("111----hashmap cap: %d, size: %d\n", map->capacity, map->size); printf("pl: %d, pr: %d, pb: %d\n\n", (int)ztl_hashmap_get(map, "长烟一空"), (int)ztl_hashmap_get(map, "上下天光"), (int)ztl_hashmap_get(map, "一碧万顷") ); printf(" %d, %d, %d, %d, %d\n\n", (int)ztl_hashmap_get(map, "abc"), (int)ztl_hashmap_get(map, "aac"), (int)ztl_hashmap_get(map, "acc"), (int)ztl_hashmap_get(map, "acca"), (int)ztl_hashmap_get(map, "mapkey11") ); for(int i=0; i<77; i++){ ztl_hashmap_remove(map, cs[i]); } ztl_hashmap_remove(map, "acca"); printf(" %d, %d, %d, %d, %d\n\n", (int)ztl_hashmap_get(map, "abc"), (int)ztl_hashmap_get(map, "aac"), (int)ztl_hashmap_get(map, "acc"), (int)ztl_hashmap_get(map, "acca"), (int)ztl_hashmap_get(map, "mapkey11") ); printf("-------------------\n"); for(int i=0; i<map->capacity; i++){ ztl_hashmap_kv_p kv = *(map->array + i); while(kv){ printf("%s = %d\n", kv->key, (int)kv->value); kv = kv->next; } } printf("222----hashmap cap: %d, size: %d\n", map->capacity, map->size); ztl_hashmap_destory(map); return 0; }