Branch: Tag:

2008-06-24

2008-06-24 18:45:56 by Henrik Grubbström (Grubba) <grubba@grubba.org>

First go at generation counting for mappings.

Rev: src/mapping.c:1.202
Rev: src/mapping.h:1.69

2:   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information. - || $Id: mapping.c,v 1.201 2008/05/11 14:55:53 mast Exp $ + || $Id: mapping.c,v 1.202 2008/06/24 18:45:56 grubba Exp $   */      #include "global.h"
205:    md->valrefs=0;    md->hardlinks=0;    md->num_keypairs=size; +  md->generation_cnt = 0;    }else{    switch (flags & MAPPING_WEAK) {    case 0: md = &empty_data; break;
417:    init_mapping(m, new_size, md->flags);    debug_malloc_touch(m);    new_md=m->data; +  new_md->generation_cnt = md->generation_cnt;       /* This operation is now 100% atomic - no locking required */    if(md->refs>1)
501:    add_ref(nmd); /* For DMALLOC... */    nmd->valrefs=0;    nmd->hardlinks=0; +  nmd->generation_cnt = md->generation_cnt;    -  +  /* FIXME: What about nmd->flags? */ +     if(md->hardlinks)    {   #ifdef PIKE_DEBUG
748:    * possible to tell the difference. */    assign_svalue (&k->ind, key);    assign_svalue(& k->val, val); +  md->flags |= MAPPING_DIRTY;   #ifdef PIKE_DEBUG    if(d_flag>1) check_mapping(m);   #endif
796:    m->debug_size++;   #endif    +  md->flags |= MAPPING_DIRTY; +    #ifdef PIKE_DEBUG    if(d_flag>1) check_mapping(m);   #endif
915:    md->ind_types |= 1 << key->type;    md->val_types |= BIT_INT;    md->size++; +  md->flags |= MAPPING_DIRTY;   #ifdef MAPPING_SIZE_DEBUG    if(m->data ==md)    m->debug_size++;
999:    if(md->size < (md->hashsize + 1) * MIN_LINK_LENGTH)    {    debug_malloc_touch(m); -  rehash(m, MAP_SLOTS(m->data->size)); +  rehash(m, MAP_SLOTS(m->data->size + !!md->generation_cnt));    }    -  +  /* Note: md may be invalid here dure to the rehash above. */ +  m->data->flags |= MAPPING_DIRTY; +    #ifdef PIKE_DEBUG    if(d_flag>1) check_mapping(m);   #endif
1051:    mark_free_svalue (&md->free_list->ind);    mark_free_svalue (&md->free_list->val);    md->size--; +  +  md->flags |= MAPPING_DIRTY; +    #ifdef MAPPING_SIZE_DEBUG    if(m->data ==md)    {
1070:    md->val_types = val_types;    md->ind_types = ind_types;    -  if(MAP_SLOTS(md->size) < md->hashsize * MIN_LINK_LENGTH) +  if(MAP_SLOTS(md->size + !!md->generation_cnt) < +  md->hashsize * MIN_LINK_LENGTH)    {    debug_malloc_touch(m); -  rehash(m, MAP_SLOTS(md->size)); +  rehash(m, MAP_SLOTS(md->size + !!md->generation_cnt));    }      #ifdef PIKE_DEBUG
1340:    PREPARE_FOR_DATA_CHANGE();    assign_svalue(& k->val, to);    md->val_types|=1<<to->type; +  md->flags |= MAPPING_DIRTY;    }    }    free_mapping_data(md);
1492:    }    }    UNSET_ONERROR(err); +  if (a_md->generation_cnt > b_md->generation_cnt) +  res->generation_cnt = a_md->generation_cnt; +  else +  res->generation_cnt = b_md->generation_cnt;    return res;   }   
1527:    }    }    UNSET_ONERROR(err); +  if (a_md->generation_cnt > b_md->generation_cnt) +  res->generation_cnt = a_md->generation_cnt; +  else +  res->generation_cnt = b_md->generation_cnt;    return res;   }   
1571:    }    }    UNSET_ONERROR(err); +  if (a_md->generation_cnt > b_md->generation_cnt) +  res->generation_cnt = a_md->generation_cnt; +  else +  res->generation_cnt = b_md->generation_cnt;    return res;   }   
1647:    free_array(ci);    free_array(cv);    +  if (a->data->generation_cnt > b->data->generation_cnt) +  m->generation_cnt = a->data->generation_cnt; +  else +  m->generation_cnt = b->data->generation_cnt;    return m;   }   
1700:    free_array(ci);    free_array(cv);    +  if (a->data->generation_cnt > b->data->generation_cnt) +  m->generation_cnt = a->data->generation_cnt; +  else +  m->generation_cnt = b->data->generation_cnt;    return m;   }   
1731:    INT32 e,d;    struct mapping *ret=0;    struct keypair *k; +  int generation = 0;       for(e=d=0;d<args;d++)    { -  +  struct mapping *m = argp[d].u.mapping;   #ifdef PIKE_DEBUG -  if(d_flag>1) check_mapping(argp[d].u.mapping); +  if(d_flag>1) check_mapping(m);   #endif -  e+=argp[d].u.mapping->data->size; +  e += m->data->size;    }       if(!e) return allocate_mapping(0);
1775:    struct mapping *m=argp[d].u.mapping;    struct mapping_data *md=m->data;    +  if (md->generation_cnt > generation) +  generation = md->generation_cnt; +     add_ref(md);    NEW_MAPPING_LOOP(md)    low_mapping_insert(ret, &k->ind, &k->val, 2);
1784: Inside #if defined(PIKE_DEBUG)
   if(!ret)    Pike_fatal("add_mappings is confused!\n");   #endif +  ret->md->generation_cnt = generation;    return ret;   }   
2196:    to->u.integer=0;   }    + PMOD_EXPORT INT32 mapping_generation(struct mapping *m) + { +  if (m->data->flags & MAPPING_DIRTY) { +  m->data->generation_cnt++; +  m->data->flags &= ~MAPPING_DIRTY; +  } +  return m->data->generation_cnt; + }      #ifdef PIKE_DEBUG