亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? hash.c

?? 在VC6環境下開發
?? C
字號:
/*
** This is the implementation of generic hash-tables
** used in eDb.
*/
#include "eDbInit.h"

/* Turn bulk memory into a hash table object by initializing the
** fields of the Hash structure.
**
** "new" is a pointer to the hash table that is to be initialized.
** keyClass is one of the constants eDb_HASH_INT, eDb_HASH_POINTER,
** eDb_HASH_BINARY, or eDb_HASH_STRING.  The value of keyClass 
** determines what kind of key the hash table will use.  "copyKey" is
** true if the hash table should make its own private copy of keys and
** false if it should just use the supplied pointer.  CopyKey only makes
** sense for eDb_HASH_STRING and eDb_HASH_BINARY and is ignored
** for other key classes.
*/
void eDbHashInit(Hash *pHash, int keyClass, int copyKey){
	assert( pHash!=0 );
	assert( keyClass>=eDb_HASH_INT && keyClass<=eDb_HASH_BINARY );
	pHash->keyClass = keyClass;
	pHash->copyKey = copyKey &&
				(keyClass==eDb_HASH_STRING || keyClass==eDb_HASH_BINARY);
	pHash->first = 0;
	pHash->count = 0;
	pHash->htsize = 0;
	pHash->ht = 0;
}

/* Remove all entries from a hash table.  Reclaim all memory.
** Call this routine to delete a hash table or to reset a hash table
** to the empty state.
*/
void eDbHashClear(Hash *pH){
	HashElem *elem;         /* For looping over all elements of the table */
	assert( pH!=0 );
	elem = pH->first;
	pH->first = 0;
	if( pH->ht ) eDbFree(pH->ht);
	pH->ht = 0;
	pH->htsize = 0;
	while( elem ){
		HashElem *next_elem = elem->next;
		if( pH->copyKey && elem->pKey ){
			eDbFree(elem->pKey);
		}
		eDbFree(elem);
		elem = next_elem;
	}
	pH->count = 0;
}

/*
** Hash and comparison functions when the mode is eDb_HASH_INT
*/
static int intHash(const void *pKey, int nKey){
	return nKey ^ (nKey<<8) ^ (nKey>>8);
}
static int intCompare(const void *pKey1, int n1, const void *pKey2, int n2){
	return n2 - n1;
}

#if 0 /* NOT USED */
/*
** Hash and comparison functions when the mode is eDb_HASH_POINTER
*/
static int ptrHash(const void *pKey, int nKey){
	uptr x = Addr(pKey);
	return x ^ (x<<8) ^ (x>>8);
}
static int ptrCompare(const void *pKey1, int n1, const void *pKey2, int n2){
	if( pKey1==pKey2 ) return 0;
	if( pKey1<pKey2 ) return -1;
	return 1;
}
#endif

/*
** Hash and comparison functions when the mode is eDb_HASH_STRING
*/
static int strHash(const void *pKey, int nKey){
	return eDbHashNoCase((const char*)pKey, nKey); 
}
static int strCompare(const void *pKey1, int n1, const void *pKey2, int n2){
	if( n1!=n2 ) return n2-n1;
	return eDbStrNICmp((const char*)pKey1,(const char*)pKey2,n1);
}

/*
** Hash and comparison functions when the mode is eDb_HASH_BINARY
*/
static int binHash(const void *pKey, int nKey){
	int h = 0;
	const char *z = (const char *)pKey;
	while( nKey-- > 0 ){
		h = (h<<3) ^ h ^ *(z++);
	}
	return h & 0x7fffffff;
}
static int binCompare(const void *pKey1, int n1, const void *pKey2, int n2){
	if( n1!=n2 ) return n2-n1;
	return memcmp(pKey1,pKey2,n1);
}

/*
** Return a pointer to the appropriate hash function given the key class.
**
** The C syntax in this function definition may be unfamilar to some 
** programmers, so we provide the following additional explanation:
**
** The name of the function is "hashFunction".  The function takes a
** single parameter "keyClass".  The return value of hashFunction()
** is a pointer to another function.  Specifically, the return value
** of hashFunction() is a pointer to a function that takes two parameters
** with types "const void*" and "int" and returns an "int".
*/
static int (*hashFunction(int keyClass))(const void*,int){
	switch( keyClass ){
		case eDb_HASH_INT:     return &intHash;
		/* case eDb_HASH_POINTER: return &ptrHash; // NOT USED */
		case eDb_HASH_STRING:  return &strHash;
		case eDb_HASH_BINARY:  return &binHash;;
		default: break;
	}
	return 0;
}

