2db2bea5cb
Expect more changes as hash version and other changes are made. From-SVN: r734
275 lines
9.9 KiB
C
275 lines
9.9 KiB
C
/* -*-c-*-
|
|
* This is a general purpose hash object.
|
|
*
|
|
* The hash object used throughout the run-time
|
|
* is an integer hash. The key and data is of type
|
|
* void*. The hashing function converts the key to
|
|
* an integer and computes it hash value.
|
|
*
|
|
* Copyright (C) 1991 Threaded Technologies Inc.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published
|
|
* by the Free Software Foundation; either version 1, or any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should receive a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*
|
|
$Header: /usr/user/dennis_glatting/ObjC/c-runtime/hash/RCS/hash.h,v 0.8 1991/12/10 12:05:28 dennisg Exp dennisg $
|
|
$Author: dennisg $
|
|
$Date: 1991/12/10 12:05:28 $
|
|
$Log: hash.h,v $
|
|
* Revision 0.8 1991/12/10 12:05:28 dennisg
|
|
* Cleaned up file format for a distribution.
|
|
*
|
|
* Revision 0.7 1991/12/03 02:01:23 dennisg
|
|
* fixed assert macro.
|
|
* added memory allocation adjustment macro for hash size allocation.
|
|
*
|
|
* Revision 0.6 1991/11/24 01:20:02 dennisg
|
|
* changed shorts back to ints.
|
|
* the efficiency gained didn't out weight the grossness of the code.
|
|
*
|
|
* Revision 0.5 1991/11/23 22:19:21 dennisg
|
|
* converted some entries in the hash structure from ints to shorts.
|
|
* this was done to use a less expensive division instruction
|
|
* in the hashIndex () routine.
|
|
*
|
|
* Revision 0.4 1991/11/21 22:25:19 dennisg
|
|
* deleted hash mask information from hash struct.
|
|
* changed hashing algorithm. those values are no longer needed.
|
|
*
|
|
* Revision 0.3 1991/11/07 23:23:40 dennisg
|
|
* implemented hash table expansion as suggested by rms.
|
|
*
|
|
* Revision 0.2 1991/11/07 22:30:54 dennisg
|
|
* added copyleft
|
|
*
|
|
* Revision 0.1 1991/10/24 00:45:39 dennisg
|
|
* Initial check in. Preliminary development stage.
|
|
*
|
|
*/
|
|
|
|
|
|
#ifndef _hash_INCLUDE_GNU
|
|
#define _hash_INCLUDE_GNU
|
|
|
|
/* If someone is using a c++
|
|
compiler then adjust the
|
|
types in the file back
|
|
to C. */
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include <assert.h>
|
|
#include <sys/types.h>
|
|
|
|
#include <mutex.h>
|
|
|
|
/*
|
|
* This data structure is used to hold items
|
|
* stored in a hash table. Each node holds
|
|
* a key/value pair.
|
|
*
|
|
* Items in the cache are really of type void*.
|
|
*/
|
|
typedef struct cache_node {
|
|
struct cache_node* nextNode; /* Pointer to next entry on
|
|
the list. NULL indicates
|
|
end of list. */
|
|
void* theKey; /* Key used to locate the
|
|
value. Used to locate
|
|
value when more than one
|
|
key computes the same hash
|
|
value. */
|
|
void* theValue; /* Value stored for the
|
|
key. */
|
|
} CacheNode, *CacheNode_t;
|
|
|
|
|
|
/*
|
|
* This data type is the function that computes a hash code given a key.
|
|
* Therefore, the key can be a pointer to anything and the function specific
|
|
* to the key type.
|
|
*
|
|
* Unfortunately there is a mutual data structure reference problem with this
|
|
* typedef. Therefore, to remove compiler warnings the functions passed to
|
|
* hash_new() will have to be casted to this type.
|
|
*/
|
|
typedef u_int (*HashFunc)(void*, void*);
|
|
|
|
/*
|
|
* This data type is the function that compares two hash keys and returns an
|
|
* integer greater than, equal to, or less than 0, according as the first
|
|
* parameter is lexico-graphically greater than, equal to, or less than the
|
|
* second.
|
|
*/
|
|
|
|
typedef int (*CompareFunc)(void*, void*);
|
|
|
|
|
|
/*
|
|
* This data structure is the cache.
|
|
*
|
|
* It must be passed to all of the hashing routines
|
|
* (except for new).
|
|
*/
|
|
typedef struct cache {
|
|
/*
|
|
* Variables used to implement the
|
|
* hash itself.
|
|
*/
|
|
CacheNode_t (* theNodeTable)[]; /* Pointer to an array of
|
|
hash nodes. */
|
|
/*
|
|
* Variables used to track the size of the hash
|
|
* table so to determine when to resize it.
|
|
*/
|
|
u_int sizeOfHash, /* Number of buckets
|
|
allocated for the hash
|
|
table (number of array
|
|
entries allocated for
|
|
"theNodeTable"). Must be
|
|
a power of two. */
|
|
entriesInHash, /* Current number of entries
|
|
in the hash table. */
|
|
mask; /* Precomputed mask. */
|
|
/*
|
|
* Variables used to implement indexing
|
|
* through the hash table.
|
|
*/
|
|
u_int lastBucket; /* Tracks which entry in the
|
|
array where the last value
|
|
was returned. */
|
|
/* Function used to compute
|
|
a hash code given a key.
|
|
This function is specified
|
|
when the hash table is
|
|
created. */
|
|
HashFunc hashFunc;
|
|
/* Function used to compare
|
|
two hash keys to determine
|
|
if they are equal. */
|
|
CompareFunc compareFunc;
|
|
} Cache, *Cache_t;
|
|
|
|
|
|
/* Prototypes for hash
|
|
functions. */
|
|
/* Allocate and initialize
|
|
a hash table. */
|
|
Cache_t
|
|
hash_new (u_int sizeOfHash, HashFunc aHashFunc, CompareFunc aCompareFunc);
|
|
/* Deallocate all of the
|
|
hash nodes and the cache
|
|
itself. */
|
|
void
|
|
hash_delete (Cache_t theCache);
|
|
/* Add the key/value pair
|
|
to the hash table. If the
|
|
hash table reaches a
|
|
level of fullnes then
|
|
it will be resized.
|
|
|
|
assert() if the key is
|
|
already in the hash. */
|
|
void
|
|
hash_add (Cache_t* theCache, void* aKey, void* aValue);
|
|
/* Remove the key/value pair
|
|
from the hash table.
|
|
assert() if the key isn't
|
|
in the table. */
|
|
void
|
|
hash_remove (Cache_t theCache, void* aKey);
|
|
/* Used to index through the
|
|
hash table. Start with NULL
|
|
to get the first entry.
|
|
|
|
Successive calls pass the
|
|
value returned previously.
|
|
** Don't modify the hash
|
|
during this operation ***
|
|
|
|
Cache nodes are returned
|
|
such that key or value can
|
|
ber extracted. */
|
|
CacheNode_t
|
|
hash_next (Cache_t theCache, CacheNode_t aCacheNode);
|
|
|
|
/* Used to return a value from
|
|
a hash table using a given
|
|
key. */
|
|
void*
|
|
hash_value_for_key (Cache_t theCache, void* aKey);
|
|
|
|
|
|
/************************************************
|
|
|
|
Useful hashing functions.
|
|
|
|
Declared inline for your pleaseure.
|
|
|
|
************************************************/
|
|
|
|
/* Calculate a hash code by
|
|
performing some manipulation
|
|
of the key pointer. */
|
|
static inline u_int
|
|
intHash(Cache_t theCache, void* aKey) {
|
|
|
|
|
|
assert(sizeof (u_int) == sizeof (aKey));
|
|
|
|
return ((u_int)aKey >> (sizeof(void*) - 1)) & theCache->mask ;
|
|
}
|
|
|
|
/* Calculate a hash code by
|
|
iterating over a NULL
|
|
terminate string. */
|
|
static inline u_int
|
|
strHash(Cache_t theCache, void* aKey) {
|
|
|
|
u_int ret = 0;
|
|
u_int ctr = 0;
|
|
|
|
|
|
while(*(char*)aKey) {
|
|
ret ^= *(char*)aKey++ << ctr;
|
|
ctr = (ctr + 1) % sizeof(void*);
|
|
}
|
|
|
|
return ret & theCache->mask ;
|
|
}
|
|
|
|
|
|
/* Compare two integers. */
|
|
static inline int
|
|
intCmp(void* k1, void* k2) {
|
|
|
|
|
|
return !((int)k1 - (int)k2);
|
|
}
|
|
|
|
|
|
/* Compare two strings. */
|
|
static inline int
|
|
strCmp(void* k1, void* k2) {
|
|
|
|
|
|
return !strcmp( k1, k2 );
|
|
}
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|