Changeset 1902 for trunk/src/kmk/hash.c
- Timestamp:
- Oct 21, 2008, 5:57:00 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/hash.c
r1864 r1902 19 19 #include "make.h" 20 20 #include "hash.h" 21 #ifdef CONFIG_WITH_STRCACHE2 22 # include <assert.h> 23 #endif 24 21 25 22 26 #define CALLOC(t, n) ((t *) calloc (sizeof (t), (n))) … … 62 66 ht->ht_hash_2 = hash_2; 63 67 ht->ht_compare = hash_cmp; 64 } 68 #ifdef CONFIG_WITH_STRCACHE2 69 ht->ht_strcache = 0; 70 ht->ht_off_string = 0; 71 #endif 72 } 73 74 #ifdef CONFIG_WITH_STRCACHE2 75 /* Same as hash_init, except that no callbacks are needed since all 76 keys - including the ones being searched for - are from a string 77 cache. This means that any give string will only have one pointer 78 value and that the hash and length can be retrived very cheaply, 79 thus permitting some nice optimizations. 80 81 STRCACHE points to the string cache, while OFF_STRING gives the 82 offset of the string pointer in the item structures the hash table 83 entries points to. */ 84 void hash_init_strcached (struct hash_table *ht, unsigned long size, 85 struct strcache2 *strcache, unsigned int off_string) 86 { 87 hash_init (ht, size, 0, 0, 0); 88 ht->ht_strcache = strcache; 89 ht->ht_off_string = off_string; 90 } 91 #endif /* CONFIG_WITH_STRCACHE2 */ 65 92 66 93 /* Load an array of items into `ht'. */ … … 71 98 { 72 99 char *items = (char *) item_table; 100 #ifndef CONFIG_WITH_STRCACHE2 73 101 while (cardinality--) 74 102 { … … 76 104 items += size; 77 105 } 106 #else /* CONFIG_WITH_STRCACHE2 */ 107 if (ht->ht_strcache) 108 while (cardinality--) 109 { 110 hash_insert_strcached (ht, items); 111 items += size; 112 } 113 else 114 while (cardinality--) 115 { 116 hash_insert (ht, items); 117 items += size; 118 } 119 #endif /* CONFIG_WITH_STRCACHE2 */ 78 120 } 79 121 … … 90 132 unsigned int hash_2 = 0; 91 133 unsigned int hash_1 = (*ht->ht_hash_1) (key); 134 135 #ifdef CONFIG_WITH_STRCACHE2 136 assert (ht->ht_strcache == 0); 137 #endif 92 138 93 139 ht->ht_lookups++; … … 124 170 } 125 171 126 #ifdef CONFIG_WITH_VALUE_LENGTH 127 /* A variant of hash_find_slot that takes the hash values as arguments. 128 The HASH_2 argument is optional, pass 0 if not available. 129 Not having to call ht_hash_1 and perhaps also not ht_hash_2 does save 130 a whole bunch of cycles in some of the kBuild use cases (strcache sees 131 serious usage there). */ 172 #ifdef CONFIG_WITH_STRCACHE2 173 /* hash_find_slot version for tables created with hash_init_strcached. */ 132 174 void ** 133 hash_find_slot_prehashed (struct hash_table *ht, const void *key, 134 unsigned int hash_1, unsigned int hash_2) 175 hash_find_slot_strcached (struct hash_table *ht, const void *key) 135 176 { 136 177 void **slot; 137 178 void **deleted_slot = 0; 179 const char *str1 = *(const char **)((const char *)key + ht->ht_off_string); 180 const char *str2; 181 unsigned int hash_1 = strcache2_get_ptr_hash (ht->ht_strcache, str1); 182 unsigned int hash_2; 183 184 #ifdef CONFIG_WITH_STRCACHE2 185 assert (ht->ht_strcache != 0); 186 #endif 138 187 139 188 ht->ht_lookups++; … … 141 190 make_stats_ht_lookups++; 142 191 #endif 192 193 /* first iteration unrolled. */ 194 195 hash_1 &= (ht->ht_size - 1); 196 slot = &ht->ht_vec[hash_1]; 197 if (*slot == 0) 198 return slot; 199 if (*slot != hash_deleted_item) 200 { 201 str2 = *(const char **)((const char *)(*slot) + ht->ht_off_string); 202 if (str1 == str2) 203 return slot; 204 205 ht->ht_collisions++; 206 #ifdef CONFIG_WITH_MAKE_STATS 207 make_stats_ht_collisions++; 208 #endif 209 } 210 else 211 deleted_slot = slot; 212 213 /* the rest of the loop. */ 214 215 hash_2 = strcache2_get_hash1 (ht->ht_strcache, str1) | 1; 216 hash_1 += hash_2; 143 217 for (;;) 144 218 { … … 155 229 else 156 230 { 157 if (key == *slot) 231 str2 = *(const char **)((const char *)(*slot) + ht->ht_off_string); 232 if (str1 == str2) 158 233 return slot; 159 if ((*ht->ht_compare) (key, *slot) == 0) 160 return slot; 234 161 235 ht->ht_collisions++; 162 236 #ifdef CONFIG_WITH_MAKE_STATS … … 164 238 #endif 165 239 } 166 if (!hash_2) 167 hash_2 = (*ht->ht_hash_2) (key) | 1; 240 168 241 hash_1 += hash_2; 169 242 } 170 243 } 171 172 #endif /* CONFIG_WITH_VALUE_LENGTH */ 244 #endif /* CONFIG_WITH_STRCACHE2 */ 173 245 174 246 void * … … 178 250 return ((HASH_VACANT (*slot)) ? 0 : *slot); 179 251 } 252 253 #ifdef CONFIG_WITH_STRCACHE2 254 void * 255 hash_find_item_strcached (struct hash_table *ht, const void *key) 256 { 257 void **slot = hash_find_slot_strcached (ht, key); 258 return ((HASH_VACANT (*slot)) ? 0 : *slot); 259 } 260 #endif /* CONFIG_WITH_STRCACHE2 */ 180 261 181 262 void * … … 188 269 } 189 270 271 #ifdef CONFIG_WITH_STRCACHE2 272 void * 273 hash_insert_strcached (struct hash_table *ht, const void *item) 274 { 275 void **slot = hash_find_slot_strcached (ht, item); 276 const void *old_item = slot ? *slot : 0; 277 hash_insert_at (ht, item, slot); 278 return (void *)((HASH_VACANT (old_item)) ? 0 : old_item); 279 } 280 #endif /* CONFIG_WITH_STRCACHE2 */ 281 190 282 void * 191 283 hash_insert_at (struct hash_table *ht, const void *item, const void *slot) … … 203 295 { 204 296 hash_rehash (ht); 297 #ifdef CONFIG_WITH_STRCACHE2 298 if (ht->ht_strcache) 299 return (void *)hash_find_slot_strcached (ht, item); 300 #endif /* CONFIG_WITH_STRCACHE2 */ 205 301 return (void *) hash_find_slot (ht, item); 206 302 } … … 215 311 return hash_delete_at (ht, slot); 216 312 } 313 314 #ifdef CONFIG_WITH_STRCACHE2 315 void * 316 hash_delete_strcached (struct hash_table *ht, const void *item) 317 { 318 void **slot = hash_find_slot_strcached (ht, item); 319 return hash_delete_at (ht, slot); 320 } 321 #endif /* CONFIG_WITH_STRCACHE2 */ 217 322 218 323 void * … … 353 458 ht->ht_vec = (void **) CALLOC (struct token *, ht->ht_size); 354 459 460 #ifndef CONFIG_WITH_STRCACHE2 355 461 for (ovp = old_vec; ovp < &old_vec[old_ht_size]; ovp++) 356 462 { … … 361 467 } 362 468 } 469 #else /* CONFIG_WITH_STRCACHE2 */ 470 if (ht->ht_strcache) 471 for (ovp = old_vec; ovp < &old_vec[old_ht_size]; ovp++) 472 { 473 if (! HASH_VACANT (*ovp)) 474 { 475 void **slot = hash_find_slot_strcached (ht, *ovp); 476 *slot = *ovp; 477 } 478 } 479 else 480 for (ovp = old_vec; ovp < &old_vec[old_ht_size]; ovp++) 481 { 482 if (! HASH_VACANT (*ovp)) 483 { 484 void **slot = hash_find_slot (ht, *ovp); 485 *slot = *ovp; 486 } 487 } 488 #endif /* CONFIG_WITH_STRCACHE2 */ 363 489 ht->ht_empty_slots = ht->ht_size - ht->ht_fill; 364 490 free (old_vec);
Note:
See TracChangeset
for help on using the changeset viewer.