Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC 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 2, or (at your option)
any later version.
GNU CC 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 have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
compiled with GCC to produce an executable, this does not cause
the resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License. */
#ifndef __hash_INCLUDE_GNU
#define __hash_INCLUDE_GNU
#include <stddef.h>
#include <objc/objc.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 *next;
NULL indicates end of list. */
const void *key;
to locate value when more than one
key computes the same hash
value. */
void *value;
} *node_ptr;
* 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 unsigned int (*hash_func_type)(void *, const 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 lexicographically greater than, equal to, or less than the
* second.
*/
typedef int (*compare_func_type)(const void *, const void *);
* This data structure is the cache.
*
* It must be passed to all of the hashing routines
* (except for new).
*/
typedef struct cache
{
node_ptr *node_table;
when to resize it. */
unsigned int size;
(number of array entries allocated for
"node_table"). Must be a power of two. */
unsigned int used;
unsigned int mask;
unsigned int last_bucket;
the last value was returned. */
This function is specified when the hash table is created. */
hash_func_type hash_func;
compare_func_type compare_func;
} *cache_ptr;
extern cache_ptr module_hash_table, class_hash_table;
cache_ptr hash_new (unsigned int size,
hash_func_type hash_func,
compare_func_type compare_func);
void hash_delete (cache_ptr cache);
hash table reaches a level of fullness then it will be resized.
assert if the key is already in the hash. */
void hash_add (cache_ptr *cachep, const void *key, void *value);
assert if the key isn't in the table. */
void hash_remove (cache_ptr cache, const void *key);
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
be extracted. */
node_ptr hash_next (cache_ptr cache, node_ptr node);
void *hash_value_for_key (cache_ptr cache, const void *key);
BOOL hash_is_key_in_hash (cache_ptr cache, const void *key);
Useful hashing functions.
Declared inline for your pleasure.
************************************************/
manipulation of the key pointer. (Use the lowest bits
except for those likely to be 0 due to alignment.) */
static inline unsigned int
hash_ptr (cache_ptr cache, const void *key)
{
return ((size_t)key / sizeof (void *)) & cache->mask;
}
terminate string. */
static inline unsigned int
hash_string (cache_ptr cache, const void *key)
{
unsigned int ret = 0;
unsigned int ctr = 0;
while (*(char*)key) {
ret ^= *(char*)key++ << ctr;
ctr = (ctr + 1) % sizeof (void *);
}
return ret & cache->mask;
}
static inline int
compare_ptrs (const void *k1, const void *k2)
{
return !(k1 - k2);
}
static inline int
compare_strings (const void *k1, const void *k2)
{
if (k1 == k2)
return 1;
else if (k1 == 0 || k2 == 0)
return 0;
else
return !strcmp (k1, k2);
}
#endif