xref: /dflybsd-src/contrib/gcc-4.7/libobjc/objc-private/hash.h (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
1*e4b17023SJohn Marino /* Hash tables for Objective C method dispatch.
2*e4b17023SJohn Marino    Copyright (C) 1993, 1995, 1996, 2004, 2009 Free Software Foundation, Inc.
3*e4b17023SJohn Marino 
4*e4b17023SJohn Marino This file is part of GCC.
5*e4b17023SJohn Marino 
6*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify
7*e4b17023SJohn Marino it under the terms of the GNU General Public License as published by
8*e4b17023SJohn Marino the Free Software Foundation; either version 3, or (at your option)
9*e4b17023SJohn Marino any later version.
10*e4b17023SJohn Marino 
11*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful,
12*e4b17023SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
13*e4b17023SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*e4b17023SJohn Marino GNU General Public License for more details.
15*e4b17023SJohn Marino 
16*e4b17023SJohn Marino Under Section 7 of GPL version 3, you are granted additional
17*e4b17023SJohn Marino permissions described in the GCC Runtime Library Exception, version
18*e4b17023SJohn Marino 3.1, as published by the Free Software Foundation.
19*e4b17023SJohn Marino 
20*e4b17023SJohn Marino You should have received a copy of the GNU General Public License and
21*e4b17023SJohn Marino a copy of the GCC Runtime Library Exception along with this program;
22*e4b17023SJohn Marino see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23*e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
24*e4b17023SJohn Marino 
25*e4b17023SJohn Marino /* You need to include this file after including objc.h  */
26*e4b17023SJohn Marino 
27*e4b17023SJohn Marino #ifndef __hash_INCLUDE_GNU
28*e4b17023SJohn Marino #define __hash_INCLUDE_GNU
29*e4b17023SJohn Marino 
30*e4b17023SJohn Marino #include <stddef.h>
31*e4b17023SJohn Marino #include <string.h>
32*e4b17023SJohn Marino 
33*e4b17023SJohn Marino /*
34*e4b17023SJohn Marino  * This data structure is used to hold items
35*e4b17023SJohn Marino  *  stored in a hash table.  Each node holds
36*e4b17023SJohn Marino  *  a key/value pair.
37*e4b17023SJohn Marino  *
38*e4b17023SJohn Marino  * Items in the cache are really of type void *.
39*e4b17023SJohn Marino  */
40*e4b17023SJohn Marino typedef struct cache_node
41*e4b17023SJohn Marino {
42*e4b17023SJohn Marino   struct cache_node *next;	/* Pointer to next entry on the list.
43*e4b17023SJohn Marino 				   NULL indicates end of list. */
44*e4b17023SJohn Marino   const void *key;		/* Key used to locate the value.  Used
45*e4b17023SJohn Marino 				   to locate value when more than one
46*e4b17023SJohn Marino 				   key computes the same hash
47*e4b17023SJohn Marino 				   value. */
48*e4b17023SJohn Marino   void *value;			/* Value stored for the key. */
49*e4b17023SJohn Marino } *node_ptr;
50*e4b17023SJohn Marino 
51*e4b17023SJohn Marino 
52*e4b17023SJohn Marino /*
53*e4b17023SJohn Marino  * This data type is the function that computes a hash code given a key.
54*e4b17023SJohn Marino  * Therefore, the key can be a pointer to anything and the function specific
55*e4b17023SJohn Marino  * to the key type.
56*e4b17023SJohn Marino  *
57*e4b17023SJohn Marino  * Unfortunately there is a mutual data structure reference problem with this
58*e4b17023SJohn Marino  * typedef.  Therefore, to remove compiler warnings the functions passed to
59*e4b17023SJohn Marino  * objc_hash_new will have to be casted to this type.
60*e4b17023SJohn Marino  */
61*e4b17023SJohn Marino typedef unsigned int (*hash_func_type) (void *, const void *);
62*e4b17023SJohn Marino 
63*e4b17023SJohn Marino /*
64*e4b17023SJohn Marino  * This data type is the function that compares two hash keys and returns an
65*e4b17023SJohn Marino  * integer greater than, equal to, or less than 0, according as the first
66*e4b17023SJohn Marino  * parameter is lexicographically greater than, equal to, or less than the
67*e4b17023SJohn Marino  * second.
68*e4b17023SJohn Marino  */
69*e4b17023SJohn Marino 
70*e4b17023SJohn Marino typedef int (*compare_func_type) (const void *, const void *);
71*e4b17023SJohn Marino 
72*e4b17023SJohn Marino 
73*e4b17023SJohn Marino /*
74*e4b17023SJohn Marino  * This data structure is the cache.
75*e4b17023SJohn Marino  *
76*e4b17023SJohn Marino  * It must be passed to all of the hashing routines
77*e4b17023SJohn Marino  *   (except for new).
78*e4b17023SJohn Marino  */
79*e4b17023SJohn Marino typedef struct cache
80*e4b17023SJohn Marino {
81*e4b17023SJohn Marino   /* Variables used to implement the hash itself.  */
82*e4b17023SJohn Marino   node_ptr *node_table; /* Pointer to an array of hash nodes.  */
83*e4b17023SJohn Marino   /* Variables used to track the size of the hash table so to determine
84*e4b17023SJohn Marino     when to resize it.  */
85*e4b17023SJohn Marino   unsigned int size; /* Number of buckets allocated for the hash table
86*e4b17023SJohn Marino 			(number of array entries allocated for
87*e4b17023SJohn Marino 			"node_table").  Must be a power of two.  */
88*e4b17023SJohn Marino   unsigned int used; /* Current number of entries in the hash table.  */
89*e4b17023SJohn Marino   unsigned int mask; /* Precomputed mask.  */
90*e4b17023SJohn Marino 
91*e4b17023SJohn Marino   /* Variables used to implement indexing through the hash table.  */
92*e4b17023SJohn Marino 
93*e4b17023SJohn Marino   unsigned int last_bucket; /* Tracks which entry in the array where
94*e4b17023SJohn Marino 			       the last value was returned.  */
95*e4b17023SJohn Marino   /* Function used to compute a hash code given a key.
96*e4b17023SJohn Marino      This function is specified when the hash table is created.  */
97*e4b17023SJohn Marino   hash_func_type    hash_func;
98*e4b17023SJohn Marino   /* Function used to compare two hash keys to see if they are equal.  */
99*e4b17023SJohn Marino   compare_func_type compare_func;
100*e4b17023SJohn Marino } *cache_ptr;
101*e4b17023SJohn Marino 
102*e4b17023SJohn Marino 
103*e4b17023SJohn Marino /* Allocate and initialize a hash table.  */
104*e4b17023SJohn Marino 
105*e4b17023SJohn Marino cache_ptr objc_hash_new (unsigned int size,
106*e4b17023SJohn Marino 			 hash_func_type hash_func,
107*e4b17023SJohn Marino 			 compare_func_type compare_func);
108*e4b17023SJohn Marino 
109*e4b17023SJohn Marino /* Deallocate all of the hash nodes and the cache itself.  */
110*e4b17023SJohn Marino 
111*e4b17023SJohn Marino void objc_hash_delete (cache_ptr cache);
112*e4b17023SJohn Marino 
113*e4b17023SJohn Marino /* Add the key/value pair to the hash table.  If the
114*e4b17023SJohn Marino    hash table reaches a level of fullness then it will be resized.
115*e4b17023SJohn Marino 
116*e4b17023SJohn Marino    assert if the key is already in the hash.  */
117*e4b17023SJohn Marino 
118*e4b17023SJohn Marino void objc_hash_add (cache_ptr *cachep, const void *key, void *value);
119*e4b17023SJohn Marino 
120*e4b17023SJohn Marino /* Remove the key/value pair from the hash table.
121*e4b17023SJohn Marino    assert if the key isn't in the table.  */
122*e4b17023SJohn Marino 
123*e4b17023SJohn Marino void objc_hash_remove (cache_ptr cache, const void *key);
124*e4b17023SJohn Marino 
125*e4b17023SJohn Marino /* Used to index through the hash table.  Start with NULL
126*e4b17023SJohn Marino    to get the first entry.
127*e4b17023SJohn Marino 
128*e4b17023SJohn Marino    Successive calls pass the value returned previously.
129*e4b17023SJohn Marino    ** Don't modify the hash during this operation ***
130*e4b17023SJohn Marino 
131*e4b17023SJohn Marino    Cache nodes are returned such that key or value can
132*e4b17023SJohn Marino    be extracted.  */
133*e4b17023SJohn Marino 
134*e4b17023SJohn Marino node_ptr objc_hash_next (cache_ptr cache, node_ptr node);
135*e4b17023SJohn Marino 
136*e4b17023SJohn Marino /* Used to return a value from a hash table using a given key.  */
137*e4b17023SJohn Marino 
138*e4b17023SJohn Marino void *objc_hash_value_for_key (cache_ptr cache, const void *key);
139*e4b17023SJohn Marino 
140*e4b17023SJohn Marino /* Used to determine if the given key exists in the hash table */
141*e4b17023SJohn Marino 
142*e4b17023SJohn Marino BOOL objc_hash_is_key_in_hash (cache_ptr cache, const void *key);
143*e4b17023SJohn Marino 
144*e4b17023SJohn Marino /************************************************
145*e4b17023SJohn Marino 
146*e4b17023SJohn Marino         Useful hashing functions.
147*e4b17023SJohn Marino 
148*e4b17023SJohn Marino         Declared inline for your pleasure.
149*e4b17023SJohn Marino 
150*e4b17023SJohn Marino ************************************************/
151*e4b17023SJohn Marino 
152*e4b17023SJohn Marino /* Calculate a hash code by performing some
153*e4b17023SJohn Marino    manipulation of the key pointer.  (Use the lowest bits
154*e4b17023SJohn Marino    except for those likely to be 0 due to alignment.)  */
155*e4b17023SJohn Marino 
156*e4b17023SJohn Marino static inline unsigned int
objc_hash_ptr(cache_ptr cache,const void * key)157*e4b17023SJohn Marino objc_hash_ptr (cache_ptr cache, const void *key)
158*e4b17023SJohn Marino {
159*e4b17023SJohn Marino   return ((size_t)key / sizeof (void *)) & cache->mask;
160*e4b17023SJohn Marino }
161*e4b17023SJohn Marino 
162*e4b17023SJohn Marino 
163*e4b17023SJohn Marino /* Calculate a hash code by iterating over a NULL
164*e4b17023SJohn Marino    terminate string.  */
165*e4b17023SJohn Marino static inline unsigned int
objc_hash_string(cache_ptr cache,const void * key)166*e4b17023SJohn Marino objc_hash_string (cache_ptr cache, const void *key)
167*e4b17023SJohn Marino {
168*e4b17023SJohn Marino   unsigned int ret = 0;
169*e4b17023SJohn Marino   unsigned int ctr = 0;
170*e4b17023SJohn Marino   const char *ckey = (const char *) key;
171*e4b17023SJohn Marino 
172*e4b17023SJohn Marino   while (*ckey) {
173*e4b17023SJohn Marino     ret ^= *ckey++ << ctr;
174*e4b17023SJohn Marino     ctr = (ctr + 1) % sizeof (void *);
175*e4b17023SJohn Marino   }
176*e4b17023SJohn Marino 
177*e4b17023SJohn Marino   return ret & cache->mask;
178*e4b17023SJohn Marino }
179*e4b17023SJohn Marino 
180*e4b17023SJohn Marino 
181*e4b17023SJohn Marino /* Compare two pointers for equality.  */
182*e4b17023SJohn Marino static inline int
objc_compare_ptrs(const void * k1,const void * k2)183*e4b17023SJohn Marino objc_compare_ptrs (const void *k1, const void *k2)
184*e4b17023SJohn Marino {
185*e4b17023SJohn Marino   return (k1 == k2);
186*e4b17023SJohn Marino }
187*e4b17023SJohn Marino 
188*e4b17023SJohn Marino 
189*e4b17023SJohn Marino /* Compare two strings.  */
190*e4b17023SJohn Marino static inline int
objc_compare_strings(const void * k1,const void * k2)191*e4b17023SJohn Marino objc_compare_strings (const void *k1, const void *k2)
192*e4b17023SJohn Marino {
193*e4b17023SJohn Marino   if (k1 == k2)
194*e4b17023SJohn Marino     return 1;
195*e4b17023SJohn Marino   else if (k1 == 0 || k2 == 0)
196*e4b17023SJohn Marino     return 0;
197*e4b17023SJohn Marino   else
198*e4b17023SJohn Marino     return ! strcmp ((const char *) k1, (const char *) k2);
199*e4b17023SJohn Marino }
200*e4b17023SJohn Marino 
201*e4b17023SJohn Marino #endif /* not __hash_INCLUDE_GNU */
202