Creating a runtime directory...
authorbdemsky <bdemsky>
Fri, 27 Feb 2004 20:34:48 +0000 (20:34 +0000)
committerbdemsky <bdemsky>
Fri, 27 Feb 2004 20:34:48 +0000 (20:34 +0000)
Repair/RepairCompiler/MCC/IR/RepairGenerator.java
Repair/RepairCompiler/MCC/IR/UpdateNode.java
Repair/RepairCompiler/MCC/Runtime/SimpleHash.cc [new file with mode: 0755]
Repair/RepairCompiler/MCC/Runtime/SimpleHash.h [new file with mode: 0755]

index 325168939022858fed8c395dd80a85c517d4a003..db37cdeae089742a51b41b9c5509fff833bb24c5 100755 (executable)
@@ -79,20 +79,22 @@ public class RepairGenerator {
        generate_updates();
     }
 
        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);        
     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();
        /* 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();) {
        }
 
        for(Iterator it=termination.updatenodes.iterator();it.hasNext();) {
@@ -108,23 +110,23 @@ public class RepairGenerator {
                switch(mun.op) {
                case MultUpdateNode.ADD:
                    if (isrelation) {
                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 {
                    } 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; }
                     };
                    }
                    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();
                    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) {
                    for(int j=0;j<r.numQuantifiers();j++) {
                        Quantifier q=r.getQuantifier(j);
                        if (q instanceof SetQuantifier) {
@@ -148,7 +150,7 @@ public class RepairGenerator {
                    CodeWriter cr2 = new StandardCodeWriter(outputaux) {
                         public SymbolTable getSymbolTable() { return st2; }
                     };
                    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:
                    craux.endblock();
                    break;
                case MultUpdateNode.MODIFY:
index ce6288667904368575482d0259c7a0852c7e24a4..66aff5570ca0f28c4871dbc60fd51c2eb1fe0afc 100755 (executable)
@@ -1,5 +1,6 @@
 package MCC.IR;
 import java.util.*;
 package MCC.IR;
 import java.util.*;
+import MCC.State;
 
 class UpdateNode {
     Vector updates;
 
 class UpdateNode {
     Vector updates;
@@ -193,14 +194,137 @@ class UpdateNode {
     public Updates getUpdate(int i) {
        return (Updates)updates.get(i);
     }
     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 (!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:
 
            switch(u.getType()) {
            case Updates.EXPR:
@@ -290,17 +414,6 @@ class UpdateNode {
        }
     }
 
        }
     }
 
-    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);
     private void generate_bindings(CodeWriter cr, String slot0, String slot1) {
        for(int i=0;i<bindings.size();i++) {
            Binding b=(Binding)bindings.get(i);
diff --git a/Repair/RepairCompiler/MCC/Runtime/SimpleHash.cc b/Repair/RepairCompiler/MCC/Runtime/SimpleHash.cc
new file mode 100755 (executable)
index 0000000..7206571
--- /dev/null
@@ -0,0 +1,440 @@
+#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;
+}
diff --git a/Repair/RepairCompiler/MCC/Runtime/SimpleHash.h b/Repair/RepairCompiler/MCC/Runtime/SimpleHash.h
new file mode 100755 (executable)
index 0000000..50020d8
--- /dev/null
@@ -0,0 +1,199 @@
+#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
+