Branch: Tag:

2016-10-25

2016-10-25 12:40:18 by Henrik Grubbström (Grubba) <grubba@grubba.org>

Mappings: Changed calling API for init_mapping() and rehash().

These two internal functions now take the size of the hashtable
rather than the number of available keypairs as argument. This
change simplifies the code somewhat, and should be marginally
more fast.

184:    * allocated space.    */   static void init_mapping(struct mapping *m, -  INT32 size, +  INT32 hashsize,    INT16 flags)   {    struct mapping_data *md;    ptrdiff_t e; -  INT32 hashsize; +  INT32 size;       debug_malloc_touch(m);   #ifdef PIKE_DEBUG    if (Pike_in_gc > GC_PASS_PREPARE && Pike_in_gc < GC_PASS_ZAP_WEAK)    Pike_fatal("Can't allocate a new mapping_data inside gc.\n"); -  if(size < 0) Pike_fatal("init_mapping with negative value.\n"); +  if(hashsize < 0) Pike_fatal("init_mapping with negative value.\n");   #endif -  if(size) +  if(hashsize)    { -  hashsize=find_next_power(size / AVG_LINK_LENGTH + 1); +  if (hashsize & (hashsize - 1)) { +  hashsize = find_next_power(hashsize); +  }    -  if (size < hashsize * AVG_LINK_LENGTH) size = hashsize * AVG_LINK_LENGTH; +  size = hashsize * AVG_LINK_LENGTH;       e=MAPPING_DATA_SIZE(hashsize, size);   
266:   PMOD_EXPORT struct mapping *debug_allocate_mapping(int size)   {    struct mapping *m = allocate_mapping_no_init(); -  init_mapping(m,size,0); +  init_mapping(m, (size + AVG_LINK_LENGTH - 1) / AVG_LINK_LENGTH, 0);    return m;   }   
515:    * run, but is used seldom enough not to degrade preformance significantly.    *    * @param m the mapping to be rehashed -  * @param new_size new mappingsize +  * @param hashsize new mappingsize    * @return the rehashed mapping    */ - static struct mapping *rehash(struct mapping *m, int new_size) + static struct mapping *rehash(struct mapping *m, int hashsize)   {    struct mapping_data *md, *new_md;   #ifdef PIKE_DEBUG    INT32 tmp=m->data->size;   #endif    INT32 e; -  INT32 hashsize = 0; +        md=m->data;    debug_malloc_touch(md);
537:   #endif       /* NB: Code duplication from init_mapping(). */ -  if (new_size) -  hashsize = find_next_power(new_size / AVG_LINK_LENGTH + 1); +  if (hashsize & (hashsize - 1)) +  hashsize = find_next_power(hashsize);    if ((md->hashsize == hashsize) && (md->refs == 1)) return m;    -  init_mapping(m, new_size, md->flags); +  init_mapping(m, hashsize, md->flags);    debug_malloc_touch(m);    new_md=m->data;   
967:    md->refs>1)    {    debug_malloc_touch(m); -  rehash(m, md->size * 2 + 2); +  rehash(m, md->hashsize?(md->hashsize<<1):AVG_LINK_LENGTH);    md=m->data;    }    h=h2 & ( md->hashsize - 1);
1091:    md->refs>1)    {    debug_malloc_touch(m); -  rehash(m, md->size * 2 + 2); +  rehash(m, md->hashsize?(md->hashsize<<1):AVG_LINK_LENGTH);    md=m->data;    }    h=h2 & ( md->hashsize - 1);
1194:    md->hashsize * MIN_LINK_LENGTH_NUMERATOR) &&    (md->hashsize > AVG_LINK_LENGTH)) {    debug_malloc_touch(m); -  rehash(m, MAP_SLOTS(m->data->size)); +  rehash(m, md->hashsize>>1);    }    }   
1272:    md->hashsize * MIN_LINK_LENGTH_NUMERATOR) &&    (md->hashsize > AVG_LINK_LENGTH)) {    debug_malloc_touch(m); -  rehash(m, MAP_SLOTS(md->size)); +  rehash(m, md->hashsize>>1);    }    }   
2545: Inside #if defined(PIKE_DEBUG)
   if(md->hashsize > md->num_keypairs)    Pike_fatal("Pretty mean hashtable there buster %d > %d (2)!\n",md->hashsize,md->num_keypairs);    -  if(md->num_keypairs > (md->hashsize + 3) * AVG_LINK_LENGTH) +  if(md->num_keypairs > (md->hashsize + AVG_LINK_LENGTH - 1) * AVG_LINK_LENGTH)    Pike_fatal("Mapping from hell detected, attempting to send it back...\n");       if(md->size > 0 && (!md->ind_types || !md->val_types))