⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hash.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
{	register Hash	hash;		/* New hash table */	register int	slots;		/* Number of slots */	if (check != 7){		fprintf(stderr, "HASH_CREATE: Wrong number of arguments\n");		exit(1);	}	/* Number of slots must be a power of two. */	slots = 1;	while (slots < size)		slots <<= 1;	hash = (Hash)memory_allocate(sizeof *hash);	hash->count = 0;		hash->key_empty = key_empty;	hash->key_equal = (key_equal != NULL) ? key_equal : nse_hash_int_equal;	hash->key_hash = (key_hash != NULL) ? key_hash : nse_hash_int_hash;	hash->key_insert =		(key_insert != NULL) ? key_insert : nse_hash_int_insert;	hash->value_empty = value_empty;	hash->value_insert =		(value_insert != NULL) ? value_insert : nse_hash_int_insert;	nse_hash_initialize(hash, slots);	return hash;}/* * nse_hash_destroy(hash, key_destroy, value_destroy) will deallocate the  * storage * associated with Hash.  Each key-value pair in Hash will be destroyed by * calling Key_Destroy(Key) and Value_Destroy(Value).  If Key_Destroy is NULL, * it will not be called.  Likewise, if Value_Destroy is NULL, it will not * be called. */voidnse_hash_destroy(hash, key_destroy, value_destroy)	register Hash		hash;		/* Hash table to destroy */	register Void_routine	key_destroy;	/* Key destroy routine */	register Void_routine	value_destroy;	/* Value destroy routine */{	register Bucket	bucket;			/* Current bucket */	register Bucket	*bucket_pointer;	/* Pointer into bucket array */	register int	slots;			/* Number of slots */	bucket_pointer = hash->buckets;	for (slots = hash->slots; slots > 0; slots--){		bucket = *bucket_pointer++;		while ((unsigned)bucket > SPECIAL){			if (key_destroy != NULL)				key_destroy(bucket->key);			if (value_destroy != NULL)				value_destroy(bucket->value);			bucket_deallocate(bucket);			bucket = bucket->next;		}	}	data_deallocate((int *)hash->buckets, hash->slots);	memory_deallocate((char *)hash, sizeof *hash);}/* * nse_hash_full_insert(hash, key, value, key_pointer, value_pointer) * =>{True, False} will insert Key-Value into Hash.  If Key is already in * Hash, the key and value already in Hash will not be affected and True will * be returned.  If Key is not already in Hash, Key and Value are inserted * into Hash and False is returned.  If Key_Pointer is non-NULL, *Key_Pointer * will be assigned the key stored in Hash.  If Value_pointer is non-NULL, * *Value_Pointer will be assigend the value stored in Hash. *//* VARARGS1 */bool_tnse_hash_full_insert(hash, key, value, key_pointer, value_pointer)	register Hash	hash;		/* Hash table */	int		key;		/* Key to lookup */	int		value;		/* Value to store */	int		*key_pointer;	/* Place to store key */	int		*value_pointer;	/* Place to store value */{	return nse_hash_access(hash, key, value, True, False, 	    (Void_routine)NULL, key_pointer, value_pointer);}/* * nse_hash_full_lookup(hash, key, key_pointer, value_pointer)=>{True, False}  * will find the key-value pair associated with Key in Hash.  If Key is in  * Hash, the * key stored with Hash will be returned in *Key_Pointer, the value stored with * Hash will be returned in *Value_Pointer, and True will be returned.  If Key * is not in Hash, the empty key will be stored into *Key_Pointer, the empty * value will be stored into *Value_Pointer.  If Key_Pointer is NULL, no key * will be stored into it.  If Value_Pointer is NULL, no value will be stored * into it. *//* VARARGS1 */bool_tnse_hash_full_lookup(hash, key, key_pointer, value_pointer)	register Hash	hash;		/* Hash table */	int		key;		/* Key to lookup */	int		*key_pointer;	/* Place to store key */	int		*value_pointer;	/* Place to store value */{	return nse_hash_access(hash, key, 0, False, False, (Void_routine)NULL,	    key_pointer, value_pointer);}/* * nse_hash_full_replace(hash, key, value, key_pointer, value_pointer) * =>{True, False} will insert Key-Value into Hash.  If Key is already in * Hash, the key and value will just be replaced and True will be returned. *  If Key is not already in Hash, Key and Value are inserted into Hash and * False is returned.  If Key_Pointer is non-NULL, *Key_Pointer will be * assigned the key stored in Hash.  If Value_pointer is non-NULL, * *Value_Pointer will be assigend the value stored in Hash. *//* VARARGS1 */bool_tnse_hash_full_replace(hash, key, value, key_pointer, value_pointer)	register Hash	hash;		/* Hash table */	int		key;		/* Key to lookup */	int		value;		/* Value to store */	int		*key_pointer;	/* Place to store key */	int		*value_pointer;	/* Place to store value */{	return nse_hash_access(hash, key, value, True, True, (Void_routine)NULL,	    key_pointer, value_pointer);}/* * nse_hash_get(Hash, Key)=>Value will lookup the value for Key in Hash.  If Key * is not in Hash, a fatal error occurs. *//* VARARGS1 */intnse_hash_get(hash, key)	register Hash	hash;	/* Hash table */	int		key;	/* Key to lookup */{	int		value;	/* Return value */	if (nse_hash_access(hash,	    key, 0, False, False, (Void_routine)NULL, (int *)NULL, &value))		return value;	else {		fprintf(stderr,			"HASH_GET:Could not find key (0x%x) in table (0x%x)\n",			key, hash);		exit(1);		/* NOTREACHED */	}}#ifdef UNUSED/* * nse_hash_histogram(hash, histogram, size) will scan through Hash generating * a histogram of the bucket length and storing the result into the Size * words starting at Histogram.  The maximum desired histogram value will * be returned. */intnse_hash_histogram(hash, histogram, size)	Hash		hash;		/* Hash table */	register int	*histogram;	/* Place to store histogram */	register int	size;		/* Maximum size of histogram */{	register Bucket	bucket;		/* Current bucket */	register Bucket *buckets;	/* Bucket array */	register int	count;		/* Number of buckets */	register int	maximum;	/* Maximum histogram value */	register int	slots;		/* Slots in bucket array */	bzero((char *)histogram, size * sizeof(int));	buckets = hash->buckets;	maximum = 0;	for (slots = hash->slots; slots > 0; slots--){		count = 0;		for (bucket = *buckets++;		    (unsigned)bucket > SPECIAL; bucket = bucket->next)			count++;		if (count < size)			histogram[count]++;		if (count > maximum)			maximum = count;	}	return maximum;}/* * nse_hash_histogram_display(hash, out_file) will print a histogram of Hash to * Out_File. */voidnse_hash_histogram_display(hash, out_file)	Hash		hash;		/* Hash table */	register FILE	*out_file;	/* Output file */{	register int	*histogram;	/* Histogram */	register int	index;		/* Index into histogram */	register int	size;		/* Histogram size */	size = nse_hash_histogram(hash, (int *)NULL, 0) + 1;	histogram = (int *)memory_allocate(size * sizeof(int));	nse_hash_histogram(hash, histogram, size);	fprintf(out_file, "Length\tCount\n");	for (index = 0; index < size; index++)		fprintf(out_file, "[%d]:\t%d\n", index, histogram[index]);	memory_deallocate((char *)histogram, size * sizeof(int));}#endif/* * nse_hash_insert(hash, key, value)=>{True,False} will attempt to find Key in * Hash.  If Key is already in Hash, True will be returned without affecting * Key's associated value.  Otherwise, Key and Value will be inserted into * Hash and False will be returned. *//* VARARGS1 */bool_tnse_hash_insert(hash, key, value)	register Hash	hash;	/* Hash table */	int		key;	/* Key to insert under */	int		value;	/* Value to insert */{	return nse_hash_access(hash, key, value, True, False, 	    (Void_routine)NULL, (int *)NULL, (int *)NULL);}/* * nse_hash_initialize(Hash, Size) will initialize Hash to contain Size table * entries. */static voidnse_hash_initialize(hash, size)	register Hash	hash;		/* Hash table */	register int	size;		/* Number of slots */{	hash->buckets = (Bucket *)data_allocate(size, (int)EMPTY);	hash->slots = size;	hash->limit = (size << 3) / 10;	hash->mask = size - 1;}/* * nse_hash_int_equal(Int1, Int2) will return True if Int1 equals Int2. */static bool_tnse_hash_int_equal(int1, int2)	int	int1;		/* First integer */	int	int2;		/* Second integer */{	return (bool_t)(int1 == int2);}/* * nse_hash_int_hash(number) will return a hash on number. */static intnse_hash_int_hash(number)	int	number;		/* Number to hash */{	return number;}/* * nse_hash_int_insert(number) will return a copy of number. */static intnse_hash_int_insert(number)	int	number;		/* Number to insert */{	return number;}/* * nse_hash_lookup(Hash, Key)=>value will lookup Key in Hash.  If Key is not * in Hash, Empty_Value will be returned. *//* VARARGS1 */intnse_hash_lookup(hash, key)	register Hash	hash;	/* Hash table */	int		key;	/* Key to lookup */{	int		value;	/* Value with Key */	nse_hash_access(hash, key, 0, False, False, (Void_routine)NULL,	    (int *)NULL, &value);	return value;}#ifdef UNUSED/* * nse_hash_read(hash, in_file, key_read, key_handle, value_read, value_handle) * will read a hash table from In_File into Hash.  Hash must be an empty * that was created in the same what that it was originally written out. * Key_Read(In_File, Key_Handle)=>Key to read a key from In_File and * Value_Read(In_File, Value_Handle, Key)=>Value to read a value from In_File. * The Key that was just read in is passed as the third argument to Value_Read. * If Key_Read or Value_Read are NULL, integer read routines will be used. */voidnse_hash_read(hash, in_file, key_read, key_handle, value_read, value_handle)	register Hash	hash;		/* Hash table to use */	register FILE	*in_file;	/* File to input from */	Int_routine	key_read;	/* Key read routine */	int		key_handle;	/* Key handle */	Int_routine	value_read;	/* Value read routine */	int		value_handle;	/* Value handle */{	register Bucket	bucket;		/* Current bucket */	register Bucket	*buckets;	/* Buckets array pointer */	register int	count;		/* Loop counter */	register int	key;		/* Key */	register int	length;		/* Bucket length */	if (hash->count != 0){		fprintf(stderr, "hash_read: reading into non-empty table\n");		exit(1);	}	data_deallocate((int *)hash->buckets, hash->slots);	read_magic(in_file, HASH_MAGIC);	hash->count = read_word(in_file);	hash->limit = read_word(in_file);	hash->mask = read_word(in_file);	hash->slots = read_word(in_file);	hash->buckets = (Bucket *)data_allocate(hash->slots, (int)EMPTY);	if (key_read == NULL)		key_read = read_word;	if (value_read == NULL)		value_read = read_word;	buckets = hash->buckets;	count = hash->slots;	while (count-- > 0){		length = read_word(in_file);		bucket = NULL;		while (length-- > 0){			if (bucket == NULL){				bucket = bucket_allocate();				*buckets = bucket;			} else {				bucket->next = bucket_allocate();				bucket = bucket->next;			}			bucket->index = read_word(in_file);			key = key_read(in_file, key_handle);			bucket->key = key;			bucket->value = value_read(in_file, value_handle, key);		}		buckets++;	}	read_magic(in_file, HASH_MAGIC);}#endif#ifdef UNUSED/* * nse_hash_rehash(hash, index) will rehash all of the hash table entires that * might conflict with Index in Hash. */static Bucketnse_hash_rehash(hash, index)	register Hash	hash;		/* Hash table to use */	register int	index;		/* Hash index to work on */{	register Bucket	bucket;		/* Current bucket */	register int	count;		/* Number of buckets to check */	register Bucket	*pointer;	/* Current bucket pointer */	Bucket		rehash[32];	/* Number of buckets to rehash */	pointer = rehash;	count = nse_hash_rehash1(hash, index, pointer);	while (count-- > 0){		bucket = *pointer++;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -