2000-02-01
2000-02-01 06:25:07 by Fredrik Hübinette (Hubbe) <hubbe@hubbe.net>
-
59e53e7e30374c37a985ce19c8db454feb356b3b
(88 lines)
(+51/-37)
[
Show
| Annotate
]
Branch: 7.9
rewrote rehash() (slower but safer) and added more debug
Rev: src/mapping.c:1.56
Rev: src/mapping.h:1.19
5:
\*/
/**/
#include "global.h"
- RCSID("$Id: mapping.c,v 1.55 2000/01/31 21:26:59 hubbe Exp $");
+ RCSID("$Id: mapping.c,v 1.56 2000/02/01 06:25:06 hubbe Exp $");
#include "main.h"
#include "object.h"
#include "mapping.h"
204:
* inefficient just after being rehashed.
* (wonder if this can't be done faster somehow?)
*/
- static void mapping_rehash_backwards(struct mapping_data *md, struct keypair *p)
+ static void mapping_rehash_backwards(struct mapping *m,
+ struct keypair *p)
{
unsigned INT32 h;
struct keypair *tmp;
if(!p) return;
- mapping_rehash_backwards(md,p->next);
- h=hash_svalue(& p->ind) % md->hashsize;
- tmp=md->free_list;
- md->free_list=tmp->next;
- tmp->next=md->hash[h];
- md->hash[h]=tmp;
- tmp->ind=p->ind;
- tmp->val=p->val;
- md->size++;
- md->ind_types |= 1 << p->ind.type;
- md->val_types |= 1 << p->val.type;
+ mapping_rehash_backwards(m,p->next);
+
+ /* We insert without overwriting
+ * however, this could still cause
+ * problems. (for instance if someone does an
+ * m_delete on an element that is not there yet..
+ */
+ low_mapping_insert(m, &p->ind, &p->val,0);
}
/* This function re-allocates a mapping. It adjusts the max no. of
235:
#endif
INT32 e;
+ md=m->data;
#ifdef PIKE_DEBUG
- if(m->data->refs <=0)
+ if(md->refs <=0)
fatal("Zero refs in mapping->data\n");
if(d_flag>1) check_mapping(m);
#endif
- /* This can be optimized to do rehash and copy
- * in one operation.. -Hubbe
- */
- md=m->data;
- if(md->refs>1)
- {
- debug_malloc_touch(md);
- md=m->data=copy_mapping_data(m->data);
- debug_malloc_touch(md);
- }
-
- #ifdef PIKE_DEBUG
- if(d_flag>1) check_mapping(m);
- #endif
-
+
init_mapping(m, new_size);
debug_malloc_touch(m);
-
+ /* No need to do add_ref(md) because the ref
+ * from 'm' is not freed yet
+ */
+ md->valrefs++;
+
for(e=0;e<md->hashsize;e++)
- mapping_rehash_backwards(m->data, md->hash[e]);
- m->data->size = md->size;
+ mapping_rehash_backwards(m, md->hash[e]);
-
+ md->valrefs--;
+
#ifdef PIKE_DEBUG
if(m->data->size != tmp)
fatal("Rehash failed, size not same any more.\n");
- if(md->refs>1)
- fatal("MD has extra refs in rehash!\n");
+
#endif
- free((char *)md);
+ free_mapping_data(md);
#ifdef PIKE_DEBUG
if(d_flag>1) check_mapping(m);
479:
/* This function inserts key:val into the mapping m.
* Same as doing m[key]=val; in pike.
*/
- void mapping_insert(struct mapping *m,
+ void low_mapping_insert(struct mapping *m,
struct svalue *key,
- struct svalue *val)
+ struct svalue *val,
+ int overwrite)
{
unsigned INT32 h,h2;
struct keypair *k, **prev;
527:
if(d_flag>1) check_mapping(m);
#endif
free_mapping_data(md);
+ if(!overwrite) return;
PREPARE_FOR_DATA_CHANGE2();
PROPAGATE(); /* propagate after preparing */
md->val_types |= 1 << val->type;
546:
/* We do a re-hash here instead of copying the mapping. */
if((!(k=md->free_list)) || md->refs>1)
{
+ debug_malloc_touch(m);
rehash(m, md->size * 2 + 2);
md=m->data;
k=md->free_list;
569:
#endif
}
+ void mapping_insert(struct mapping *m,
+ struct svalue *key,
+ struct svalue *val)
+ {
+ low_mapping_insert(m,key,val,1);
+ }
+
union anything *mapping_get_item_ptr(struct mapping *m,
struct svalue *key,
TYPE_T t)
645:
/* no need to call PREPARE_* because we re-hash instead */
if(!(k=md->free_list) || md->refs>1)
{
+ debug_malloc_touch(m);
rehash(m, md->size * 2 + 2);
md=m->data;
k=md->free_list;
681: Inside #if defined(PIKE_DEBUG)
if(m->data->refs <=0)
fatal("Zero refs in mapping->data\n");
if(d_flag>1) check_mapping(m);
+ debug_malloc_touch(m);
#endif
h2=hash_svalue(key);
697:
goto md_do_nothing);
md_do_nothing:
+ debug_malloc_touch(m);
free_mapping_data(md);
if(to)
{
713: Inside #if defined(PIKE_DEBUG)
if(m->data != md)
fatal("Wrong dataset in mapping_delete!\n");
if(d_flag>1) check_mapping(m);
+ debug_malloc_touch(m);
#endif
free_mapping_data(md);
PREPARE_FOR_INDEX_CHANGE2();
732:
md->size--;
if(md->size < (md->hashsize + 1) * MIN_LINK_LENGTH)
+ {
+ debug_malloc_touch(m);
rehash(m, MAP_SLOTS(m->data->size));
-
+ }
#ifdef PIKE_DEBUG
if(d_flag>1) check_mapping(m);
751: Inside #if defined(PIKE_DEBUG)
if(m->data->refs <=0)
fatal("Zero refs in mapping->data\n");
if(d_flag>1) check_mapping(m);
+ debug_malloc_touch(m);
#endif
/* no is_eq -> no locking */
785:
}
}
if(MAP_SLOTS(md->size) < md->hashsize * MIN_LINK_LENGTH)
+ {
+ debug_malloc_touch(m);
rehash(m, MAP_SLOTS(md->size));
-
+ }
md->val_types = val_types;
md->ind_types = ind_types;
1104:
#endif
n=allocate_mapping(0);
+ if(!m_sizeof(m)) return n; /* done */
debug_malloc_touch(n->data);
free_mapping_data(n->data);
n->data=m->data;
1835:
}
}
if(MAP_SLOTS(md->size) < md->hashsize * MIN_LINK_LENGTH)
+ {
+ debug_malloc_touch(m);
rehash(m, MAP_SLOTS(md->size));
-
+ }
next=m->next;
free_mapping(m);
}