pike.git / src / mapping.c

version» Context lines:

pike.git/src/mapping.c:177:    IF_ELSE_KEYPAIR_LOOP((struct keypair *)&weak_val_empty_data.hash, 0), {0}};   static struct mapping_data weak_both_empty_data =    { PIKE_CONSTANT_MEMOBJ_INIT(1, T_MAPPING_DATA), 1, 0,0,0,0,0,0, MAPPING_WEAK,    IF_ELSE_KEYPAIR_LOOP((struct keypair *)&weak_both_empty_data.hash, 0), {0}};      /** This function allocates the hash table and svalue space for a mapping    * struct. The size is the max number of indices that can fit in the    * 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);       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:259:    * for 'size' values.    *    * @param size initial number of values    * @return the newly allocated mapping    * @see do_free_mapping    * @see free_mapping    */   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;   }      PMOD_EXPORT void really_free_mapping_data(struct mapping_data *md)   {    INT32 e;    struct keypair *k;    debug_malloc_touch(md);      #ifdef PIKE_DEBUG
pike.git/src/mapping.c:508:    md->val_types |= 1<< (TYPEOF(k->val));    md->size++;    }   }      /** This function re-allocates a mapping. It adjusts the max no. of    * values can be fitted into the mapping. It takes a bit of time to    * 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);   #ifdef PIKE_DEBUG    if(md->refs <=0)    Pike_fatal("Zero refs in mapping->data\n");       if(d_flag>1) check_mapping(m);   #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;       /* This operation is now 100% atomic - no locking required */    if(md->refs>1)    {    /* good */    /* More than one reference to the md ==> We need to    * keep it afterwards.    */
pike.git/src/mapping.c:960:    /* We do a re-hash here instead of copying the mapping. */    if(   #ifndef PIKE_MAPPING_KEYPAIR_LOOP    (!md->free_list) ||   #else /* PIKE_MAPPING_KEYPAIR_LOOP */    (md->size >= md->num_keypairs) ||   #endif /* !PIKE_MAPPING_KEYPAIR_LOOP */    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);       /* no need to lock here since we are not calling is_eq - Hubbe */       k=md->free_list;   #ifndef PIKE_MAPPING_KEYPAIR_LOOP    md->free_list=k->next;   #else /* PIKE_MAPPING_KEYPAIR_LOOP */
pike.git/src/mapping.c:1084:    /* no need to call PREPARE_* because we re-hash instead */    if(   #ifndef PIKE_MAPPING_KEYPAIR_LOOP    !(md->free_list) ||   #else /* PIKE_MAPPING_KEYPAIR_LOOP */    (md->size >= md->num_keypairs) ||   #endif /* !PIKE_MAPPING_KEYPAIR_LOOP */    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);       k=md->free_list;   #ifndef PIKE_MAPPING_KEYPAIR_LOOP    md->free_list=k->next;   #else /* PIKE_MAPPING_KEYPAIR_LOOP */    md->free_list++;   #endif /* !PIKE_MAPPING_KEYPAIR_LOOP */
pike.git/src/mapping.c:1187: Inside #if defined(MAPPING_SIZE_DEBUG)
  #ifdef MAPPING_SIZE_DEBUG    if(m->data ==md)    m->debug_size--;   #endif       if (!(md->flags & MAPPING_FLAG_NO_SHRINK)) {    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)); +  rehash(m, md->hashsize>>1);    }    }      #ifdef PIKE_DEBUG    if(d_flag>1) check_mapping(m);   #endif    return;   }      PMOD_EXPORT void check_mapping_for_destruct(struct mapping *m)
pike.git/src/mapping.c:1265:    }       md->val_types = val_types;    md->ind_types = ind_types;       if (!(md->flags & MAPPING_FLAG_NO_SHRINK)) {    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)); +  rehash(m, md->hashsize>>1);    }    }      #ifdef PIKE_DEBUG    if(d_flag>1) check_mapping(m);   #endif    }   }      PMOD_EXPORT struct svalue *low_mapping_lookup(struct mapping *m,
pike.git/src/mapping.c:2538: Inside #if defined(PIKE_DEBUG)
      if(md->size > md->num_keypairs)    Pike_fatal("Pretty mean hashtable there buster!\n");       if(md->hashsize & (md->hashsize - 1))    Pike_fatal("Invalid hashtable size: 0x%08lx\n", (long)md->hashsize);       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))    Pike_fatal("Mapping type fields are... wrong.\n");       num=0;    NEW_MAPPING_LOOP(md)    {    num++;