Moved the interpreter
[repair.git] / Repair / RepairInterpreter / Relation.cc
1 #include "Relation.h"
2 #include "element.h"
3 #include "GenericHashtable.h"
4 #include "set.h"
5 #include "stdio.h"
6
7
8 // class Tuple
9
10 Tuple::Tuple(void *l,void *r) {
11   left=l;
12   right=r;
13 }
14  
15 Tuple::Tuple() {
16   left=NULL;right=NULL;
17 }
18
19 bool Tuple::isnull() {
20   if (left==NULL&&right==NULL)
21     return true;
22   else
23     return false;
24 }
25
26
27 // class WorkRelation
28
29 WorkRelation::WorkRelation() {
30   forward=genallocatehashtable((unsigned int (*)(void *)) & hashelement,(int (*)(void *,void *)) & elementequals);
31   inverse=genallocatehashtable((unsigned int (*)(void *)) & hashelement,(int (*)(void *,void *)) & elementequals);
32   flag=false;
33 }
34
35 WorkRelation::WorkRelation(bool flag) {
36   forward=genallocatehashtable(NULL,NULL);
37   inverse=genallocatehashtable(NULL,NULL);
38   this->flag=true;
39 }
40
41 Tuple WorkRelation::firstelement() {
42   if (forward->list==NULL)
43     return Tuple();
44   void * forwardfirst=forward->list->src;
45   WorkSet *ws=getset(forwardfirst);
46   return Tuple(forwardfirst,ws->firstelement());
47 }
48  
49 Tuple WorkRelation::getnextelement(void *left,void *right) {
50   WorkSet *ws=getset(left);
51   if (ws->getnextelement(right)!=NULL) {
52     return Tuple(left, ws->getnextelement(right));
53   }
54   void *leftnext=getnext(forward,left);
55   if (leftnext!=NULL) {
56     return Tuple(leftnext,getset(leftnext)->firstelement());
57   } else return Tuple();
58 }
59
60 bool WorkRelation::contains(void *key, void*object) {
61   /*Set up forward reference*/
62   if(!gencontains(forward,key))
63     return false;
64   WorkSet *w=(WorkSet *)gengettable(forward,key);
65   return w->contains(object);
66 }
67
68 void WorkRelation::put(void *key, void*object) {
69   {    /*Set up forward reference*/
70     if(!gencontains(forward,key)) {
71       WorkSet *w=flag?new WorkSet(true):new WorkSet();
72       genputtable(forward,key,w);
73     }
74     WorkSet *w=(WorkSet *)gengettable(forward,key);
75     w->addobject(object);
76   }
77   {/*Set up backwars reference*/
78     if(!gencontains(inverse,object)) {
79       WorkSet *w=flag?new WorkSet(true):new WorkSet();
80       genputtable(inverse,object,w);
81     }
82     WorkSet *w=(WorkSet *) gengettable(inverse,object);
83     w->addobject(key);
84   }
85 }
86   
87 void WorkRelation::remove(void *key, void *object) {
88   { /*Set up forward reference*/
89     WorkSet *w=(WorkSet *)gengettable(forward,key);
90     w->removeobject(object);
91     if (w->isEmpty()) {
92       genfreekey(forward,key);
93       delete(w);
94     }
95   }
96   { /*Set up backwards reference*/
97     WorkSet *w=(WorkSet *)gengettable(inverse,object);
98     w->removeobject(key);
99     if (w->isEmpty()) {
100       genfreekey(inverse,object);
101       delete(w);
102     }
103   }
104 }
105
106 WorkSet* WorkRelation::getset(void *key) {
107   if (gencontains(forward,key))
108     return (WorkSet *) gengettable(forward,key);
109   else return NULL;
110 }
111
112 void* WorkRelation::getobj(void *key) {
113   WorkSet *ws=getset(key);
114   if (ws==NULL)
115     return NULL;
116   return ws->firstelement();
117 }
118
119 WorkSet* WorkRelation::invgetset(void *key) {
120   if (gencontains(inverse,key))
121     return (WorkSet *) gengettable(inverse,key);
122   else
123     return NULL;
124 }
125
126 void* WorkRelation::invgetobj(void *key) {
127   WorkSet *ws=invgetset(key);
128   if (ws==NULL)
129     return NULL;
130   return ws->firstelement();
131 }
132
133 WorkRelation::~WorkRelation() {
134   destroyer(forward);
135   destroyer(inverse);
136 }
137
138 void WorkRelation::destroyer(struct genhashtable *d) {
139   struct geniterator *it=gengetiterator(d);
140   while (true) {
141     void *key=gennext(it);
142     if (key==NULL)
143       break;
144     WorkSet *ws=(WorkSet *)gengettable(d,key);
145     delete(ws);
146   }
147   genfreeiterator(it);
148   genfreehashtable(d);
149 }
150
151 void WorkRelation::print()
152 {
153   printf("\n");
154   Tuple tuple = firstelement();
155   while (!tuple.isnull())
156     {
157       Element *l = (Element *) tuple.left;
158       Element *r = (Element *) tuple.right;
159       printf("("); l->print(); printf(", "); r->print(); printf(")\n");
160       tuple = getnextelement(tuple.left, tuple.right);
161     }
162 }