123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- /* Hash tables for Objective C method dispatch.
- Copyright (C) 1993-2015 Free Software Foundation, Inc.
- This file is part of GCC.
- GCC 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 3, or (at your option)
- any later version.
- GCC 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.
- Under Section 7 of GPL version 3, you are granted additional
- permissions described in the GCC Runtime Library Exception, version
- 3.1, as published by the Free Software Foundation.
- You should have received a copy of the GNU General Public License and
- a copy of the GCC Runtime Library Exception along with this program;
- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
- <http://www.gnu.org/licenses/>. */
- /* You need to include this file after including objc.h */
- #ifndef __hash_INCLUDE_GNU
- #define __hash_INCLUDE_GNU
- #include <stddef.h>
- #include <string.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; /* Pointer to next entry on the list.
- NULL indicates end of list. */
- const void *key; /* Key used to locate the value. Used
- to locate value when more than one
- key computes the same hash
- value. */
- void *value; /* Value stored for the key. */
- } *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
- * objc_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
- {
- /* Variables used to implement the hash itself. */
- node_ptr *node_table; /* Pointer to an array of hash nodes. */
- /* Variables used to track the size of the hash table so to determine
- when to resize it. */
- unsigned int size; /* Number of buckets allocated for the hash table
- (number of array entries allocated for
- "node_table"). Must be a power of two. */
- unsigned int used; /* Current number of entries in the hash table. */
- unsigned int mask; /* Precomputed mask. */
- /* Variables used to implement indexing through the hash table. */
- unsigned int last_bucket; /* 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. */
- hash_func_type hash_func;
- /* Function used to compare two hash keys to see if they are equal. */
- compare_func_type compare_func;
- } *cache_ptr;
- /* Allocate and initialize a hash table. */
- cache_ptr objc_hash_new (unsigned int size,
- hash_func_type hash_func,
- compare_func_type compare_func);
-
- /* Deallocate all of the hash nodes and the cache itself. */
- void objc_hash_delete (cache_ptr cache);
- /* Add the key/value pair to the hash table. If the
- hash table reaches a level of fullness then it will be resized.
-
- assert if the key is already in the hash. */
- void objc_hash_add (cache_ptr *cachep, const void *key, void *value);
-
- /* Remove the key/value pair from the hash table.
- assert if the key isn't in the table. */
- void objc_hash_remove (cache_ptr cache, const void *key);
- /* 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
- be extracted. */
- node_ptr objc_hash_next (cache_ptr cache, node_ptr node);
- /* Used to return a value from a hash table using a given key. */
- void *objc_hash_value_for_key (cache_ptr cache, const void *key);
- /* Used to determine if the given key exists in the hash table */
- BOOL objc_hash_is_key_in_hash (cache_ptr cache, const void *key);
- /************************************************
- Useful hashing functions.
-
- Declared inline for your pleasure.
-
- ************************************************/
- /* Calculate a hash code by performing some
- manipulation of the key pointer. (Use the lowest bits
- except for those likely to be 0 due to alignment.) */
- static inline unsigned int
- objc_hash_ptr (cache_ptr cache, const void *key)
- {
- return ((size_t)key / sizeof (void *)) & cache->mask;
- }
- /* Calculate a hash code by iterating over a NULL
- terminate string. */
- static inline unsigned int
- objc_hash_string (cache_ptr cache, const void *key)
- {
- unsigned int ret = 0;
- unsigned int ctr = 0;
- const char *ckey = (const char *) key;
-
- while (*ckey) {
- ret ^= *ckey++ << ctr;
- ctr = (ctr + 1) % sizeof (void *);
- }
- return ret & cache->mask;
- }
- /* Compare two pointers for equality. */
- static inline int
- objc_compare_ptrs (const void *k1, const void *k2)
- {
- return (k1 == k2);
- }
- /* Compare two strings. */
- static inline int
- objc_compare_strings (const void *k1, const void *k2)
- {
- if (k1 == k2)
- return 1;
- else if (k1 == 0 || k2 == 0)
- return 0;
- else
- return ! strcmp ((const char *) k1, (const char *) k2);
- }
- #endif /* not __hash_INCLUDE_GNU */
|