/*
** Return a pointer to the appropriate hash function given the key class.
**
** For help in interpreted the obscure C code in the function definition,
** see the header comment on the previous function.
*/
static int (*compareFunction(int keyClass))(const void*,int,const void*,int){
	switch( keyClass ){
		case eDb_HASH_INT:     return &intCompare;
		/* case eDb_HASH_POINTER: return &ptrCompare; // NOT USED */
		case eDb_HASH_STRING:  return &strCompare;
		case eDb_HASH_BINARY:  return &binCompare;
		default: break;
	}
	return 0;
}


/* Resize the hash table so that it cantains "new_size" buckets.
** "new_size" must be a power of 2.  The hash table might fail 
** to resize if eDbMalloc() fails.
*/
static void rehash(Hash *pH, int new_size){
	struct _ht *new_ht;            /* The new hash table */
	HashElem *elem, *next_elem;    /* For looping over existing elements */
	HashElem *x;                   /* Element being copied to new hash table */
	int (*xHash)(const void*,int); /* The hash function */

	assert( (new_size & (new_size-1))==0 );
	new_ht = (struct _ht *)eDbMalloc( new_size*sizeof(struct _ht) );
	if( new_ht==0 ) return;
	if( pH->ht ) eDbFree(pH->ht);
	pH->ht = new_ht;
	pH->htsize = new_size;
	xHash = hashFunction(pH->keyClass);
	for(elem=pH->first, pH->first=0; elem; elem = next_elem){
		int h = (*xHash)(elem->pKey, elem->nKey) & (new_size-1);
		next_elem = elem->next;
		x = new_ht[h].chain;
		if( x ){
			elem->next = x;
			elem->prev = x->prev;
			if( x->prev ) x->prev->next = elem;
			else          pH->first = elem;
			x->prev = elem;
		}else{
			elem->next = pH->first;
			if( pH->first ) pH->first->prev = elem;
			elem->prev = 0;
			pH->first = elem;
		}
		new_ht[h].chain = elem;
		new_ht[h].count++;
	}
}

/* This function (for internal use only) locates an element in an
** hash table that matches the given key.  The hash for this key has
** already been computed and is passed as the 4th parameter.
*/
static HashElem *findElementGivenHash(
	const Hash *pH,     /* The pH to be searched */
	const void *pKey,   /* The key we are searching for */
	int nKey,
	int h               /* The hash for this key. */
){
	HashElem *elem;                /* Used to loop thru the element list */
	int count;                     /* Number of elements left to test */
	int (*xCompare)(const void*,int,const void*,int);  /* comparison function */

	if( pH->ht ){
		elem = pH->ht[h].chain;
		count = pH->ht[h].count;
		xCompare = compareFunction(pH->keyClass);
		while( count-- && elem ){
			if( (*xCompare)(elem->pKey,elem->nKey,pKey,nKey)==0 ){ 
				return elem;
			}
			elem = elem->next;
		}
	}
	return 0;
}

/* Remove a single entry from the hash table given a pointer to that
** element and a hash on the element's key.
*/
static void removeElementGivenHash(
	Hash *pH,         /* The pH containing "elem" */
	HashElem* elem,   /* The element to be removed from the pH */
	int h             /* Hash value for the element */
){
	if( elem->prev ){
		elem->prev->next = elem->next; 
	}else{
		pH->first = elem->next;
	}
	if( elem->next ){
		elem->next->prev = elem->prev;
	}
	if( pH->ht[h].chain==elem ){
		pH->ht[h].chain = elem->next;
	}
	pH->ht[h].count--;
	if( pH->ht[h].count<=0 ){
		pH->ht[h].chain = 0;
	}
	if( pH->copyKey && elem->pKey ){
		eDbFree(elem->pKey);
	}
	eDbFree( elem );
	pH->count--;
}

/* Attempt to locate an element of the hash table pH with a key
** that matches pKey,nKey.  Return the data for this element if it is
** found, or NULL if there is no match.
*/
void *eDbHashFind(const Hash *pH, const void *pKey, int nKey){
	int h;             /* A hash on key */
	HashElem *elem;    /* The element that matches key */
	int (*xHash)(const void*,int);  /* The hash function */

	if( pH==0 || pH->ht==0 ) return 0;
	xHash = hashFunction(pH->keyClass);
	assert( xHash!=0 );
	h = (*xHash)(pKey,nKey);
	assert( (pH->htsize & (pH->htsize-1))==0 );
	elem = findElementGivenHash(pH,pKey,nKey, h & (pH->htsize-1));
	return elem ? elem->data : 0;
}

