mirror of
https://gcc.gnu.org/git/gcc.git
synced 2025-01-21 11:54:28 +08:00
fixed assert macro.
added memory allocation adjustment macro for hash size allocation. From-SVN: r96
This commit is contained in:
parent
c4329e99ba
commit
cb21dc2330
127
gcc/objc/hash.c
127
gcc/objc/hash.c
@ -16,17 +16,21 @@
|
||||
* 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/lib/RCS/hash.c,v 0.7 1991/11/23 22:18:29 dennisg Exp dennisg $
|
||||
$Header: /usr/user/dennis_glatting/ObjC/c-runtime/lib/RCS/hash.c,v 0.8 1991/11/24 01:20:02 dennisg Exp dennisg $
|
||||
$Author: dennisg $
|
||||
$Date: 1991/11/23 22:18:29 $
|
||||
$Date: 1991/11/24 01:20:02 $
|
||||
$Log: hash.c,v $
|
||||
* Revision 0.8 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.7 1991/11/23 22:18:29 dennisg
|
||||
* deleted hashIndex() and moved it to hash-inline.h
|
||||
* converted hash_value_for_key() to a inline and moved it to hash-inline.h.
|
||||
* converted hash_value_for_key () to a inline and moved it to hash-inline.h.
|
||||
*
|
||||
* Revision 0.6 1991/11/21 22:27:06 dennisg
|
||||
* changed hash value calculation.
|
||||
* func name changed from hashValue() to hashIndex(). the
|
||||
* func name changed from hashValue () to hashIndex(). the
|
||||
* func really calculated a index anyway.
|
||||
* changed hash func impl. essentially it was calculating a hash value
|
||||
* from a hash value. this is a implementation thing.
|
||||
@ -35,8 +39,8 @@
|
||||
* converted hashIndex() to a inline.
|
||||
*
|
||||
* Revision 0.4 1991/11/19 12:34:41 dennisg
|
||||
* bug in hash_delete(). It was using void* to obtain nodes to
|
||||
* pass to hash_remove(). The value passed to hash_removed() is a
|
||||
* bug in hash_delete (). It was using void* to obtain nodes to
|
||||
* pass to hash_remove (). The value passed to hash_removed () is a
|
||||
* entry from the node structure rather than the node itself. Using
|
||||
* void* removed compiler checking.
|
||||
* Modified to implement cache expansion.
|
||||
@ -70,78 +74,86 @@
|
||||
These equations are
|
||||
percentages. */
|
||||
#define FULLNESS(cache) \
|
||||
((((cache)->sizeOfHash * 75 ) / 100 ) <= (cache)->entriesInHash)
|
||||
((((cache)->sizeOfHash * 75 ) / 100) <= (cache)->entriesInHash)
|
||||
#define EXPANSION(cache) \
|
||||
(((cache)->sizeOfHash * 175 ) / 100 )
|
||||
|
||||
#define MEMORY_ALLOCATION_ADJUST(i) \
|
||||
((i&0x01)?i:(i-1))
|
||||
|
||||
Cache_t hash_new( u_int sizeOfHash ) {
|
||||
Cache_t hash_new (u_int sizeOfHash) {
|
||||
|
||||
Cache_t retCache;
|
||||
|
||||
|
||||
|
||||
assert( sizeOfHash );
|
||||
assert(sizeOfHash);
|
||||
|
||||
/* Memory is allocated on this
|
||||
machine in even address
|
||||
chunks. Therefore the
|
||||
modulus must be odd. */
|
||||
sizeOfHash = MEMORY_ALLOCATION_ADJUST(sizeOfHash);
|
||||
|
||||
/* Allocate the cache
|
||||
structure. calloc() insures
|
||||
structure. calloc () insures
|
||||
its initialization for
|
||||
default values. */
|
||||
retCache = calloc( 1, sizeof( Cache ));
|
||||
assert( retCache );
|
||||
retCache = calloc (1, sizeof (Cache));
|
||||
assert(retCache);
|
||||
|
||||
/* Allocate the array of
|
||||
buckets for the cache.
|
||||
calloc() initializes all of
|
||||
calloc () initializes all of
|
||||
the pointers to NULL. */
|
||||
retCache->theNodeTable = calloc( sizeOfHash, sizeof( CacheNode_t ));
|
||||
assert( retCache->theNodeTable );
|
||||
retCache->theNodeTable = calloc (sizeOfHash, sizeof (CacheNode_t));
|
||||
assert(retCache->theNodeTable);
|
||||
|
||||
retCache->sizeOfHash = sizeOfHash;
|
||||
retCache->sizeOfHash = sizeOfHash;
|
||||
|
||||
return retCache;
|
||||
}
|
||||
|
||||
|
||||
void hash_delete( Cache_t theCache ) {
|
||||
void hash_delete (Cache_t theCache) {
|
||||
|
||||
CacheNode_t aNode;
|
||||
|
||||
|
||||
/* Purge all key/value pairs
|
||||
from the table. */
|
||||
while( aNode = hash_next( theCache, NULL ))
|
||||
hash_remove( theCache, aNode->theKey );
|
||||
while (aNode = hash_next (theCache, NULL))
|
||||
hash_remove (theCache, aNode->theKey);
|
||||
|
||||
/* Release the array of nodes
|
||||
and the cache itself. */
|
||||
free( theCache->theNodeTable );
|
||||
free( theCache );
|
||||
free (theCache->theNodeTable);
|
||||
free (theCache);
|
||||
}
|
||||
|
||||
|
||||
void hash_add( Cache_t* theCache, void* aKey, void* aValue ) {
|
||||
void hash_add (Cache_t* theCache, void* aKey, void* aValue) {
|
||||
|
||||
u_int indx = hashIndex( *theCache, aKey );
|
||||
CacheNode_t aCacheNode = calloc( 1, sizeof( CacheNode ));
|
||||
u_int indx = hashIndex(*theCache, aKey);
|
||||
CacheNode_t aCacheNode = calloc (1, sizeof (CacheNode));
|
||||
|
||||
|
||||
assert( aCacheNode );
|
||||
assert(aCacheNode);
|
||||
|
||||
/* Initialize the new node. */
|
||||
aCacheNode->theKey = aKey;
|
||||
aCacheNode->theValue = aValue;
|
||||
aCacheNode->nextNode = ( *( *theCache )->theNodeTable )[ indx ];
|
||||
aCacheNode->nextNode = (* (*theCache)->theNodeTable)[ indx ];
|
||||
|
||||
/* Debugging.
|
||||
|
||||
Check the list for another
|
||||
key. */
|
||||
#ifdef DEBUG
|
||||
{ CacheNode_t checkHashNode = ( *( *theCache )->theNodeTable )[ indx ];
|
||||
{ CacheNode_t checkHashNode = (* (*theCache)->theNodeTable)[ indx ];
|
||||
|
||||
while( checkHashNode ) {
|
||||
while (checkHashNode) {
|
||||
|
||||
assert( checkHashNode->theKey != aKey );
|
||||
assert(checkHashNode->theKey != aKey);
|
||||
checkHashNode = checkHashNode->nextNode;
|
||||
}
|
||||
}
|
||||
@ -149,17 +161,17 @@ void hash_add( Cache_t* theCache, void* aKey, void* aValue ) {
|
||||
|
||||
/* Install the node as the
|
||||
first element on the list. */
|
||||
( *( *theCache )->theNodeTable )[ indx ] = aCacheNode;
|
||||
(* (*theCache)->theNodeTable)[ indx ] = aCacheNode;
|
||||
|
||||
/* Bump the number of entries
|
||||
in the cache. */
|
||||
++( *theCache )->entriesInHash;
|
||||
++ (*theCache)->entriesInHash;
|
||||
|
||||
/* Check the hash table's
|
||||
fullness. We're going
|
||||
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
|
||||
expand it.
|
||||
@ -169,20 +181,21 @@ void hash_add( Cache_t* theCache, void* aKey, void* aValue ) {
|
||||
primitive functions thereby
|
||||
increasing its
|
||||
correctness. */
|
||||
Cache_t newCache = hash_new(EXPANSION( *theCache ));
|
||||
CacheNode_t aNode = NULL;
|
||||
Cache_t newCache =
|
||||
hash_new (MEMORY_ALLOCATION_ADJUST( EXPANSION (*theCache)));
|
||||
|
||||
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
|
||||
first hash table to the
|
||||
new one. */
|
||||
while( aNode = hash_next( *theCache, aNode ))
|
||||
hash_add( &newCache, aNode->theKey, aNode->theValue );
|
||||
while (aNode = hash_next (*theCache, aNode))
|
||||
hash_add (&newCache, aNode->theKey, aNode->theValue);
|
||||
|
||||
/* Trash the old cache. */
|
||||
hash_delete( *theCache );
|
||||
hash_delete (*theCache);
|
||||
|
||||
/* Return a pointer to the new
|
||||
hash table. */
|
||||
@ -191,23 +204,23 @@ void hash_add( Cache_t* theCache, void* aKey, void* aValue ) {
|
||||
}
|
||||
|
||||
|
||||
void hash_remove( Cache_t theCache, void* aKey ) {
|
||||
void hash_remove (Cache_t theCache, void* aKey) {
|
||||
|
||||
u_int indx = hashIndex( theCache, aKey );
|
||||
CacheNode_t aCacheNode = ( *theCache->theNodeTable )[ indx ];
|
||||
u_int indx = hashIndex(theCache, aKey);
|
||||
CacheNode_t aCacheNode = (*theCache->theNodeTable)[ indx ];
|
||||
|
||||
|
||||
/* We assume there is an entry
|
||||
in the table. Error if it
|
||||
is not. */
|
||||
assert( aCacheNode );
|
||||
assert(aCacheNode);
|
||||
|
||||
/* Special case. First element
|
||||
is the key/value pair to be
|
||||
removed. */
|
||||
if( aCacheNode->theKey == aKey ) {
|
||||
( *theCache->theNodeTable )[ indx ] = aCacheNode->nextNode;
|
||||
free( aCacheNode );
|
||||
if (aCacheNode->theKey == aKey) {
|
||||
(*theCache->theNodeTable)[ indx ] = aCacheNode->nextNode;
|
||||
free (aCacheNode);
|
||||
} else {
|
||||
/* Otherwise, find the hash
|
||||
entry. */
|
||||
@ -216,13 +229,13 @@ void hash_remove( Cache_t theCache, void* aKey ) {
|
||||
|
||||
do {
|
||||
|
||||
if( aCacheNode->theKey == aKey ) {
|
||||
if (aCacheNode->theKey == aKey) {
|
||||
prevHashNode->nextNode = aCacheNode->nextNode, removed = YES;
|
||||
free( aCacheNode );
|
||||
free (aCacheNode);
|
||||
} else
|
||||
prevHashNode = aCacheNode, aCacheNode = aCacheNode->nextNode;
|
||||
} while( !removed && aCacheNode );
|
||||
assert( removed );
|
||||
} while (!removed && aCacheNode);
|
||||
assert(removed);
|
||||
}
|
||||
|
||||
/* Decrement the number of
|
||||
@ -231,7 +244,7 @@ void hash_remove( Cache_t theCache, void* aKey ) {
|
||||
}
|
||||
|
||||
|
||||
CacheNode_t hash_next( Cache_t theCache, CacheNode_t aCacheNode ) {
|
||||
CacheNode_t hash_next (Cache_t theCache, CacheNode_t aCacheNode) {
|
||||
|
||||
CacheNode_t theCacheNode = aCacheNode;
|
||||
|
||||
@ -240,7 +253,7 @@ CacheNode_t hash_next( Cache_t theCache, CacheNode_t aCacheNode ) {
|
||||
then reset the last node
|
||||
visitied pointer and bucket
|
||||
index. */
|
||||
if( !theCacheNode )
|
||||
if (!theCacheNode)
|
||||
theCache->lastBucket = 0;
|
||||
|
||||
/* If there is a node visited
|
||||
@ -248,8 +261,8 @@ CacheNode_t hash_next( Cache_t theCache, CacheNode_t aCacheNode ) {
|
||||
entry in the same bucket;
|
||||
Otherwise step to the next
|
||||
bucket. */
|
||||
if( theCacheNode )
|
||||
if( theCacheNode->nextNode )
|
||||
if (theCacheNode)
|
||||
if (theCacheNode->nextNode)
|
||||
/* There is a node which
|
||||
follows the last node
|
||||
returned. Step to that node
|
||||
@ -261,15 +274,15 @@ CacheNode_t hash_next( Cache_t theCache, CacheNode_t aCacheNode ) {
|
||||
/* If the list isn't exhausted
|
||||
then search the buckets for
|
||||
other nodes. */
|
||||
if( theCache->lastBucket < theCache->sizeOfHash ) {
|
||||
if (theCache->lastBucket < theCache->sizeOfHash) {
|
||||
/* Scan the remainder of the
|
||||
buckets looking for an entry
|
||||
at the head of the list.
|
||||
Return the first item
|
||||
found. */
|
||||
while( theCache->lastBucket < theCache->sizeOfHash )
|
||||
if(( *theCache->theNodeTable )[ theCache->lastBucket ])
|
||||
return ( *theCache->theNodeTable )[ theCache->lastBucket ];
|
||||
while (theCache->lastBucket < theCache->sizeOfHash)
|
||||
if ((*theCache->theNodeTable)[ theCache->lastBucket ])
|
||||
return (*theCache->theNodeTable)[ theCache->lastBucket ];
|
||||
else
|
||||
++theCache->lastBucket;
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
* void*. The hashing function converts the key to
|
||||
* an integer and computes it hash value.
|
||||
*
|
||||
* Copyright (C) 1991 Threaded Technologies Inc.
|
||||
* 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
|
||||
@ -21,14 +21,18 @@
|
||||
* 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/lib/RCS/hash.h,v 0.5 1991/11/23 22:19:21 dennisg Exp dennisg $
|
||||
$Header: /usr/user/dennis_glatting/ObjC/c-runtime/lib/RCS/hash.h,v 0.6 1991/11/24 01:20:02 dennisg Exp dennisg $
|
||||
$Author: dennisg $
|
||||
$Date: 1991/11/23 22:19:21 $
|
||||
$Date: 1991/11/24 01:20:02 $
|
||||
$Log: hash.h,v $
|
||||
* 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.
|
||||
* in the hashIndex () routine.
|
||||
*
|
||||
* Revision 0.4 1991/11/21 22:25:19 dennisg
|
||||
* deleted hash mask information from hash struct.
|
||||
@ -85,24 +89,25 @@ typedef struct cache_node {
|
||||
* This data structure is the cache.
|
||||
*
|
||||
* It must be passed to all of the hashing routines
|
||||
* (except for new).
|
||||
* (except for new).
|
||||
*/
|
||||
typedef struct cache {
|
||||
/*
|
||||
* Variables used to implement the
|
||||
* hash itself.
|
||||
*/
|
||||
CacheNode_t (* theNodeTable )[]; /* Pointer to an array of
|
||||
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
|
||||
u_int sizeOfHash, /* Number of buckets
|
||||
allocated for the hash
|
||||
table (number of array
|
||||
table (number of array
|
||||
entries allocated for
|
||||
"theNodeTable"). */
|
||||
"theNodeTable"). Must be
|
||||
a power of two. */
|
||||
entriesInHash; /* Current number of entries
|
||||
in ther hash table. */
|
||||
/*
|
||||
@ -119,14 +124,12 @@ typedef struct cache {
|
||||
functions. */
|
||||
/* Allocate and initialize
|
||||
a hash table. Hash table
|
||||
size taken as a parameter.
|
||||
A value of 0 is not
|
||||
allowed. */
|
||||
Cache_t hash_new( u_int sizeOfHash );
|
||||
size taken as a parameter. */
|
||||
Cache_t hash_new (u_int sizeOfHash);
|
||||
/* Deallocate all of the
|
||||
hash nodes and the cache
|
||||
itself. */
|
||||
void hash_delete( Cache_t theCache );
|
||||
void hash_delete (Cache_t theCache);
|
||||
/* Add the key/value pair
|
||||
to the hash table. If the
|
||||
hash table reaches a
|
||||
@ -135,12 +138,12 @@ void hash_delete( Cache_t theCache );
|
||||
|
||||
assert() if the key is
|
||||
already in the hash. */
|
||||
void hash_add( Cache_t* theCache, void* aKey, void* aValue );
|
||||
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 );
|
||||
void hash_remove (Cache_t theCache, void* aKey);
|
||||
/* Used to index through the
|
||||
hash table. Start with NULL
|
||||
to get the first entry.
|
||||
@ -153,7 +156,7 @@ void hash_remove( Cache_t theCache, void* aKey );
|
||||
Cache nodes are returned
|
||||
such that key or value can
|
||||
ber extracted. */
|
||||
CacheNode_t hash_next( Cache_t theCache, CacheNode_t aCacheNode );
|
||||
CacheNode_t hash_next (Cache_t theCache, CacheNode_t aCacheNode);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
Loading…
Reference in New Issue
Block a user