generate_updates();
}
+ String ststate="state";
+ String stmodel="model";
+ String strepairtable="repairtable";
+ String stleft="left";
+ String stright="right";
+
private void generate_updates() {
int count=0;
CodeWriter crhead = new StandardCodeWriter(outputhead);
CodeWriter craux = new StandardCodeWriter(outputaux);
- String state="state";
- String model="model";
- String repairtable="repairtable";
- String left="left";
- String right="right";
+
/* Rewrite globals */
for (Iterator it=this.state.stGlobals.descriptors();it.hasNext();) {
VarDescriptor vd=(VarDescriptor)it.next();
- craux.outputline("#define "+vd.getSafeSymbol()+" "+state+"->"+vd.getSafeSymbol());
+ craux.outputline("#define "+vd.getSafeSymbol()+" "+ststate+"->"+vd.getSafeSymbol());
}
for(Iterator it=termination.updatenodes.iterator();it.hasNext();) {
switch(mun.op) {
case MultUpdateNode.ADD:
if (isrelation) {
- crhead.outputline("void "+methodname+"("+name+"_state * " +state+","+name+" * "+model+", RepairHash * "+repairtable+", int "+left+", int "+right+");");
- craux.outputline("void "+methodname+"("+name+"_state * "+ state+","+name+" * "+model+", RepairHash * "+repairtable+", int "+left+", int "+right+")");
+ crhead.outputline("void "+methodname+"("+name+"_state * " +ststate+","+name+" * "+stmodel+", RepairHash * "+strepairtable+", int "+stleft+", int "+stright+");");
+ craux.outputline("void "+methodname+"("+name+"_state * "+ ststate+","+name+" * "+stmodel+", RepairHash * "+strepairtable+", int "+stleft+", int "+stright+")");
} else {
- crhead.outputline("void "+methodname+"("+name+"_state * "+ state+","+name+" * "+model+", RepairHash * "+repairtable+", int "+left+");");
- craux.outputline("void "+methodname+"("+name+"_state * "+state+","+name+" * "+model+", RepairHash * "+repairtable+", int "+left+")");
+ crhead.outputline("void "+methodname+"("+name+"_state * "+ ststate+","+name+" * "+stmodel+", RepairHash * "+strepairtable+", int "+stleft+");");
+ craux.outputline("void "+methodname+"("+name+"_state * "+ststate+","+name+" * "+stmodel+", RepairHash * "+strepairtable+", int "+stleft+")");
}
craux.startblock();
final SymbolTable st = un.getRule().getSymbolTable();
CodeWriter cr = new StandardCodeWriter(outputaux) {
public SymbolTable getSymbolTable() { return st; }
};
- un.generate(cr, false, left,right);
+ un.generate(cr, false, stleft,stright,this);
craux.endblock();
break;
case MultUpdateNode.REMOVE:
Rule r=un.getRule();
- String methodcall="void "+methodname+"("+name+"_state * "+state+","+name+" * "+model+", RepairHash * "+repairtable;
+ String methodcall="void "+methodname+"("+name+"_state * "+ststate+","+name+" * "+stmodel+", RepairHash * "+strepairtable;
for(int j=0;j<r.numQuantifiers();j++) {
Quantifier q=r.getQuantifier(j);
if (q instanceof SetQuantifier) {
CodeWriter cr2 = new StandardCodeWriter(outputaux) {
public SymbolTable getSymbolTable() { return st2; }
};
- un.generate(cr2, true, null,null);
+ un.generate(cr2, true, null,null,this);
craux.endblock();
break;
case MultUpdateNode.MODIFY:
package MCC.IR;
import java.util.*;
+import MCC.State;
class UpdateNode {
Vector updates;
public Updates getUpdate(int i) {
return (Updates)updates.get(i);
}
- public void generate(CodeWriter cr, boolean removal, String slot0, String slot1) {
+
+ private MultUpdateNode getMultUpdateNode(boolean negate, Descriptor d, RepairGenerator rg) {
+ Termination termination=rg.termination;
+ MultUpdateNode mun=null;
+ GraphNode gn;
+ if (negate)
+ gn=(GraphNode)termination.abstractremove.get(d);
+ else
+ gn=(GraphNode)termination.abstractadd.get(d);
+ TermNode tn=(TermNode)gn.getOwner();
+ for(Iterator edgeit=gn.edges();edgeit.hasNext();) {
+ GraphNode gn2=((GraphNode.Edge) edgeit.next()).getTarget();
+ if (!rg.removed.contains(gn2)) {
+ TermNode tn2=(TermNode)gn2.getOwner();
+ if (tn2.getType()==TermNode.UPDATE) {
+ mun=tn2.getUpdate();
+ break;
+ }
+ }
+ }
+ if (mun==null)
+ throw new Error("Can't find update node!");
+ return mun;
+ }
+
+ public void generate_abstract(CodeWriter cr, boolean removal, String slot0, String slot1, Updates u, RepairGenerator rg) {
+ State state=rg.state;
+ Expr abstractexpr=u.getLeftExpr();
+ boolean negated=u.negate;
+ Descriptor d=null;
+ Expr left=null;
+ Expr right=null;
+ boolean istuple=false;
+ if (abstractexpr instanceof TupleOfExpr) {
+ TupleOfExpr toe=(TupleOfExpr) abstractexpr;
+ d=toe.relation;
+ left=toe.left;
+ right=toe.right;
+ istuple=true;
+ } else if (abstractexpr instanceof TupleOfExpr) {
+ ElementOfExpr eoe=(ElementOfExpr) abstractexpr;
+ d=eoe.set;
+ left=eoe.element;
+ istuple=false;
+ } else {
+ throw new Error("Unsupported Expr");
+ }
+ MultUpdateNode mun=getMultUpdateNode(negated,d,rg);
+ VarDescriptor leftvar=VarDescriptor.makeNew("leftvar");
+ VarDescriptor rightvar=VarDescriptor.makeNew("rightvar");
+ left.generate(cr, leftvar);
+ if (istuple)
+ right.generate(cr,rightvar);
+
+ if (negated) {
+ if (istuple) {
+ RelationDescriptor rd=(RelationDescriptor)d;
+ boolean usageimage=rd.testUsage(RelationDescriptor.IMAGE);
+ boolean usageinvimage=rd.testUsage(RelationDescriptor.INVIMAGE);
+ if (usageimage)
+ cr.outputline(rg.stmodel+"->"+rd.getJustSafeSymbol() + "_hash->remove((int)" + leftvar.getSafeSymbol() + ", (int)" + rightvar.getSafeSymbol() + ");");
+ if (usageinvimage)
+ cr.outputline(rg.stmodel+"->"+rd.getJustSafeSymbol() + "_hashinv->remove((int)" + rightvar.getSafeSymbol() + ", (int)" + leftvar.getSafeSymbol() + ");");
+
+ for(int i=0;i<state.vRules.size();i++) {
+ Rule r=(Rule)state.vRules.get(i);
+ if (r.getInclusion().getTargetDescriptors().contains(rd)) {
+ for(int j=0;j<mun.numUpdates();j++) {
+ UpdateNode un=mun.getUpdate(i);
+ if (un.getRule()==r) {
+ /* Update for rule rule r */
+ String name=(String)rg.updatenames.get(un);
+ cr.outputline(rg.strepairtable+"->addrelation("+rd.getNum()+","+r.getNum()+","+leftvar.getSafeSymbol()+","+rightvar.getSafeSymbol()+",(int) &"+name+");");
+ }
+ }
+ }
+ }
+ } else {
+ SetDescriptor sd=(SetDescriptor) d;
+ cr.outputline(rg.stmodel+"->"+sd.getJustSafeSymbol() + "_hash->remove((int)" + leftvar.getSafeSymbol() + ", (int)" + leftvar.getSafeSymbol() + ");");
+
+ for(int i=0;i<state.vRules.size();i++) {
+ Rule r=(Rule)state.vRules.get(i);
+ if (r.getInclusion().getTargetDescriptors().contains(sd)) {
+ for(int j=0;j<mun.numUpdates();j++) {
+ UpdateNode un=mun.getUpdate(i);
+ if (un.getRule()==r) {
+ /* Update for rule rule r */
+ String name=(String)rg.updatenames.get(un);
+ cr.outputline(rg.strepairtable+"->addset("+sd.getNum()+","+r.getNum()+","+leftvar.getSafeSymbol()+",(int) &"+name+");");
+ }
+ }
+ }
+ }
+ }
+ } else {
+ /* Generate update */
+ if (istuple) {
+ RelationDescriptor rd=(RelationDescriptor) d;
+ boolean usageimage=rd.testUsage(RelationDescriptor.IMAGE);
+ boolean usageinvimage=rd.testUsage(RelationDescriptor.INVIMAGE);
+ if (usageimage)
+ cr.outputline(rg.stmodel+"->"+rd.getJustSafeSymbol() + "_hash->add((int)" + leftvar.getSafeSymbol() + ", (int)" + rightvar.getSafeSymbol() + ");");
+ if (usageinvimage)
+ cr.outputline(rg.stmodel+"->"+rd.getJustSafeSymbol() + "_hashinv->add((int)" + rightvar.getSafeSymbol() + ", (int)" + leftvar.getSafeSymbol() + ");");
+
+ UpdateNode un=mun.getUpdate(0);
+ String name=(String)rg.updatenames.get(un);
+ cr.outputline(name+"(this,"+rg.stmodel+","+rg.strepairtable+","+leftvar.getSafeSymbol()+","+rightvar.getSafeSymbol()+");");
+ } else {
+ SetDescriptor sd=(SetDescriptor)d;
+ cr.outputline(rg.stmodel+"->"+sd.getJustSafeSymbol() + "_hash->add((int)" + leftvar.getSafeSymbol() + ", (int)" + leftvar.getSafeSymbol() + ");");
+
+ UpdateNode un=mun.getUpdate(0);
+ /* Update for rule rule r */
+ String name=(String)rg.updatenames.get(un);
+ cr.outputline(name+"(this,"+rg.stmodel+","+rg.strepairtable+","+leftvar.getSafeSymbol()+");");
+ }
+ }
+
+ }
+
+ public void generate(CodeWriter cr, boolean removal, String slot0, String slot1, RepairGenerator rg) {
if (!removal)
generate_bindings(cr, slot0,slot1);
for(int i=0;i<updates.size();i++) {
Updates u=(Updates)updates.get(i);
VarDescriptor right=VarDescriptor.makeNew("right");
- if (u.getType()==Updates.ABSTRACT)
- throw new Error("Abstract update not implemented");
+ if (u.getType()==Updates.ABSTRACT) {
+ generate_abstract(cr, removal, slot0, slot1, u, rg);
+ }
switch(u.getType()) {
case Updates.EXPR:
}
}
- private int bitmask(int bits) {
- int mask = 0;
-
- for (int i = 0; i < bits; i++) {
- mask <<= 1;
- mask += 1;
- }
-
- return mask;
- }
-
private void generate_bindings(CodeWriter cr, String slot0, String slot1) {
for(int i=0;i<bindings.size();i++) {
Binding b=(Binding)bindings.get(i);
--- /dev/null
+#include "SimpleHash.h"
+#include <stdarg.h>
+#include <stdlib.h>
+
+/* LINKED HASH NODE ****************************************************/
+
+LinkedHashNode::LinkedHashNode(int key, int data, LinkedHashNode *next) {
+ this->key = key;
+ this->data = data;
+ this->next = next;
+ this->lnext=0;
+ this->lprev=0;
+}
+
+LinkedHashNode::LinkedHashNode() {
+ this->key = -1;
+ this->data = -1;
+ this->next = 0;
+ this->lnext=0;
+ this->lprev=0;
+}
+
+/* SIMPLE LIST ****************************************************/
+
+SimpleList::SimpleList() {
+ ptr = 0;
+ head.next = 0;
+}
+
+void SimpleList::reset() {
+ // ptr = head.next;
+ ptr = &head;
+}
+
+int SimpleList::hasMoreElements() {
+ // return (ptr != 0);
+ return (ptr->next != 0);
+}
+
+int SimpleList::nextElement() {
+ ptr = ptr->next;
+ return ptr->data;
+
+ //int data = ptr->data;
+ //ptr = ptr->next;
+ //return data;
+}
+
+void SimpleList::add(int data) {
+ LinkedHashNode *cur = &head;
+ while (cur->next) {
+ cur = cur->next;
+ if (cur->data == data) {
+ return; // no duplicates
+ }
+ }
+ cur->next = new LinkedHashNode(0, data, 0);
+ return;
+}
+
+int SimpleList::contains(int data) {
+ LinkedHashNode *cur = &head;
+ while (cur->next) {
+ cur = cur->next;
+ if (cur->data == data) {
+ return 1; // found!
+ }
+ }
+ return 0;
+}
+
+/* WORK LIST ****************************************************/
+
+WorkList::WorkList() {
+ head=(struct ListNode *) malloc(sizeof(struct ListNode));
+ tail=head;
+ headoffset=0;
+ tailoffset=0;
+}
+
+int WorkList::hasMoreElements() {
+ // return (ptr != 0);
+ return ((head!=tail)||(headoffset!=tailoffset));
+}
+
+int WorkList::getid() {
+ return tail->data[tailoffset];
+}
+
+int WorkList::gettype() {
+ return tail->data[tailoffset+1];
+}
+
+int WorkList::getlvalue() {
+ return tail->data[tailoffset+2];
+}
+
+int WorkList::getrvalue() {
+ return tail->data[tailoffset+3];
+}
+
+WorkList::~WorkList() {
+ struct ListNode *ptr=tail;
+ while(ptr) {
+ struct ListNode *oldptr=ptr;
+ ptr=ptr->next;
+ free(oldptr);
+ }
+}
+
+void WorkList::pop() {
+ int newoffset=tailoffset+4;
+ struct ListNode *ptr=tail;
+ if (newoffset>=WLISTSIZE) {
+ newoffset-=WLISTSIZE;
+ struct ListNode *oldptr=ptr;
+ ptr=ptr->next;
+ free(oldptr);
+ }
+ tail=ptr;
+ tailoffset=newoffset;
+}
+
+void WorkList::add(int id,int type, int lvalue, int rvalue) {
+ if (headoffset==WLISTSIZE) {
+ head->next=(struct ListNode *)malloc(sizeof(struct ListNode));
+ headoffset=0;
+ head=head->next;
+ }
+ head->data[headoffset++]=id;
+ head->data[headoffset++]=type;
+ head->data[headoffset++]=lvalue;
+ head->data[headoffset++]=rvalue;
+}
+
+/* SIMPLE HASH ********************************************************/
+SimpleIterator* SimpleHash::iterator() {
+ return new SimpleIterator(listhead,this);
+}
+
+void SimpleHash::iterator(SimpleIterator & it) {
+ it.table=this;
+ it.cur=listhead;
+ it.index=0;
+}
+
+SimpleHash::SimpleHash(int size) {
+ if (size <= 0) {
+ throw SimpleHashException();
+ }
+ this->size = size;
+ this->bucket = (struct SimpleNode **) calloc(sizeof(struct SimpleNode *)*size,1);
+ /* Set allocation blocks*/
+ this->listhead=(struct ArraySimple *) calloc(sizeof(struct ArraySimple),1);
+ this->listtail=this->listhead;
+ this->tailindex=0;
+ /*Set data counts*/
+ this->numparents = 0;
+ this->numchildren = 0;
+ this->numelements = 0;
+}
+
+SimpleHash::~SimpleHash() {
+ free(bucket);
+ struct ArraySimple *ptr=listhead;
+ while(ptr) {
+ struct ArraySimple *next=ptr->nextarray;
+ free(ptr);
+ ptr=next;
+ }
+}
+
+void SimpleHash::addParent(SimpleHash* parent) {
+ parents[numparents++] = parent;
+ parent->addChild(this);
+}
+
+void SimpleHash::addChild(SimpleHash *child) {
+ children[numchildren++]=child;
+}
+
+int SimpleHash::remove(int key, int data) {
+ unsigned int hashkey = (unsigned int)key % size;
+
+ struct SimpleNode **ptr = &bucket[hashkey];
+
+ for (int i = 0; i < numchildren; i++) {
+ children[i]->remove(key, data);
+ }
+
+ while (*ptr) {
+ if ((*ptr)->key == key && (*ptr)->data == data) {
+ struct SimpleNode *toremove=*ptr;
+ *ptr=(*ptr)->next;
+
+ toremove->inuse=0; /* Marked as unused */
+
+ numelements--;
+ return 1;
+ }
+ ptr = &((*ptr)->next);
+ }
+
+ return 0;
+}
+
+
+
+int SimpleHash::add(int key, int data) {
+ unsigned int hashkey = (unsigned int)key % size;
+
+ struct SimpleNode **ptr = &bucket[hashkey];
+
+ /* check that this key/object pair isn't already here */
+ // TBD can be optimized for set v. relation */
+ while (*ptr) {
+ if ((*ptr)->key == key && (*ptr)->data == data) {
+ return 0;
+ }
+ ptr = &((*ptr)->next);
+ }
+ if (tailindex==ARRAYSIZE) {
+ listtail->nextarray=(struct ArraySimple *) calloc(sizeof(struct ArraySimple),1);
+ tailindex=0;
+ listtail=listtail->nextarray;
+ }
+
+ *ptr = &listtail->nodes[tailindex++];
+ (*ptr)->key=key;
+ (*ptr)->data=data;
+ (*ptr)->inuse=1;
+
+ numelements++;
+
+ for (int i = 0; i < numparents; i++) {
+ parents[i]->add(key, data);
+ }
+
+ return 1;
+}
+
+bool SimpleHash::contains(int key) {
+ unsigned int hashkey = (unsigned int)key % size;
+
+ struct SimpleNode *ptr = bucket[hashkey];
+ while (ptr) {
+ if (ptr->key == key) {
+ // we already have this object
+ // stored in the hash so just return
+ return true;
+ }
+ ptr = ptr->next;
+ }
+ return false;
+}
+
+bool SimpleHash::contains(int key, int data) {
+ unsigned int hashkey = (unsigned int)key % size;
+
+ struct SimpleNode *ptr = bucket[hashkey];
+ while (ptr) {
+ if (ptr->key == key && ptr->data == data) {
+ // we already have this object
+ // stored in the hash so just return
+ return true;
+ }
+ ptr = ptr->next;
+ }
+ return false;
+}
+
+int SimpleHash::count(int key) {
+ unsigned int hashkey = (unsigned int)key % size;
+ int count = 0;
+
+ struct SimpleNode *ptr = bucket[hashkey];
+ while (ptr) {
+ if (ptr->key == key) {
+ count++;
+ }
+ ptr = ptr->next;
+ }
+ return count;
+}
+
+int SimpleHash::get(int key, int&data) {
+ unsigned int hashkey = (unsigned int)key % size;
+
+ struct SimpleNode *ptr = bucket[hashkey];
+ while (ptr) {
+ if (ptr->key == key) {
+ data = ptr->data;
+ return 1; // success
+ }
+ ptr = ptr->next;
+ }
+
+ return 0; // failure
+}
+
+int SimpleHash::countdata(int data) {
+ int count = 0;
+ struct ArraySimple *ptr = listhead;
+ while(ptr) {
+ if (ptr->nextarray) {
+ for(int i=0;i<ARRAYSIZE;i++)
+ if (ptr->nodes[i].data == data
+ &&ptr->nodes[i].inuse) {
+ count++;
+ }
+ } else {
+ for(int i=0;i<tailindex;i++)
+ if (ptr->nodes[i].data == data
+ &&ptr->nodes[i].inuse) {
+ count++;
+ }
+ }
+ ptr = ptr->nextarray;
+ }
+ return count;
+}
+
+SimpleHashException::SimpleHashException() {}
+// ************************************************************
+
+
+RepairHashNode::RepairHashNode(int setrelation, int rule, int lvalue, int rvalue, int data){
+ this->setrelation = setrelation;
+ this->lvalue=lvalue;
+ this->rvalue=rvalue;
+ this->data = data;
+ this->next = 0;
+ this->lnext=0;
+ this->rule=rule;
+}
+
+// ************************************************************
+
+RepairHash::RepairHash(int size) {
+ if (size <= 0) {
+ throw SimpleHashException();
+ }
+ this->size = size;
+ this->bucket = new RepairHashNode* [size];
+ for (int i=0;i<size;i++)
+ bucket[i]=0;
+ this->nodelist=0;
+ this->numelements = 0;
+}
+
+RepairHash::RepairHash() {
+ RepairHash(100);
+}
+
+RepairHash::~RepairHash() {
+ delete [] this->bucket;
+ RepairHashNode *ptr=nodelist;
+ while(ptr) {
+ RepairHashNode *next=ptr->lnext;
+ delete ptr;
+ ptr=next;
+ }
+}
+
+#define SETFLAG (1<<31)
+
+int RepairHash::addset(int setv, int rule, int value, int data) {
+ return addrelation(setv||SETFLAG, rule, value,0,data);
+}
+
+int RepairHash::addrelation(int relation, int rule, int lvalue, int rvalue, int data) {
+ unsigned int hashkey = ((unsigned int)(relation ^ rule ^ lvalue ^ rvalue)) % size;
+
+ RepairHashNode **ptr = &bucket[hashkey];
+
+ /* check that this key/object pair isn't already here */
+ // TBD can be optimized for set v. relation */
+ while (*ptr) {
+ if ((*ptr)->setrelation == relation &&
+ (*ptr)->rule==rule &&
+ (*ptr)->lvalue==lvalue &&
+ (*ptr)->rvalue==rvalue &&
+ (*ptr)->data == data) {
+ return 0;
+ }
+ ptr = &((*ptr)->next);
+ }
+
+ *ptr = new RepairHashNode(relation,rule,lvalue,rvalue, data);
+ (*ptr)->lnext=nodelist;
+ nodelist=*ptr;
+ numelements++;
+ return 1;
+}
+
+bool RepairHash::containsset(int setv, int rule, int value) {
+ return containsrelation(setv||SETFLAG, rule, value,0);
+}
+
+bool RepairHash::containsrelation(int relation, int rule, int lvalue, int rvalue) {
+ unsigned int hashkey = ((unsigned int)(relation ^ rule ^ lvalue ^ rvalue)) % size;
+
+ RepairHashNode **ptr = &bucket[hashkey];
+
+ /* check that this key/object pair isn't already here */
+ // TBD can be optimized for set v. relation */
+ while (*ptr) {
+ if ((*ptr)->setrelation == relation &&
+ (*ptr)->rule==rule &&
+ (*ptr)->lvalue==lvalue &&
+ (*ptr)->rvalue==rvalue) {
+ return true;
+ }
+ ptr = &((*ptr)->next);
+ }
+ return false;
+}
+
+int RepairHash::getset(int setv, int rule, int value) {
+ return getrelation(setv||SETFLAG, rule, value,0);
+}
+
+int RepairHash::getrelation(int relation, int rule, int lvalue,int rvalue) {
+ unsigned int hashkey = ((unsigned int)(relation ^ rule ^ lvalue ^ rvalue)) % size;
+
+ RepairHashNode **ptr = &bucket[hashkey];
+
+ /* check that this key/object pair isn't already here */
+ // TBD can be optimized for set v. relation */
+ while (*ptr) {
+ if ((*ptr)->setrelation == relation &&
+ (*ptr)->rule==rule &&
+ (*ptr)->lvalue==lvalue &&
+ (*ptr)->rvalue==rvalue) {
+ return (*ptr)->data;
+ }
+ ptr = &((*ptr)->next);
+ }
+ return 0;
+}
--- /dev/null
+#ifndef SIMPLEHASH_H
+#define SIMPLEHASH_H
+
+/* LinkedHashNode *****************************************************/
+
+class LinkedHashNode {
+
+public:
+ LinkedHashNode *next;
+ LinkedHashNode *lnext,*lprev;
+ int data;
+ int key;
+
+
+ LinkedHashNode(int key, int data, LinkedHashNode *next);
+ LinkedHashNode();
+
+};
+
+/* SimpleList *********************************************************/
+
+class SimpleList {
+private:
+ LinkedHashNode head;
+ LinkedHashNode *ptr;
+public:
+ SimpleList();
+ void add(int data);
+ int contains(int data);
+ void reset();
+ int hasMoreElements();
+ int nextElement();
+};
+
+
+/* WorkList *********************************************************/
+#define WLISTSIZE 4*100
+
+class WorkList {
+private:
+ struct ListNode *head;
+ struct ListNode *tail;
+ int headoffset;
+ int tailoffset;
+
+public:
+ WorkList();
+ ~WorkList();
+ void add(int id, int type, int lvalue, int rvalue);
+ int hasMoreElements();
+ int getid();
+ int gettype();
+ int getlvalue();
+ int getrvalue();
+ void pop();
+};
+
+struct ListNode {
+ int data[WLISTSIZE];
+ ListNode *next;
+};
+/* SimpleHash *********************************************************/
+class SimpleIterator;
+
+class SimpleHash {
+private:
+ int numelements;
+ int size;
+ struct SimpleNode **bucket;
+ struct ArraySimple *listhead;
+ struct ArraySimple *listtail;
+
+
+ int numparents;
+ int numchildren;
+ SimpleHash* parents[10];
+ SimpleHash* children[10];
+ void addChild(SimpleHash* child);
+public:
+ int tailindex;
+ SimpleHash(int size=100);
+ ~SimpleHash();
+ int add(int key, int data);
+ int remove(int key, int data);
+ bool contains(int key);
+ bool contains(int key, int data);
+ int get(int key, int& data);
+ int countdata(int data);
+ void addParent(SimpleHash* parent);
+ int firstkey();
+ SimpleIterator* iterator();
+ void iterator(SimpleIterator & it);
+ inline int count() {
+ return numelements;
+ }
+ int count(int key);
+
+};
+
+/* SimpleHashExcepion *************************************************/
+
+
+/* SimpleIterator *****************************************************/
+#define ARRAYSIZE 100
+
+struct SimpleNode {
+ struct SimpleNode *next;
+ int data;
+ int key;
+ int inuse;
+};
+
+struct ArraySimple {
+ struct SimpleNode nodes[ARRAYSIZE];
+ struct ArraySimple * nextarray;
+};
+
+
+class SimpleIterator {
+ public:
+
+ struct ArraySimple *cur;
+ int index;
+ SimpleHash * table;
+ inline SimpleIterator() {}
+
+ inline SimpleIterator(struct ArraySimple *start, SimpleHash *t) {
+ cur = start;
+ table=t;
+ index=0;
+ }
+
+ inline int hasNext() {
+ while((index==ARRAYSIZE)||!cur->nodes[index].inuse) {
+ if (cur->nextarray==0 &&
+ index==table->tailindex)
+ return 0;
+ index++;
+ if (index==ARRAYSIZE) {
+ index=0;
+ cur=cur->nextarray;
+ }
+ }
+ if (cur->nodes[index].inuse)
+ return 1;
+ else
+ return 0;
+ }
+
+ inline int next() {
+ return cur->nodes[index++].data;
+ }
+
+ inline int key() {
+ return cur->nodes[index].key;
+ }
+};
+
+/* SimpleHashExcepion *************************************************/
+
+class SimpleHashException {
+public:
+ SimpleHashException();
+};
+
+class RepairHashNode {
+ public:
+ RepairHashNode *next;
+ RepairHashNode *lnext;
+ int data;
+ int setrelation;
+ int lvalue;
+ int rvalue;
+ int rule;
+ RepairHashNode(int setrelation, int rule, int lvalue, int rvalue, int data);
+};
+
+class RepairHash {
+
+private:
+ int numelements;
+ int size;
+ RepairHashNode **bucket;
+ RepairHashNode *nodelist;
+
+public:
+ RepairHash();
+ RepairHash(int size);
+ ~RepairHash();
+ int addset(int setv, int rule, int value, int data);
+ int addrelation(int relation, int rule, int lvalue, int rvalue, int data);
+ bool containsset(int setv, int rule, int value);
+ bool containsrelation(int relation, int rule, int lvalue, int rvalue);
+ int getset(int setv, int rule, int value);
+ int getrelation(int relation, int rule, int lvalue, int rvalue);
+};
+
+#endif
+