This commit is contained in:
		| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * $Id: map.c 350 2008-08-29 14:51:04Z baconevi $ | ||||
|  * $Id: map.c 351 2008-08-29 15:02:26Z baconevi $ | ||||
|  * | ||||
|  * {License} | ||||
|  */ | ||||
| @ -24,20 +24,9 @@ | ||||
| #define SIZEOF(x) ASE_SIZEOF(x) | ||||
| #define size_t   ase_size_t | ||||
| #define byte_t   ase_byte_t | ||||
| #define uint_t   ase_uint_t | ||||
| #define mmgr_t   ase_mmgr_t | ||||
|  | ||||
| #define PUB(m)  (m) | ||||
| #define PRIV(m) ((priv_t*)(m+1)) | ||||
|  | ||||
| typedef struct priv_t priv_t; | ||||
|  | ||||
| struct priv_t | ||||
| { | ||||
| 	unsigned int load_factor;  | ||||
| 	size_t threshold; | ||||
| 	pair_t** bucket; | ||||
| }; | ||||
|  | ||||
| static int reorganize (map_t* map); | ||||
|  | ||||
| static size_t hash_key (map_t* map, const void* kptr, size_t klen) | ||||
| @ -196,9 +185,7 @@ static pair_t* change_pair_val ( | ||||
| 	return pair; | ||||
| } | ||||
|  | ||||
| map_t* ase_map_open ( | ||||
| 	mmgr_t* mmgr, size_t ext,  | ||||
| 	size_t capa, unsigned int load_factor) | ||||
| map_t* ase_map_open (mmgr_t* mmgr, size_t ext, size_t capa, uint_t factor) | ||||
| { | ||||
| 	map_t* map; | ||||
|  | ||||
| @ -212,29 +199,43 @@ map_t* ase_map_open ( | ||||
| 		if (mmgr == ASE_NULL) return ASE_NULL; | ||||
| 	} | ||||
|  | ||||
| 	ASE_ASSERTX (capa >= 0,  | ||||
| 		"The initial capacity should be greater than 0"); | ||||
|  | ||||
| 	ASE_ASSERTX (load_factor >= 0 && load_factor <= 100, | ||||
| 		"The load factor should be between 0 and 100 inclusive"); | ||||
|  | ||||
| 	map = ASE_MMGR_ALLOC (mmgr, SIZEOF(map_t)+SIZEOF(priv_t)+ext); | ||||
| 	if (map == ASE_NULL) return ASE_NULL; | ||||
|  | ||||
| 	PRIV(map)->bucket = ASE_MMGR_ALLOC (mmgr, capa*SIZEOF(pair_t*)); | ||||
| 	if (PRIV(map)->bucket == ASE_NULL) | ||||
| 	if (ase_map_init (map, mmgr, capa, factor) == ASE_NULL) | ||||
| 	{ | ||||
| 		ASE_MMGR_FREE (mmgr, map); | ||||
| 		return ASE_NULL; | ||||
| 	} | ||||
|  | ||||
| 	return mmgr; | ||||
| } | ||||
|  | ||||
| void ase_map_close (map_t* map) | ||||
| { | ||||
| 	ase_map_fini (map); | ||||
| 	ASE_MMGR_FREE (map->mmgr, map); | ||||
| } | ||||
|  | ||||
| map_t* ase_map_init (map_t* map, mmgr_t* mmgr, size_t capa, uint_t factor) | ||||
| { | ||||
| 	ASE_ASSERTX (capa >= 0,  | ||||
| 		"The initial capacity should be greater than 0"); | ||||
|  | ||||
| 	ASE_ASSERTX (factor >= 0 && factor <= 100, | ||||
| 		"The load factor should be between 0 and 100 inclusive"); | ||||
|  | ||||
| 	/* do not zero out the extension */ | ||||
| 	ASE_MEMSET (map, 0, SIZEOF(map_t)+SIZEOF(priv_t)); | ||||
| 	ASE_MEMSET (map, 0, SIZEOF(map_t)); | ||||
| 	map->mmgr = mmgr; | ||||
|  | ||||
| 	map->bucket = ASE_MMGR_ALLOC (mmgr, capa*SIZEOF(pair_t*)); | ||||
| 	if (map->bucket == ASE_NULL) | ||||
| 	{ | ||||
| 		ASE_MMGR_FREE (mmgr, map); | ||||
| 		return ASE_NULL; | ||||
| 	} | ||||
|  | ||||
| 	map->size = 0; | ||||
| 	map->capa = capa; | ||||
| 	PRIV(map)->load_factor = load_factor; | ||||
| 	map->factor = factor; | ||||
|  | ||||
| 	map->hasher = hash_key; | ||||
| 	map->comper = comp_key; | ||||
| @ -242,11 +243,10 @@ map_t* ase_map_open ( | ||||
| 	return map; | ||||
| } | ||||
|  | ||||
| void ase_map_close (map_t* map) | ||||
| void ase_map_fini (map_t* map) | ||||
| { | ||||
| 	ase_map_clear (map); | ||||
| 	ASE_MMGR_FREE (map->mmgr, PRIV(map)->bucket); | ||||
| 	ASE_MMGR_FREE (map->mmgr, map); | ||||
| 	ASE_MMGR_FREE (map->mmgr, map->bucket); | ||||
| } | ||||
|  | ||||
| void ase_map_clear (map_t* map) | ||||
| @ -256,7 +256,7 @@ void ase_map_clear (map_t* map) | ||||
|  | ||||
| 	for (i = 0; i < map->capa; i++)  | ||||
| 	{ | ||||
| 		pair = PRIV(map)->bucket[i]; | ||||
| 		pair = map->bucket[i]; | ||||
|  | ||||
| 		while (pair != ASE_NULL)  | ||||
| 		{ | ||||
| @ -266,7 +266,7 @@ void ase_map_clear (map_t* map) | ||||
| 			pair = next; | ||||
| 		} | ||||
|  | ||||
| 		PRIV(map)->bucket[i] = ASE_NULL; | ||||
| 		map->bucket[i] = ASE_NULL; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -322,7 +322,7 @@ void ase_map_setcomper (map_t* map, comper_t comper) | ||||
|  | ||||
| void* ase_map_getextension (map_t* map) | ||||
| { | ||||
| 	return PRIV(map) + 1; | ||||
| 	return map + 1; | ||||
| } | ||||
|  | ||||
| mmgr_t* ase_map_getmmgr (map_t* map) | ||||
| @ -351,7 +351,7 @@ pair_t* ase_map_search (map_t* map, const void* kptr, size_t klen) | ||||
| 	size_t hc; | ||||
|  | ||||
| 	hc = map->hasher(map,kptr,klen) % map->capa; | ||||
| 	pair = PRIV(map)->bucket[hc]; | ||||
| 	pair = map->bucket[hc]; | ||||
|  | ||||
| 	while (pair != ASE_NULL)  | ||||
| 	{ | ||||
| @ -374,7 +374,7 @@ int ase_map_put ( | ||||
| 	size_t hc; | ||||
|  | ||||
| 	hc = map->hasher(map,kptr,klen) % map->capa; | ||||
| 	pair = PRIV(map)->bucket[hc]; | ||||
| 	pair = map->bucket[hc]; | ||||
| 	prev = ASE_NULL; | ||||
|  | ||||
| 	while (pair != ASE_NULL)  | ||||
| @ -388,7 +388,7 @@ int ase_map_put ( | ||||
| 			if (p != pair)  | ||||
| 			{ | ||||
| 				/* the pair has been reallocated. relink it */ | ||||
| 				if (prev == ASE_NULL) PRIV(map)->bucket[hc] = p; | ||||
| 				if (prev == ASE_NULL) map->bucket[hc] = p; | ||||
| 				else NEXT(prev) = p; | ||||
| 				NEXT(p) = next; | ||||
| 			} | ||||
| @ -401,7 +401,7 @@ int ase_map_put ( | ||||
| 		pair = next; | ||||
| 	} | ||||
|  | ||||
| 	if (PRIV(map)->threshold > 0 && map->size >= PRIV(map)->threshold) | ||||
| 	if (map->threshold > 0 && map->size >= map->threshold) | ||||
| 	{ | ||||
| 		if (reorganize(map) == 0) /* ignore the error */ | ||||
| 		{ | ||||
| @ -414,8 +414,8 @@ int ase_map_put ( | ||||
| 	pair = alloc_pair (map, kptr, klen, vptr, vlen); | ||||
| 	if (pair == ASE_NULL) return -1; /* error */ | ||||
|  | ||||
| 	NEXT(pair) = PRIV(map)->bucket[hc]; | ||||
| 	PRIV(map)->bucket[hc] = pair; | ||||
| 	NEXT(pair) = map->bucket[hc]; | ||||
| 	map->bucket[hc] = pair; | ||||
| 	map->size++; | ||||
|  | ||||
| 	if (px != ASE_NULL) *px = pair; | ||||
| @ -441,7 +441,7 @@ pair_t* ase_map_insert ( | ||||
| 	size_t hc; | ||||
|  | ||||
| 	hc = map->hasher(map,kptr,klen) % map->capa; | ||||
| 	pair = PRIV(map)->bucket[hc]; | ||||
| 	pair = map->bucket[hc]; | ||||
|  | ||||
| 	while (pair != ASE_NULL)  | ||||
| 	{ | ||||
| @ -453,7 +453,7 @@ pair_t* ase_map_insert ( | ||||
| 		pair = NEXT(pair); | ||||
| 	} | ||||
|  | ||||
| 	if (PRIV(map)->threshold > 0 && map->size >= PRIV(map)->threshold) | ||||
| 	if (map->threshold > 0 && map->size >= map->threshold) | ||||
| 	{ | ||||
| 		if (reorganize(map) == 0) /* ignore the error */ | ||||
| 		{ | ||||
| @ -466,8 +466,8 @@ pair_t* ase_map_insert ( | ||||
| 	pair = alloc_pair (map, kptr, klen, vptr, vlen); | ||||
| 	if (pair == ASE_NULL) return ASE_NULL; | ||||
|  | ||||
| 	NEXT(pair) = PRIV(map)->bucket[hc]; | ||||
| 	PRIV(map)->bucket[hc] = pair; | ||||
| 	NEXT(pair) = map->bucket[hc]; | ||||
| 	map->bucket[hc] = pair; | ||||
| 	map->size++; | ||||
|  | ||||
| 	return pair; | ||||
| @ -480,7 +480,7 @@ pair_t* ase_map_update ( | ||||
| 	size_t hc; | ||||
|  | ||||
| 	hc = map->hasher(map,kptr,klen) % map->capa; | ||||
| 	pair = PRIV(map)->bucket[hc]; | ||||
| 	pair = map->bucket[hc]; | ||||
| 	prev = ASE_NULL; | ||||
|  | ||||
| 	while (pair != ASE_NULL)  | ||||
| @ -495,7 +495,7 @@ pair_t* ase_map_update ( | ||||
| 			if (p != pair)  | ||||
| 			{ | ||||
| 				/* the pair has been reallocated. relink it */ | ||||
| 				if (prev == ASE_NULL) PRIV(map)->bucket[hc] = p; | ||||
| 				if (prev == ASE_NULL) map->bucket[hc] = p; | ||||
| 				else NEXT(prev) = p; | ||||
| 				NEXT(p) = next; | ||||
| 			} | ||||
| @ -516,7 +516,7 @@ int ase_map_delete (map_t* map, const void* kptr, size_t klen) | ||||
| 	size_t hc; | ||||
|  | ||||
| 	hc = map->hasher(map,kptr,klen) % map->capa; | ||||
| 	pair = PRIV(map)->bucket[hc]; | ||||
| 	pair = map->bucket[hc]; | ||||
| 	prev = ASE_NULL; | ||||
|  | ||||
| 	while (pair != ASE_NULL)  | ||||
| @ -524,7 +524,7 @@ int ase_map_delete (map_t* map, const void* kptr, size_t klen) | ||||
| 		if (map->comper (map, KPTR(pair), KLEN(pair), kptr, klen) == 0)  | ||||
| 		{ | ||||
| 			if (prev == ASE_NULL)  | ||||
| 				PRIV(map)->bucket[hc] = NEXT(pair); | ||||
| 				map->bucket[hc] = NEXT(pair); | ||||
| 			else NEXT(prev) = NEXT(pair); | ||||
|  | ||||
| 			free_pair (map, pair); | ||||
| @ -547,7 +547,7 @@ void ase_map_walk (map_t* map, walker_t walker, void* arg) | ||||
|  | ||||
| 	for (i = 0; i < map->capa; i++)  | ||||
| 	{ | ||||
| 		pair = PRIV(map)->bucket[i]; | ||||
| 		pair = map->bucket[i]; | ||||
|  | ||||
| 		while (pair != ASE_NULL)  | ||||
| 		{ | ||||
| @ -565,7 +565,7 @@ pair_t* ase_map_getfirstpair (map_t* map, size_t* buckno) | ||||
|  | ||||
| 	for (i = 0; i < map->capa; i++) | ||||
| 	{ | ||||
| 		pair = PRIV(map)->bucket[i]; | ||||
| 		pair = map->bucket[i]; | ||||
| 		if (pair != ASE_NULL)  | ||||
| 		{ | ||||
| 			*buckno = i; | ||||
| @ -590,7 +590,7 @@ pair_t* ase_map_getnextpair (map_t* map, pair_t* pair, size_t* buckno) | ||||
|  | ||||
| 	for (i = (*buckno)+1; i < map->capa; i++) | ||||
| 	{ | ||||
| 		pair = PRIV(map)->bucket[i]; | ||||
| 		pair = map->bucket[i]; | ||||
| 		if (pair != ASE_NULL)  | ||||
| 		{ | ||||
| 			*buckno = i; | ||||
| @ -615,7 +615,7 @@ static int reorganize (map_t* map) | ||||
| 	if (new_buck == ASE_NULL)  | ||||
| 	{ | ||||
| 		/* reorganization is disabled once it fails */ | ||||
| 		PRIV(map)->threshold = 0; | ||||
| 		map->threshold = 0; | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| @ -623,7 +623,7 @@ static int reorganize (map_t* map) | ||||
|  | ||||
| 	for (i = 0; i < map->capa; i++) | ||||
| 	{ | ||||
| 		pair_t* pair = PRIV(map)->bucket[i]; | ||||
| 		pair_t* pair = map->bucket[i]; | ||||
|  | ||||
| 		while (pair != ASE_NULL)  | ||||
| 		{ | ||||
| @ -640,10 +640,10 @@ static int reorganize (map_t* map) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	ASE_MMGR_FREE (map->mmgr, PRIV(map)->bucket); | ||||
| 	PRIV(map)->bucket = new_buck; | ||||
| 	ASE_MMGR_FREE (map->mmgr, map->bucket); | ||||
| 	map->bucket = new_buck; | ||||
| 	map->capa = new_capa; | ||||
| 	PRIV(map)->threshold = map->capa * PRIV(map)->load_factor / 100; | ||||
| 	map->threshold = map->capa * map->factor / 100; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user