comparison src/symbols.c @ 490:38fb9ae12edd

[xemacs-hg @ 2001-04-30 09:12:03 by martinb] a better string hash function
author martinb
date Mon, 30 Apr 2001 09:12:04 +0000
parents c33ae14dd6d0
children 183866b06e0b
comparison
equal deleted inserted replaced
489:4a8bb4aa9740 490:38fb9ae12edd
339 Also store the bucket number in oblookup_last_bucket_number. */ 339 Also store the bucket number in oblookup_last_bucket_number. */
340 340
341 Lisp_Object 341 Lisp_Object
342 oblookup (Lisp_Object obarray, const Bufbyte *ptr, Bytecount size) 342 oblookup (Lisp_Object obarray, const Bufbyte *ptr, Bytecount size)
343 { 343 {
344 int hash, obsize; 344 unsigned int hash, obsize;
345 Lisp_Symbol *tail; 345 Lisp_Symbol *tail;
346 Lisp_Object bucket; 346 Lisp_Object bucket;
347 347
348 if (!VECTORP (obarray) || 348 if (!VECTORP (obarray) ||
349 (obsize = XVECTOR_LENGTH (obarray)) == 0) 349 (obsize = XVECTOR_LENGTH (obarray)) == 0)
372 break; 372 break;
373 } 373 }
374 return make_int (hash); 374 return make_int (hash);
375 } 375 }
376 376
377 #if 0 /* Emacs 19.34 */ 377 /* An excellent string hashing function.
378 int 378 Adapted from glib's g_str_hash().
379 Investigation by Karl Nelson <kenelson@ece.ucdavis.edu>.
380 Do a web search for "g_str_hash X31_HASH" if you want to know more. */
381 unsigned int
379 hash_string (const Bufbyte *ptr, Bytecount len) 382 hash_string (const Bufbyte *ptr, Bytecount len)
380 { 383 {
381 const Bufbyte *p = ptr; 384 unsigned int hash;
382 const Bufbyte *end = p + len; 385
383 Bufbyte c; 386 for (hash = 0; len; len--, ptr++)
384 int hash = 0; 387 /* (31 * hash) will probably be optimized to ((hash << 5) - hash). */
385 388 hash = 31 * hash + *ptr;
386 while (p != end) 389
387 { 390 return hash;
388 c = *p++;
389 if (c >= 0140) c -= 40;
390 hash = ((hash<<3) + (hash>>28) + c);
391 }
392 return hash & 07777777777;
393 }
394 #endif
395
396 /* derived from hashpjw, Dragon Book P436. */
397 int
398 hash_string (const Bufbyte *ptr, Bytecount len)
399 {
400 int hash = 0;
401
402 while (len-- > 0)
403 {
404 int g;
405 hash = (hash << 4) + *ptr++;
406 g = hash & 0xf0000000;
407 if (g)
408 hash = (hash ^ (g >> 24)) ^ g;
409 }
410 return hash & 07777777777;
411 } 391 }
412 392
413 /* Map FN over OBARRAY. The mapping is stopped when FN returns a 393 /* Map FN over OBARRAY. The mapping is stopped when FN returns a
414 non-zero value. */ 394 non-zero value. */
415 void 395 void
3248 Vobarray = make_vector (OBARRAY_SIZE, Qzero); 3228 Vobarray = make_vector (OBARRAY_SIZE, Qzero);
3249 initial_obarray = Vobarray; 3229 initial_obarray = Vobarray;
3250 staticpro (&initial_obarray); 3230 staticpro (&initial_obarray);
3251 /* Intern nil in the obarray */ 3231 /* Intern nil in the obarray */
3252 { 3232 {
3253 int hash = hash_string (string_data (XSYMBOL (Qnil)->name), 3); 3233 unsigned int hash = hash_string (string_data (XSYMBOL (Qnil)->name), 3);
3254 XVECTOR_DATA (Vobarray)[hash % OBARRAY_SIZE] = Qnil; 3234 XVECTOR_DATA (Vobarray)[hash % OBARRAY_SIZE] = Qnil;
3255 } 3235 }
3256 3236
3257 { 3237 {
3258 /* Required to get around a GCC syntax error on certain 3238 /* Required to get around a GCC syntax error on certain