pike.git / src / mapping.c

version» Context lines:

pike.git/src/mapping.c:16:   #include "pike_types.h"   #include "dynamic_buffer.h"   #include "interpret.h"   #include "las.h"   #include "gc.h"   #include "stralloc.h"   #include "block_allocator.h"   #include "opcodes.h"   #include "stuff.h"    + /* Average number of keypairs per slot when allocating. */   #define AVG_LINK_LENGTH 4 - #define MIN_LINK_LENGTH 1 +  + /* Minimum number of elements in a hashtable is half of the slots. */ + #define MIN_LINK_LENGTH_NUMERATOR 1 + #define MIN_LINK_LENGTH_DENOMINATOR 2 +  + /* Number of keypairs to allocate for a given size. */   #define MAP_SLOTS(X) ((X)?((X)+((X)>>4)+8):0)      struct mapping *first_mapping;      struct mapping *gc_internal_mapping = 0;   static struct mapping *gc_mark_mapping_pos = 0;      #define unlink_mapping_data(M) do{ \    struct mapping_data *md_=(M); \    if(md_->hardlinks) { md_->hardlinks--; md_->valrefs--; } \
pike.git/src/mapping.c:188: Inside #if defined(PIKE_DEBUG)
   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");   #endif    if(size)    {    hashsize=find_next_power(size / AVG_LINK_LENGTH + 1);    -  if (size < hashsize) size = hashsize; +  if (size < hashsize * AVG_LINK_LENGTH) size = hashsize * AVG_LINK_LENGTH;       e=MAPPING_DATA_SIZE(hashsize, size);       md=xcalloc(1,e);       m->data=md;    md->hashsize=hashsize;       md->free_list=MD_KEYPAIRS(md, hashsize);   #ifndef PIKE_MAPPING_KEYPAIR_LOOP
pike.git/src/mapping.c:512:    * @param new_size new mappingsize    * @return the rehashed mapping    */   static struct mapping *rehash(struct mapping *m, int new_size)   {    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);   #ifdef PIKE_DEBUG    if(md->refs <=0)    Pike_fatal("Zero refs in mapping->data\n");       if(d_flag>1) check_mapping(m);   #endif    -  /* FIXME: The special case below seems suspect. -  * /grubba 2011-09-04 -  */ -  if ((md->hashsize == new_size) && (md->refs == 1)) return m; +  /* NB: Code duplication from init_mapping(). */ +  if (new_size) +  hashsize = find_next_power(new_size / AVG_LINK_LENGTH + 1); +  if ((md->hashsize == hashsize) && (md->refs == 1)) return m;       init_mapping(m, new_size, md->flags);    debug_malloc_touch(m);    new_md=m->data;       /* This operation is now 100% atomic - no locking required */    if(md->refs>1)    {    /* good */    /* More than one reference to the md ==> We need to
pike.git/src/mapping.c:1176:    mark_free_svalue (&md->free_list->ind);    mark_free_svalue (&md->free_list->val);       md->size--;   #ifdef MAPPING_SIZE_DEBUG    if(m->data ==md)    m->debug_size--;   #endif       if (!(md->flags & MAPPING_FLAG_NO_SHRINK)) { -  if((MAP_SLOTS(md->size) < md->hashsize * MIN_LINK_LENGTH) && +  if((md->size * MIN_LINK_LENGTH_DENOMINATOR < +  md->hashsize * MIN_LINK_LENGTH_NUMERATOR) &&    (md->hashsize > AVG_LINK_LENGTH)) {    debug_malloc_touch(m);    rehash(m, MAP_SLOTS(m->data->size));    }    }      #ifdef PIKE_DEBUG    if(d_flag>1) check_mapping(m);   #endif    return;
pike.git/src/mapping.c:1253:    ind_types |= 1 << TYPEOF(k->ind);    prev=&k->next;    }    }    }       md->val_types = val_types;    md->ind_types = ind_types;       if (!(md->flags & MAPPING_FLAG_NO_SHRINK)) { -  if((MAP_SLOTS(md->size) < md->hashsize * MIN_LINK_LENGTH) && +  if((md->size * MIN_LINK_LENGTH_DENOMINATOR < +  md->hashsize * MIN_LINK_LENGTH_NUMERATOR) &&    (md->hashsize > AVG_LINK_LENGTH)) {    debug_malloc_touch(m);    rehash(m, MAP_SLOTS(md->size));    }    }      #ifdef PIKE_DEBUG    if(d_flag>1) check_mapping(m);   #endif    }