diff --git a/src/stralloc.c b/src/stralloc.c index 3d8232ce5a19cae5456f6ddce577ce85abb2fda7..3d5ede6dd9f6c833586cfd12a4f29454924386ff 100644 --- a/src/stralloc.c +++ b/src/stralloc.c @@ -23,11 +23,16 @@ #define HUGE HUGE_VAL #endif /*!HUGE*/ -RCSID("$Id: stralloc.c,v 1.61 1999/08/14 15:09:27 per Exp $"); +RCSID("$Id: stralloc.c,v 1.62 1999/09/02 04:40:49 hubbe Exp $"); #define BEGIN_HASH_SIZE 997 #define MAX_AVG_LINK_LENGTH 3 -#define HASH_PREFIX 64 + +/* Experimental dynamic hash length */ +#ifndef HASH_PREFIX +static unsigned int HASH_PREFIX=32; +static int need_more_hash_prefix=0; +#endif unsigned INT32 htable_size=0; static unsigned int hashprimes_entry=0; @@ -282,6 +287,9 @@ static struct pike_string *internal_findstring(const char *s, int h) { struct pike_string *curr,**prev, **base; +#ifndef HASH_PREFIX + unsigned int depth=0; +#endif for(base = prev = base_table + h;( curr=*prev ); prev=&curr->next) { @@ -304,7 +312,21 @@ static struct pike_string *internal_findstring(const char *s, *base = curr; return curr; /* pointer to string */ } +#ifndef HASH_PREFIX + depth++; +#endif + } +#ifndef HASH_PREFIX + /* These heuruistics might require tuning! /Hubbe */ + if(depth > HASH_PREFIX && HASH_PREFIX<len) + { + need_more_hash_prefix++; +/* fprintf(stderr,"depth=%d num_strings=%d need_more_hash_prefix=%d HASH_PREFIX=%d\n",depth,num_strings,need_more_hash_prefix,HASH_PREFIX); */ + }else{ + if(need_more_hash_prefix) + need_more_hash_prefix--; } +#endif return 0; /* not found */ } @@ -372,7 +394,8 @@ static void rehash(void) base_table=(struct pike_string **)xalloc(sizeof(struct pike_string *)*htable_size); MEMSET((char *)base_table,0,sizeof(struct pike_string *)*htable_size); - for(h=0;h<old;h++) rehash_string_backwards(old_base[h]); + for(h=0;h<old;h++) + rehash_string_backwards(old_base[h]); if(old_base) free((char *)old_base); @@ -408,6 +431,40 @@ static void link_pike_string(struct pike_string *s, int h) num_strings++; if(num_strings > MAX_AVG_LINK_LENGTH * htable_size) rehash(); + +#ifndef HASH_PREFIX + /* These heuruistics might require tuning! /Hubbe */ + if(need_more_hash_prefix > ( htable_size >> 4)) + { + /* This could in theory have a pretty ugly complexity */ + /* /Hubbe + */ + unsigned INT32 save_full_hash_value=full_hash_value; + + need_more_hash_prefix=0; + HASH_PREFIX=HASH_PREFIX*2; +/* fprintf(stderr,"Doubling HASH_PREFIX to %d and rehashing\n",HASH_PREFIX); */ + + for(h=0;h<htable_size;h++) + { + struct pike_string *tmp=base_table[h]; + base_table[h]=0; + while(tmp) + { + int h2; + struct pike_string *tmp2=tmp; /* First unlink */ + tmp=tmp2->next; + + h2=do_hash(tmp2); /* compute new hash value */ + tmp2->hval=full_hash_value; + + tmp2->next=base_table[h2]; /* and re-hash */ + base_table[h2]=tmp2; + } + } + full_hash_value=save_full_hash_value; + } +#endif } struct pike_string *debug_begin_wide_shared_string(int len, int shift)