/* Insert an element into the hash table pH.  The key is pKey,nKey
** and the data is "data".
**
** If no element exists with a matching key, then a new
** element is created.  A copy of the key is made if the copyKey
** flag is set.  NULL is returned.
**
** If another element already exists with the same key, then the
** new data replaces the old data and the old data is returned.
** The key is not copied in this instance.  If a malloc fails, then
** the new data is returned and the hash table is unchanged.
**
** If the "data" parameter to this function is NULL, then the
** element corresponding to "key" is removed from the hash table.
*/
void *eDbHashInsert(Hash *pH, const void *pKey, int nKey, void *data){
	int hraw;             /* Raw hash value of the key */
	int h;                /* the hash of the key modulo hash table size */
	HashElem *elem;       /* Used to loop thru the element list */
	HashElem *new_elem;   /* New element added to the pH */
	int (*xHash)(const void*,int);  /* The hash function */

	assert( pH!=0 );
	xHash = hashFunction(pH->keyClass);
	assert( xHash!=0 );
	hraw = (*xHash)(pKey, nKey);
	assert( (pH->htsize & (pH->htsize-1))==0 );
	h = hraw & (pH->htsize-1);
	elem = findElementGivenHash(pH,pKey,nKey,h);
	if( elem ){
		void *old_data = elem->data;
		if( data==0 ){
			removeElementGivenHash(pH,elem,h);
		}else{
			elem->data = data;
		}
		return old_data;
	}
	if( data==0 ) return 0;
	new_elem = (HashElem*)eDbMalloc( sizeof(HashElem) );
	if( new_elem==0 ) return data;
	if( pH->copyKey && pKey!=0 ){
		new_elem->pKey = eDbMallocRaw( nKey );
		if( new_elem->pKey==0 ){
			eDbFree(new_elem);
			return data;
		}
		memcpy((void*)new_elem->pKey, pKey, nKey);
	}else{
		new_elem->pKey = (void*)pKey;
	}
	new_elem->nKey = nKey;
	pH->count++;
	if( pH->htsize==0 ) rehash(pH,8);
	if( pH->htsize==0 ){
		pH->count = 0;
		eDbFree(new_elem);
		return data;
	}
	if( pH->count > pH->htsize ){
		rehash(pH,pH->htsize*2);
	}
	assert( (pH->htsize & (pH->htsize-1))==0 );
	h = hraw & (pH->htsize-1);
	elem = pH->ht[h].chain;
	if( elem ){
		new_elem->next = elem;
		new_elem->prev = elem->prev;
		if( elem->prev ){
			elem->prev->next = new_elem;
		}else{
			pH->first = new_elem;
		}
		elem->prev = new_elem;
	}else{
		new_elem->next = pH->first;
		new_elem->prev = 0;
		if( pH->first ){
			pH->first->prev = new_elem;
		}
		pH->first = new_elem;
	}
	pH->ht[h].count++;
	pH->ht[h].chain = new_elem;
	new_elem->data = data;
	return 0;
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲精品福利视频网站| 国产成人aaa| 亚洲黄一区二区三区| 国产精品第四页| 亚洲国产精品99久久久久久久久| 亚洲精品在线电影| 国产亚洲欧美日韩俺去了| 26uuu国产在线精品一区二区| 日韩色在线观看| 欧美成人三级在线| 国产日韩欧美一区二区三区乱码| 2023国产一二三区日本精品2022| 亚洲精品一区二区三区影院| 2023国产精品自拍| 精品欧美乱码久久久久久1区2区| 国产一二精品视频| 蜜乳av一区二区三区| 日本成人在线看| 久久草av在线| 成a人片国产精品| 欧美影院午夜播放| 精品日韩一区二区| 综合久久一区二区三区| 亚洲一区二区不卡免费| 日韩成人免费看| 国产不卡高清在线观看视频| 91影视在线播放| 51精品久久久久久久蜜臀| 久久综合色一综合色88| 亚洲欧美日韩久久精品| 日韩1区2区日韩1区2区| 高清av一区二区| 欧美吻胸吃奶大尺度电影| 精品免费国产一区二区三区四区| 国产亚洲欧美日韩日本| 午夜久久福利影院| 成人av午夜影院| 3d成人h动漫网站入口| 中文字幕av资源一区| 日韩精品欧美精品| 北岛玲一区二区三区四区| 日韩一区二区三区观看| 中文字幕亚洲电影| 久久精品国产在热久久| 在线中文字幕一区二区| 国产欧美日本一区二区三区| 亚洲电影欧美电影有声小说| 国产69精品久久99不卡| 91精品国产91综合久久蜜臀| 亚洲日本乱码在线观看| 国产精品一级片| 678五月天丁香亚洲综合网| 亚洲天天做日日做天天谢日日欢| 激情另类小说区图片区视频区| 欧美性videosxxxxx| 欧美国产1区2区| 国产一区欧美二区| 欧美疯狂性受xxxxx喷水图片| 成人免费在线视频观看| 国产精品影视在线观看| 一区视频在线播放| 国产一区二区伦理| 日韩精品一区二区三区中文精品| 亚洲另类色综合网站| 成人国产在线观看| 国产精品久久久久国产精品日日| 国产在线播放一区| 精品久久久三级丝袜| 日本不卡视频在线| 欧美一级一区二区| 麻豆精品久久久| 欧美变态凌虐bdsm| 国内外成人在线| 日韩欧美一级特黄在线播放| 日本美女一区二区三区视频| 欧美日韩aaaaaa| 日韩精品电影在线观看| 日韩一区二区视频| 久久黄色级2电影| 久久婷婷久久一区二区三区| 久久99精品久久久| 久久精品一区二区三区不卡| 国产经典欧美精品| 亚洲欧美在线aaa| 91蝌蚪porny| 亚洲成人av资源| 欧美sm极限捆绑bd| 国产黄色精品网站| 中文字幕在线观看不卡视频| 99久久综合国产精品| 亚洲综合图片区| 欧美日韩精品一区二区三区蜜桃 | 欧美色视频在线观看| 亚洲国产视频一区二区| 欧美老人xxxx18| 国产自产视频一区二区三区| 国产欧美日韩不卡| 欧美性色欧美a在线播放| 天天影视涩香欲综合网| 国产精品国产三级国产专播品爱网| 97久久人人超碰| 欧美亚洲丝袜传媒另类| 亚洲国产人成综合网站| 欧美一区二区三区日韩视频| 经典三级视频一区| 亚洲精品成人精品456| 欧美一区二区三区免费观看视频 | 国产欧美日韩不卡免费| 一本久道久久综合中文字幕 | 91在线你懂得| 首页国产丝袜综合| 日本一区二区三区高清不卡| 91九色02白丝porn| 国产精品正在播放| 亚洲成人av一区二区| 欧美日韩国产成人在线免费| 欧美成人精品1314www| 91香蕉视频在线| 免费美女久久99| 亚洲日本在线天堂| 久久精品夜夜夜夜久久| 欧美日韩亚洲综合| 成人蜜臀av电影| 麻豆成人久久精品二区三区小说| 日本va欧美va精品| 亚洲天堂成人网| 国产日韩欧美精品在线| 欧美一区二区在线视频| 欧美专区在线观看一区| 国产a精品视频| 久久99精品国产麻豆婷婷 | 99国内精品久久| 狠狠色2019综合网| 丝瓜av网站精品一区二区| 国产精品黄色在线观看| 久久久久久久久免费| 日韩一二三区视频| 91亚洲精品久久久蜜桃网站| 蜜桃久久av一区| 国产欧美视频在线观看| 色婷婷久久久综合中文字幕| 在线免费观看日本一区| 国产传媒日韩欧美成人| 精品亚洲porn| 蜜桃视频一区二区三区在线观看| 一区二区三区中文在线观看| 亚洲视频中文字幕| 中文字幕日韩一区| 日韩理论片在线| 综合分类小说区另类春色亚洲小说欧美| 精品盗摄一区二区三区| 精品乱人伦小说| 久久综合网色—综合色88| 亚洲精品一区二区三区福利| 欧美一区二区三区日韩视频| 欧美精品丝袜久久久中文字幕| 欧美色网一区二区| 欧美日韩成人一区| 欧美一卡二卡在线| wwwwww.欧美系列| 亚洲国产高清不卡| 亚洲欧美一区二区三区极速播放| 国产精品第一页第二页第三页| 综合久久国产九一剧情麻豆| 亚洲女同一区二区| 爽好久久久欧美精品| 美日韩一区二区| 国产精品一区二区久久不卡| 成人av网站免费| 欧美日韩中文国产| 精品区一区二区| 国产精品第五页| 性做久久久久久免费观看欧美| 偷拍与自拍一区| 韩国精品久久久| 91视频.com| 日韩一级二级三级| 国产精品美女久久久久高潮| 亚洲激情自拍偷拍| 麻豆精品久久久| 91在线你懂得| 欧美大黄免费观看| 亚洲欧美激情插| 麻豆91在线看| 色哟哟国产精品| 精品99久久久久久| 亚洲理论在线观看| 狠狠色丁香婷婷综合久久片| 91蜜桃婷婷狠狠久久综合9色| 3atv在线一区二区三区| 国产精品水嫩水嫩| 日韩1区2区3区| 色综合久久综合网97色综合 | 久久99精品国产麻豆婷婷| av亚洲精华国产精华精| 91精品国产入口| 亚洲人成在线播放网站岛国| 免费成人性网站| 欧美在线你懂的| 国产精品免费人成网站|