Commit 893cc958 by Dennis Glatting

minor documentation changes.

From-SVN: r2007
parent 4037e7bf
...@@ -25,10 +25,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ...@@ -25,10 +25,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
the executable file might be covered by the GNU General Public License. */ the executable file might be covered by the GNU General Public License. */
/* /*
$Header: /usr/user/dennis_glatting/ObjC/c-runtime/dispatch.common/RCS/hash.c,v 0.12 1992/04/13 11:43:08 dennisg Exp dennisg $ $Header: /usr/user/dennis_glatting/ObjC/c-runtime/dispatch/RCS/hash.c,v 0.13 1992/08/18 04:46:58 dglattin Exp $
$Author: dennisg $ $Author: dglattin $
$Date: 1992/04/13 11:43:08 $ $Date: 1992/08/18 04:46:58 $
$Log: hash.c,v $ $Log: hash.c,v $
* Revision 0.13 1992/08/18 04:46:58 dglattin
* Saving a working version before release.
*
* Revision 0.12 1992/04/13 11:43:08 dennisg * Revision 0.12 1992/04/13 11:43:08 dennisg
* Check in after array version of run-time works. * Check in after array version of run-time works.
* Expect more changes as hash version and other changes are made. * Expect more changes as hash version and other changes are made.
...@@ -110,40 +113,30 @@ hash_new (u_int sizeOfHash, HashFunc aHashFunc, CompareFunc aCompareFunc) { ...@@ -110,40 +113,30 @@ hash_new (u_int sizeOfHash, HashFunc aHashFunc, CompareFunc aCompareFunc) {
Cache_t retCache; Cache_t retCache;
/* Pass me a value greater /* Pass me a value greater than 0 and a power of 2. */
than 0 and a power of 2. */
assert(sizeOfHash); assert(sizeOfHash);
assert( !(sizeOfHash & (sizeOfHash - 1))); assert( !(sizeOfHash & (sizeOfHash - 1)));
/* Allocate the cache /* Allocate the cache structure. calloc () insures
structure. calloc () insures its initialization for default values. */
its initialization for
default values. */
retCache = calloc (1, sizeof (Cache)); retCache = calloc (1, sizeof (Cache));
assert(retCache); assert(retCache);
/* Allocate the array of /* Allocate the array of buckets for the cache.
buckets for the cache. calloc() initializes all of the pointers to NULL. */
calloc() initializes all of
the pointers to NULL. */
retCache->theNodeTable = calloc (sizeOfHash, sizeof (CacheNode_t)); retCache->theNodeTable = calloc (sizeOfHash, sizeof (CacheNode_t));
assert(retCache->theNodeTable); assert(retCache->theNodeTable);
retCache->sizeOfHash = sizeOfHash; retCache->sizeOfHash = sizeOfHash;
/* This should work for all /* This should work for all processor architectures? */
processor architectures? */
retCache->mask = ( sizeOfHash - 1 ); retCache->mask = ( sizeOfHash - 1 );
/* Store the hashing function /* Store the hashing function so that codes can be computed. */
so that codes can be
computed. */
retCache->hashFunc = aHashFunc; retCache->hashFunc = aHashFunc;
/* Store the function that /* Store the function that compares hash keys to
compares hash keys to determine if they are equal. */
determine if they are
equal. */
retCache->compareFunc = aCompareFunc; retCache->compareFunc = aCompareFunc;
return retCache; return retCache;
...@@ -156,13 +149,11 @@ hash_delete (Cache_t theCache) { ...@@ -156,13 +149,11 @@ hash_delete (Cache_t theCache) {
CacheNode_t aNode; CacheNode_t aNode;
/* Purge all key/value pairs /* Purge all key/value pairs from the table. */
from the table. */
while (aNode = hash_next (theCache, NULL)) while (aNode = hash_next (theCache, NULL))
hash_remove (theCache, aNode->theKey); hash_remove (theCache, aNode->theKey);
/* Release the array of nodes /* Release the array of nodes and the cache itself. */
and the cache itself. */
free (theCache->theNodeTable); free (theCache->theNodeTable);
free (theCache); free (theCache);
} }
...@@ -183,9 +174,7 @@ hash_add (Cache_t* theCache, void* aKey, void* aValue) { ...@@ -183,9 +174,7 @@ hash_add (Cache_t* theCache, void* aKey, void* aValue) {
aCacheNode->nextNode = (* (*theCache)->theNodeTable)[ indx ]; aCacheNode->nextNode = (* (*theCache)->theNodeTable)[ indx ];
/* Debugging. /* Debugging.
Check the list for another key. */
Check the list for another
key. */
#ifdef DEBUG #ifdef DEBUG
{ CacheNode_t checkHashNode = (* (*theCache)->theNodeTable)[ indx ]; { CacheNode_t checkHashNode = (* (*theCache)->theNodeTable)[ indx ];
...@@ -197,27 +186,21 @@ hash_add (Cache_t* theCache, void* aKey, void* aValue) { ...@@ -197,27 +186,21 @@ hash_add (Cache_t* theCache, void* aKey, void* aValue) {
} }
#endif #endif
/* Install the node as the /* Install the node as the first element on the list. */
first element on the list. */
(* (*theCache)->theNodeTable)[ indx ] = aCacheNode; (* (*theCache)->theNodeTable)[ indx ] = aCacheNode;
/* Bump the number of entries /* Bump the number of entries in the cache. */
in the cache. */
++ (*theCache)->entriesInHash; ++ (*theCache)->entriesInHash;
/* Check the hash table's /* Check the hash table's fullness. We're going
fullness. We're going to expand if it is above the fullness level. */
to expand if it is above
the fullness level. */
if (FULLNESS (*theCache)) { if (FULLNESS (*theCache)) {
/* The hash table has reached
its fullness level. Time to /* The hash table has reached its fullness level. Time to
expand it. expand it.
I'm using a slow method I'm using a slow method here but is built on other
here but is built on other primitive functions thereby increasing its
primitive functions thereby
increasing its
correctness. */ correctness. */
CacheNode_t aNode = NULL; CacheNode_t aNode = NULL;
Cache_t newCache = hash_new (EXPANSION (*theCache), Cache_t newCache = hash_new (EXPANSION (*theCache),
...@@ -227,17 +210,14 @@ hash_add (Cache_t* theCache, void* aKey, void* aValue) { ...@@ -227,17 +210,14 @@ hash_add (Cache_t* theCache, void* aKey, void* aValue) {
DEBUG_PRINTF (stderr, "Expanding cache %#x from %d to %d\n", DEBUG_PRINTF (stderr, "Expanding cache %#x from %d to %d\n",
*theCache, (*theCache)->sizeOfHash, newCache->sizeOfHash); *theCache, (*theCache)->sizeOfHash, newCache->sizeOfHash);
/* Copy the nodes from the /* Copy the nodes from the first hash table to the new one. */
first hash table to the
new one. */
while (aNode = hash_next (*theCache, aNode)) while (aNode = hash_next (*theCache, aNode))
hash_add (&newCache, aNode->theKey, aNode->theValue); hash_add (&newCache, aNode->theKey, aNode->theValue);
/* Trash the old cache. */ /* Trash the old cache. */
hash_delete (*theCache); hash_delete (*theCache);
/* Return a pointer to the new /* Return a pointer to the new hash table. */
hash table. */
*theCache = newCache; *theCache = newCache;
} }
} }
...@@ -250,20 +230,16 @@ hash_remove (Cache_t theCache, void* aKey) { ...@@ -250,20 +230,16 @@ hash_remove (Cache_t theCache, void* aKey) {
CacheNode_t aCacheNode = (*theCache->theNodeTable)[ indx ]; CacheNode_t aCacheNode = (*theCache->theNodeTable)[ indx ];
/* We assume there is an entry /* We assume there is an entry in the table. Error if it is not. */
in the table. Error if it
is not. */
assert(aCacheNode); assert(aCacheNode);
/* Special case. First element /* Special case. First element is the key/value pair to be removed. */
is the key/value pair to be
removed. */
if ((*theCache->compareFunc)(aCacheNode->theKey, aKey)) { if ((*theCache->compareFunc)(aCacheNode->theKey, aKey)) {
(*theCache->theNodeTable)[ indx ] = aCacheNode->nextNode; (*theCache->theNodeTable)[ indx ] = aCacheNode->nextNode;
free (aCacheNode); free (aCacheNode);
} else { } else {
/* Otherwise, find the hash
entry. */ /* Otherwise, find the hash entry. */
CacheNode_t prevHashNode = aCacheNode; CacheNode_t prevHashNode = aCacheNode;
BOOL removed = NO; BOOL removed = NO;
...@@ -278,8 +254,7 @@ hash_remove (Cache_t theCache, void* aKey) { ...@@ -278,8 +254,7 @@ hash_remove (Cache_t theCache, void* aKey) {
assert(removed); assert(removed);
} }
/* Decrement the number of /* Decrement the number of entries in the hash table. */
entries in the hash table. */
--theCache->entriesInHash; --theCache->entriesInHash;
} }
...@@ -290,55 +265,43 @@ hash_next (Cache_t theCache, CacheNode_t aCacheNode) { ...@@ -290,55 +265,43 @@ hash_next (Cache_t theCache, CacheNode_t aCacheNode) {
CacheNode_t theCacheNode = aCacheNode; CacheNode_t theCacheNode = aCacheNode;
/* If the scan is being started /* If the scan is being started then reset the last node
then reset the last node visitied pointer and bucket index. */
visitied pointer and bucket
index. */
if (!theCacheNode) if (!theCacheNode)
theCache->lastBucket = 0; theCache->lastBucket = 0;
/* If there is a node visited /* If there is a node visited last then check for another
last then check for another entry in the same bucket; Otherwise step to the next bucket. */
entry in the same bucket;
Otherwise step to the next
bucket. */
if (theCacheNode) if (theCacheNode)
if (theCacheNode->nextNode) if (theCacheNode->nextNode)
/* There is a node which /* There is a node which follows the last node
follows the last node returned. Step to that node and retun it. */
returned. Step to that node
and retun it. */
return theCacheNode->nextNode; return theCacheNode->nextNode;
else else
++theCache->lastBucket; ++theCache->lastBucket;
/* If the list isn't exhausted /* If the list isn't exhausted then search the buckets for
then search the buckets for
other nodes. */ other nodes. */
if (theCache->lastBucket < theCache->sizeOfHash) { if (theCache->lastBucket < theCache->sizeOfHash) {
/* Scan the remainder of the /* Scan the remainder of the buckets looking for an entry
buckets looking for an entry at the head of the list. Return the first item found. */
at the head of the list.
Return the first item
found. */
while (theCache->lastBucket < theCache->sizeOfHash) while (theCache->lastBucket < theCache->sizeOfHash)
if ((*theCache->theNodeTable)[ theCache->lastBucket ]) if ((*theCache->theNodeTable)[ theCache->lastBucket ])
return (*theCache->theNodeTable)[ theCache->lastBucket ]; return (*theCache->theNodeTable)[ theCache->lastBucket ];
else else
++theCache->lastBucket; ++theCache->lastBucket;
/* No further nodes were found /* No further nodes were found in the hash table. */
in the hash table. */
return NULL; return NULL;
} else } else
return NULL; return NULL;
} }
/* Given key, return its /*
value. Return NULL if the * Given key, return its value. Return NULL if the
key/value pair isn't in * key/value pair isn't in the hash.
the hash. */ */
void* void*
hash_value_for_key (Cache_t theCache, void* aKey) { hash_value_for_key (Cache_t theCache, void* aKey) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment