06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | |
|
57d4d3 | 2000-08-23 | Henrik Grubbström (Grubba) | |
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | #include "global.h"
#include "array.h"
#include "multiset.h"
#include "svalue.h"
|
bb55f8 | 1997-03-16 | Fredrik Hübinette (Hubbe) | | #include "pike_macros.h"
|
9aa6fa | 1997-05-19 | Fredrik Hübinette (Hubbe) | | #include "pike_memory.h"
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | #include "error.h"
#include "dynamic_buffer.h"
#include "interpret.h"
#include "builtin_functions.h"
#include "gc.h"
|
7e97c3 | 1999-01-21 | Fredrik Hübinette (Hubbe) | | #include "security.h"
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | |
|
57d4d3 | 2000-08-23 | Henrik Grubbström (Grubba) | | RCSID("$Id: multiset.c,v 1.27 2000/08/23 18:53:47 grubba Exp $");
|
24ddc7 | 1998-03-28 | Henrik Grubbström (Grubba) | |
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct multiset *first_multiset;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | struct multiset *gc_internal_multiset = 0;
static struct multiset *gc_mark_multiset_pos = 0;
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT int multiset_member(struct multiset *l, struct svalue *ind)
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | {
return set_lookup(l->ind, ind) >= 0;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct multiset *allocate_multiset(struct array *ind)
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | {
struct multiset *l;
l=ALLOC_STRUCT(multiset);
|
7bf623 | 2000-04-23 | Martin Stjernholm | | GC_ALLOC(l);
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | l->refs = 1;
l->ind=ind;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | DOUBLELINK(first_multiset, l);
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | |
|
7e97c3 | 1999-01-21 | Fredrik Hübinette (Hubbe) | | INITIALIZE_PROT(l);
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | return l;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void really_free_multiset(struct multiset *l)
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | {
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | if(l->refs)
fatal("really free multiset on multiset with nonzero refs.\n");
#endif
free_array(l->ind);
|
7e97c3 | 1999-01-21 | Fredrik Hübinette (Hubbe) | | FREE_PROT(l);
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | |
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | if (gc_internal_multiset) {
if (l == gc_internal_multiset)
gc_internal_multiset = l->next;
if (l == gc_mark_multiset_pos)
gc_mark_multiset_pos = l->next;
}
DOUBLEUNLINK(first_multiset, l);
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | |
free((char *)l);
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | GC_FREE();
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | }
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void do_free_multiset(struct multiset *l)
|
65b673 | 2000-07-07 | Martin Stjernholm | | {
if (l)
free_multiset(l);
}
|
1a3e1b | 1999-04-13 | Fredrik Hübinette (Hubbe) | |
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void order_multiset(struct multiset *l)
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | {
INT32 *order;
|
361904 | 1999-10-29 | Martin Stjernholm | | int flags;
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | | if(l->ind->size < 2) return;
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | order = get_set_order(l->ind);
|
361904 | 1999-10-29 | Martin Stjernholm | | flags = l->ind->flags;
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | l->ind = order_array(l->ind, order);
|
361904 | 1999-10-29 | Martin Stjernholm | | l->ind->flags = flags;
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | free((char *)order);
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct multiset *mkmultiset(struct array *ind)
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | {
struct multiset *l;
l=allocate_multiset(copy_array(ind));
order_multiset(l);
return l;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void multiset_insert(struct multiset *l,
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct svalue *ind)
{
INT32 i;
i=set_lookup(l->ind, ind);
if(i < 0)
{
|
361904 | 1999-10-29 | Martin Stjernholm | | int flags = l->ind->flags;
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | l->ind=array_insert(l->ind, ind, ~i);
|
361904 | 1999-10-29 | Martin Stjernholm | | l->ind->flags = flags;
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | }
}
#if 0
struct array *multiset_indices(struct multiset *l)
{
return l->ind;
}
#endif
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void multiset_delete(struct multiset *l,struct svalue *ind)
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | {
INT32 i;
i=set_lookup(l->ind, ind);
|
361904 | 1999-10-29 | Martin Stjernholm | | if(i >= 0)
{
int flags = l->ind->flags;
l->ind=array_remove(l->ind, i);
l->ind->flags = flags;
}
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | }
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void check_multiset_for_destruct(struct multiset *l)
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | {
|
361904 | 1999-10-29 | Martin Stjernholm | |
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | INT32 i;
|
361904 | 1999-10-29 | Martin Stjernholm | | int flags = l->ind->flags;
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | while( (i=array_find_destructed_object(l->ind)) >= 0)
l->ind=array_remove(l->ind, i);
|
361904 | 1999-10-29 | Martin Stjernholm | | l->ind->flags = flags;
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | }
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct multiset *copy_multiset(struct multiset *tmp)
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | {
check_multiset_for_destruct(tmp);
return allocate_multiset(copy_array(tmp->ind));
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct multiset *merge_multisets(struct multiset *a,
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct multiset *b,
INT32 operator)
{
struct multiset *ret;
INT32 *zipper;
check_multiset_for_destruct(a);
check_multiset_for_destruct(b);
zipper=merge(a->ind,b->ind,operator);
ret=allocate_multiset(array_zip(a->ind,b->ind,zipper));
free((char *)zipper);
return ret;
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT struct multiset *add_multisets(struct svalue *argp,INT32 args)
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | {
struct multiset *ret,*a,*b;
switch(args)
{
case 0:
ret=allocate_multiset(allocate_array_no_init(0,0));
break;
case 1:
ret=copy_multiset(argp->u.multiset);
break;
case 2:
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | ret=merge_multisets(argp[0].u.multiset,argp[1].u.multiset,PIKE_ARRAY_OP_ADD);
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | break;
case 3:
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | a=merge_multisets(argp[0].u.multiset, argp[1].u.multiset, PIKE_ARRAY_OP_ADD);
ret=merge_multisets(a, argp[2].u.multiset, PIKE_ARRAY_OP_ADD);
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | free_multiset(a);
break;
default:
a=add_multisets(argp,args/2);
b=add_multisets(argp+args/2,args-args/2);
|
71f3a2 | 1998-11-22 | Fredrik Hübinette (Hubbe) | | ret=merge_multisets(a,b,PIKE_ARRAY_OP_ADD);
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | free_multiset(a);
free_multiset(b);
break;
}
return ret;
}
int multiset_equal_p(struct multiset *a, struct multiset *b, struct processing *p)
{
if(a == b) return 1;
check_multiset_for_destruct(a);
return array_equal_p(a->ind, b->ind, p);
}
void describe_multiset(struct multiset *l,struct processing *p,int indent)
{
struct processing doing;
int e;
char buf[40];
if(!l->ind->size)
{
my_strcat("(< >)");
return;
}
doing.next=p;
doing.pointer_a=(void *)l;
for(e=0;p;e++,p=p->next)
{
if(p->pointer_a == (void *)l)
{
sprintf(buf,"@%d",e);
my_strcat(buf);
return;
}
}
|
57d4d3 | 2000-08-23 | Henrik Grubbström (Grubba) | |
if (l->ind->size == 1) {
my_strcat("(< /* 1 element */\n");
} else {
sprintf(buf, "(< /* %ld elements */\n", (long)l->ind->size);
my_strcat(buf);
}
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | describe_array_low(l->ind,&doing,indent);
my_putchar('\n');
for(e=2; e<indent; e++) my_putchar(' ');
my_strcat(">)");
}
node * make_node_from_multiset(struct multiset *l)
{
if(check_that_array_is_constant(l->ind))
{
struct svalue s;
s.type=T_MULTISET;
s.subtype=0;
s.u.multiset=l;
return mkconstantsvaluenode(&s);
}else{
return mkefuncallnode("mkmultiset",make_node_from_array(l->ind));
}
}
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | PMOD_EXPORT void f_aggregate_multiset(INT32 args)
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | {
struct multiset *l;
f_aggregate(args);
l=allocate_multiset(sp[-1].u.array);
order_multiset(l);
sp[-1].type=T_MULTISET;
sp[-1].u.multiset=l;
}
struct multiset *copy_multiset_recursively(struct multiset *l,
struct processing *p)
{
struct processing doing;
struct multiset *ret;
doing.next=p;
doing.pointer_a=(void *)l;
for(;p;p=p->next)
{
if(p->pointer_a == (void *)l)
{
ret=(struct multiset *)p->pointer_b;
|
d6ac73 | 1998-04-20 | Henrik Grubbström (Grubba) | | add_ref(ret);
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | return ret;
}
}
ret=allocate_multiset( & empty_array );
doing.pointer_b=(void *)ret;
ret->ind=copy_array_recursively(l->ind,&doing);
order_multiset(ret);
return ret;
}
void gc_mark_multiset_as_referenced(struct multiset *l)
{
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | if(gc_mark(l)) {
if (l == gc_mark_multiset_pos)
gc_mark_multiset_pos = l->next;
if (l == gc_internal_multiset)
gc_internal_multiset = l->next;
else {
DOUBLEUNLINK(first_multiset, l);
DOUBLELINK(first_multiset, l);
}
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | gc_mark_array_as_referenced(l->ind);
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | }
}
|
45d87e | 2000-07-18 | Martin Stjernholm | | void real_gc_cycle_check_multiset(struct multiset *l, int weak)
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | {
|
45d87e | 2000-07-18 | Martin Stjernholm | | GC_CYCLE_ENTER(l, weak) {
gc_cycle_check_array(l->ind, 0);
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | } GC_CYCLE_LEAVE;
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | }
|
7bf623 | 2000-04-23 | Martin Stjernholm | | #ifdef PIKE_DEBUG
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | unsigned gc_touch_all_multisets(void)
|
7bf623 | 2000-04-23 | Martin Stjernholm | | {
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | unsigned n = 0;
|
7bf623 | 2000-04-23 | Martin Stjernholm | | struct multiset *l;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | if (first_multiset && first_multiset->prev)
fatal("Error in multiset link list.\n");
|
7bf623 | 2000-04-23 | Martin Stjernholm | | for(l=first_multiset;l;l=l->next) {
debug_gc_touch(l);
n++;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | if (l->next && l->next->prev != l)
fatal("Error in multiset link list.\n");
|
7bf623 | 2000-04-23 | Martin Stjernholm | | }
return n;
}
#endif
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | void gc_check_all_multisets(void)
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | {
struct multiset *l;
for(l=first_multiset;l;l=l->next)
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | debug_gc_check(l->ind, T_MULTISET, l);
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | }
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | void gc_mark_all_multisets(void)
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | {
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | gc_mark_multiset_pos = gc_internal_multiset;
while (gc_mark_multiset_pos) {
struct multiset *l = gc_mark_multiset_pos;
gc_mark_multiset_pos = l->next;
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | if(gc_is_referenced(l))
gc_mark_multiset_as_referenced(l);
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | }
}
void gc_cycle_check_all_multisets(void)
{
struct multiset *l;
for (l = gc_internal_multiset; l; l = l->next) {
|
45d87e | 2000-07-18 | Martin Stjernholm | | real_gc_cycle_check_multiset(l, 0);
gc_cycle_run_queue();
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | }
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | }
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | void gc_free_all_unreferenced_multisets(void)
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | {
struct multiset *l,*next;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | for(l=gc_internal_multiset;l;l=next)
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | {
if(gc_do_free(l))
{
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | |
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | free_svalues(ITEM(l->ind), l->ind->size, l->ind->type_field);
l->ind->size=0;
|
e2d9e6 | 2000-06-10 | Martin Stjernholm | | gc_free_extra_ref(l);
|
69ee4b | 2000-04-06 | Fredrik Hübinette (Hubbe) | | SET_NEXT_AND_FREE(l, free_multiset);
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | }else{
next=l->next;
}
}
}
|
c3c703 | 1996-12-04 | Fredrik Hübinette (Hubbe) | | void count_memory_in_multisets(INT32 *num_, INT32 *size_)
{
struct multiset *m;
INT32 size=0, num=0;
for(m=first_multiset;m;m=m->next)
{
num++;
size+=sizeof(struct multiset);
}
*num_=num;
*size_=size;
}
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | |
|