Changeset 1857 for trunk/src/kmk/strcache.c
- Timestamp:
- Oct 13, 2008, 5:58:07 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/strcache.c
r1854 r1857 61 61 } 62 62 63 #ifndef CONFIG_WITH_VALUE_LENGTH 63 64 static const char * 64 65 add_string(const char *str, int len) … … 67 68 struct strcache *sp; 68 69 const char *res; 69 #ifdef CONFIG_WITH_VALUE_LENGTH70 int str_len = len;71 char *tmp;72 73 /* Add space a length prefix and the terminator and assure74 (somewhat) natural alignment. */75 len += sizeof(unsigned int) + 1;76 len = (len + sizeof(void *) - 1) & ~(sizeof(void *) - 1);77 --len;78 #endif79 70 80 71 /* If the string we want is too large to fit into a single buffer, then … … 98 89 99 90 /* Add the string to the best cache. */ 100 #ifndef CONFIG_WITH_VALUE_LENGTH101 91 res = best->end; 102 92 memcpy (best->end, str, len); … … 105 95 best->bytesfree -= len + 1; 106 96 ++best->count; 97 return res; 98 } 99 107 100 #else /* CONFIG_WITH_VALUE_LENGTH */ 108 tmp = best->end; 109 best->end += len + 1; 110 assert(!((size_t)tmp & (sizeof(void *) - 1))); 111 112 *(unsigned int *)tmp = str_len; /* length prefix */ 113 tmp += sizeof(unsigned int); 114 115 res = tmp; 116 memcpy (tmp, str, str_len); 117 tmp += str_len; 118 *(tmp++) = '\0'; 119 120 best->bytesfree -= len + 1; 101 102 static const char * 103 add_string(const char *str, struct strcache_pref *prefix) 104 { 105 struct strcache *best = NULL; 106 struct strcache *sp; 107 struct strcache_pref *real_prefix; 108 int len; 109 const char *res; 110 char *dst; 111 112 /* Calc the entry length; the prefix data + the string + alignment. */ 113 len = sizeof(struct strcache_pref) + prefix->len + 1; 114 len = (len + sizeof(void *) - 1) & ~(sizeof(void *) - 1); 115 116 /* If the string we want is too large to fit into a single buffer, then 117 we're screwed; nothing will ever fit! Change the maximum size of the 118 cache to be big enough. */ 119 if (len > bufsize) 120 bufsize = len * 2; 121 122 /* First, find a cache with enough free space. We always look through all 123 the blocks and choose the one with the best fit (the one that leaves the 124 least amount of space free). */ 125 for (sp = strcache; sp != NULL; sp = sp->next) 126 if (sp->bytesfree >= len && (!best || best->bytesfree > sp->bytesfree)) 127 best = sp; 128 129 /* If nothing is big enough, make a new cache. */ 130 if (!best) 131 best = new_cache(); 132 133 assert (best->bytesfree >= len); 134 135 /* Add the string to the best cache. */ 136 real_prefix = (struct strcache_pref *)best->end; 137 *real_prefix = *prefix; 138 139 res = dst = (char *)(real_prefix + 1); 140 assert(!((size_t)res & (sizeof(void *) - 1))); 141 memcpy (dst, str, prefix->len); 142 dst += prefix->len; 143 *(dst++) = '\0'; 144 145 best->end += len; 146 best->bytesfree -= len; 121 147 ++best->count; 122 148 123 assert (tmp <= best->end);124 assert (!((size_t)res & (sizeof(void *) - 1)));125 #endif /* CONFIG_WITH_VALUE_LENGTH */126 149 return res; 127 150 } 128 151 129 130 /* Hash table of strings in the cache. */131 132 #ifdef CONFIG_WITH_VALUE_LENGTH133 152 /* Hackish globals for passing data to the hash functions. 134 153 There isn't really any other way without running the 135 154 risk of breaking rehashing. */ 136 155 static const char *lookup_string; 137 static unsigned int lookup_string_len; 138 # ifdef CONFIG_WITH_INCLUDEDEP 139 static unsigned long lookup_string_hash1; 140 static unsigned long lookup_string_hash2; 141 # endif /* CONFIG_WITH_INCLUDEDEP */ 156 static struct strcache_pref *lookup_prefix; 157 142 158 #endif /* CONFIG_WITH_VALUE_LENGTH */ 159 160 161 /* Hash table of strings in the cache. */ 143 162 144 163 static unsigned long 145 164 str_hash_1 (const void *key) 146 165 { 147 #ifdef CONFIG_WITH_ INCLUDEDEP148 if ( (const char *) key == lookup_string && lookup_string_hash1)149 return lookup_ string_hash1;166 #ifdef CONFIG_WITH_VALUE_LENGTH 167 if (MY_PREDICT_TRUE ((const char *) key == lookup_string)) 168 return lookup_prefix->hash1; 150 169 #endif 151 170 return_ISTRING_HASH_1 ((const char *) key); … … 155 174 str_hash_2 (const void *key) 156 175 { 157 #ifdef CONFIG_WITH_INCLUDEDEP 158 if ((const char *) key == lookup_string && lookup_string_hash2) 159 return lookup_string_hash2; 176 #ifdef CONFIG_WITH_VALUE_LENGTH 177 if (MY_PREDICT_TRUE ((const char *) key == lookup_string)) 178 { 179 if (lookup_prefix->hash2) 180 { 181 unsigned long hash2 = 0; 182 ISTRING_HASH_2 ((const char *)key, hash2); 183 lookup_prefix->hash2 = hash2; 184 } 185 return lookup_prefix->hash2; 186 } 160 187 #endif 161 188 return_ISTRING_HASH_2 ((const char *) key); … … 172 199 kBuild scenario. */ 173 200 174 if ( (const char *) x == lookup_string)175 { 176 assert (lookup_ string_len == strlen ((const char *)x));177 if (strcache_get_len ((const char *)y) != lookup_ string_len)201 if (MY_PREDICT_TRUE ((const char *) x == lookup_string)) 202 { 203 assert (lookup_prefix->len == strlen ((const char *)x)); 204 if (strcache_get_len ((const char *)y) != lookup_prefix->len) 178 205 return -1; 179 206 } … … 185 212 static unsigned long total_adds = 0; 186 213 214 #ifndef CONFIG_WITH_VALUE_LENGTH 187 215 static const char * 188 216 add_hash (const char *str, int len) 189 217 { 190 218 /* Look up the string in the hash. If it's there, return it. */ 191 #ifndef CONFIG_WITH_VALUE_LENGTH192 219 char *const *slot = (char *const *) hash_find_slot (&strings, str); 193 220 const char *key = *slot; 194 #else /* CONFIG_WITH_VALUE_LENGTH */195 char *const *slot;196 const char *key;197 198 lookup_string = str;199 lookup_string_len = len;200 slot = (char *const *) hash_find_slot (&strings, str);201 key = *slot;202 #endif /* CONFIG_WITH_VALUE_LENGTH */203 221 204 222 /* Count the total number of adds we performed. */ … … 213 231 return key; 214 232 } 233 234 #else /* CONFIG_WITH_VALUE_LENGTH */ 235 236 static const char * 237 add_hash (const char *str, int len, unsigned long hash1, unsigned long hash2) 238 { 239 char *const *slot; 240 const char *key; 241 struct strcache_pref prefix; 242 243 /* Look up the string in the hash. If it's there, return it. */ 244 prefix.len = len; 245 prefix.hash2 = hash2; 246 if (!hash1 && !hash2) 247 ISTRING_HASH_1 (str, hash1); 248 prefix.hash1 = hash1; 249 250 lookup_string = str; 251 lookup_prefix = &prefix; 252 253 slot = (char *const *) hash_find_slot (&strings, str); 254 key = *slot; 255 256 /* Count the total number of adds we performed. */ 257 ++total_adds; 258 259 if (!HASH_VACANT (key)) 260 return key; 261 262 /* Not there yet so add it to a buffer, then into the hash table. */ 263 key = add_string (str, &prefix); 264 hash_insert_at (&strings, key, slot); 265 return key; 266 } 267 268 /* Verifies that a string cache entry didn't change and that the 269 prefix is still valid. */ 270 int 271 strcache_check_sanity (const char *str) 272 { 273 struct strcache_pref const *prefix = (struct strcache_pref const *)str - 1; 274 unsigned long hash; 275 276 if (strlen (str) != prefix->len) 277 { 278 MY_ASSERT_MSG (0, ("len: %u != %u - '%s'\n", (unsigned int)strlen (str), 279 prefix->len, str)); 280 return -1; 281 } 282 283 hash = 0; 284 ISTRING_HASH_1 (str, hash); 285 if (hash != prefix->hash1) 286 { 287 MY_ASSERT_MSG (0, ("hash1: %lx != %lx - '%s'\n", hash, prefix->hash1, str)); 288 return -1; 289 } 290 291 if (prefix->hash2) 292 { 293 hash = 0; 294 ISTRING_HASH_2 (str, hash); 295 if (hash != prefix->hash2) 296 { 297 MY_ASSERT_MSG (0, ("hash2: %lx != %lx - '%s'\n", hash, prefix->hash2, str)); 298 return -1; 299 } 300 } 301 302 return 0; 303 } 304 305 /* Fallback for when the hash2 value isn't present. */ 306 unsigned long 307 strcache_get_hash2_fallback (const char *str) 308 { 309 struct strcache_pref *prefix = (struct strcache_pref *)str - 1; 310 unsigned long hash2 = 0; 311 312 ISTRING_HASH_2 (str, hash2); 313 prefix->hash2 = hash2; 314 315 return hash2; 316 } 317 318 #endif /* CONFIG_WITH_VALUE_LENGTH */ 215 319 216 320 /* Returns true if the string is in the cache; false if not. */ … … 233 337 strcache_add (const char *str) 234 338 { 339 #ifndef CONFIG_WITH_VALUE_LENGTH 235 340 return add_hash (str, strlen (str)); 341 #else 342 /* XXX: calc the hash1 while determining the string length. */ 343 return add_hash (str, strlen (str), 0, 0); 344 #endif 236 345 } 237 346 … … 249 358 } 250 359 360 #ifndef CONFIG_WITH_VALUE_LENGTH 251 361 return add_hash (str, len); 362 #else 363 /* XXX: eliminate the alloca mess using the prefixing? */ 364 return add_hash (str, len, 0, 0); 365 #endif 252 366 } 253 367 … … 260 374 unsigned long hash2) 261 375 { 262 const char *retstr; 263 264 assert (hash1 == str_hash_1 (str)); 265 assert (hash2 == str_hash_2 (str)); 266 267 lookup_string_hash1 = hash1; 268 lookup_string_hash2 = hash2; 269 270 retstr = add_hash (str, len); 271 272 lookup_string_hash1 = 0; 273 lookup_string_hash2 = 0; 274 275 return retstr; 376 return add_hash (str, len, hash1, hash2); 276 377 } 277 378
Note:
See TracChangeset
for help on using the changeset viewer.