if (isRange) {
return element >= low && element <= high;
} else {
- uint size = members->getSize();
- for (uint i = 0; i < size; i++) {
- if (element == members->get(i))
+ //Use Binary Search
+ uint low=0;
+ uint high=members->getSize()-1;
+ while(true) {
+ uint middle=(low+high)/2;
+ uint64_t val=members->get(middle);
+ if (element < val) {
+ high=middle;
+ if (middle==low)
+ return false;
+ } else if (element > val) {
+ low=middle;
+ if (middle==high)
+ return false;
+ } else {
return true;
+ }
}
- return false;
}
}
return s;
}
+uint Set::getUnionSize(Set *s) {
+ uint sSize = s->getSize();
+ uint thisSize = getSize();
+ uint sIndex = 0;
+ uint thisIndex = 0;
+ uint sum = 0;
+ uint64_t sValue = s->getElement(sIndex);
+ uint64_t thisValue = getElement(thisIndex);
+ while(thisIndex < thisSize && sIndex < sSize) {
+ if (sValue < thisValue) {
+ sValue = s->getElement(++sIndex);
+ sum++;
+ } else if (thisValue < sValue) {
+ thisValue = getElement(++thisIndex);
+ sum++;
+ } else {
+ thisValue = getElement(++thisIndex);
+ sValue = s->getElement(++sIndex);
+ sum++;
+ }
+ }
+ sum += (thisSize - thisIndex) + (sSize - sIndex);
+
+ return sum;
+}
void Set::serialize(Serializer* serializer){
if(serializer->isSerialized(this))
uint64_t getNewUniqueItem() {return low++;}
uint64_t getMemberAt(uint index);
uint64_t getElement(uint index);
+ uint getUnionSize(Set *s);
virtual bool isMutableSet() {return false;}
virtual Set *clone(CSolver *solver, CloneMap *map);
virtual void serialize(Serializer* serializer);
uint64_t low;//also used to count unique items
uint64_t high;
Vector<uint64_t> *members;
-
};
int intcompare(const void *p1, const void *p2);
#include "set.h"
#include "csolver.h"
#include "tunable.h"
+#include "qsort.h"
+#include "subgraph.h"
+#include "elementencoding.h"
#include "boolean.h"
EncodingGraph::EncodingGraph(CSolver * _solver) :
solver(_solver) {
-
+}
+int sortEncodingEdge(const void * p1, const void *p2) {
+ const EncodingEdge * e1 = * (const EncodingEdge **) p1;
+ const EncodingEdge * e2 = * (const EncodingEdge **) p2;
+ uint64_t v1 = e1->getValue();
+ uint64_t v2 = e2->getValue();
+ if (v1 < v2)
+ return 1;
+ else if (v1 == v2)
+ return 0;
+ else
+ return -1;
}
void EncodingGraph::buildGraph() {
ASSERT(0);
}
}
+ bsdqsort(edgeVector.expose(), edgeVector.getSize(), sizeof(EncodingEdge *), sortEncodingEdge);
+ decideEdges();
+}
+
+void EncodingGraph::encode() {
+ SetIteratorEncodingSubGraph * itesg=subgraphs.iterator();
+ while(itesg->hasNext()) {
+ EncodingSubGraph *sg=itesg->next();
+ sg->encode();
+ }
+ delete itesg;
+
+ ElementIterator it(solver);
+ while(it.hasNext()) {
+ Element * e = it.next();
+ switch(e->type) {
+ case ELEMSET:
+ case ELEMFUNCRETURN: {
+ ElementEncoding *encoding=e->getElementEncoding();
+ if (encoding->getElementEncodingType() == ELEM_UNASSIGNED) {
+ //Do assignment...
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
}
void EncodingGraph::mergeNodes(EncodingNode *first, EncodingNode *second) {
EncodingSubGraph *graph2=graphMap.get(second);
if (graph1 == NULL && graph2 == NULL) {
graph1 = new EncodingSubGraph();
+ subgraphs.add(graph1);
graphMap.put(first, graph1);
graph1->addNode(first);
}
graph1->addNode(node);
graphMap.put(node, graph1);
}
+ subgraphs.remove(graph2);
delete nodeit;
delete graph2;
} else {
}
}
+uint convertSize(uint cost) {
+ cost = 1.2 * cost; // fudge factor
+ return NEXTPOW2(cost);
+}
+
+void EncodingGraph::decideEdges() {
+ uint size=edgeVector.getSize();
+ for(uint i=0; i<size; i++) {
+ EncodingEdge *ee = edgeVector.get(i);
+ EncodingNode *left = ee->left;
+ EncodingNode *right = ee->right;
+
+ if (ee->encoding != EDGE_UNASSIGNED ||
+ left->encoding != BINARYINDEX ||
+ right->encoding != BINARYINDEX)
+ continue;
+
+ uint64_t eeValue = ee->getValue();
+ if (eeValue == 0)
+ return;
+
+ EncodingSubGraph *leftGraph = graphMap.get(left);
+ EncodingSubGraph *rightGraph = graphMap.get(right);
+ if (leftGraph == NULL && rightGraph !=NULL) {
+ EncodingNode *tmp = left; left=right; right=tmp;
+ EncodingSubGraph *tmpsg = leftGraph; leftGraph = rightGraph; rightGraph = tmpsg;
+ }
+
+ uint leftSize=0, rightSize=0, newSize=0;
+ uint64_t totalCost=0;
+ if (leftGraph == NULL && rightGraph == NULL) {
+ leftSize=convertSize(left->getSize());
+ rightSize=convertSize(right->getSize());
+ newSize=convertSize(left->s->getUnionSize(right->s));
+ newSize=(leftSize > newSize) ? leftSize: newSize;
+ newSize=(rightSize > newSize) ? rightSize: newSize;
+ totalCost = (newSize - leftSize) * left->elements.getSize() +
+ (newSize - rightSize) * right->elements.getSize();
+ } else if (leftGraph != NULL && rightGraph == NULL) {
+ leftSize=convertSize(leftGraph->encodingSize);
+ rightSize=convertSize(right->getSize());
+ newSize=convertSize(leftGraph->estimateNewSize(right));
+ newSize=(leftSize > newSize) ? leftSize: newSize;
+ newSize=(rightSize > newSize) ? rightSize: newSize;
+ totalCost = (newSize - leftSize) * leftGraph->numElements +
+ (newSize - rightSize) * right->elements.getSize();
+ } else {
+ //Neither are null
+ leftSize=convertSize(leftGraph->encodingSize);
+ rightSize=convertSize(rightGraph->encodingSize);
+ newSize=convertSize(leftGraph->estimateNewSize(rightGraph));
+ newSize=(leftSize > newSize) ? leftSize: newSize;
+ newSize=(rightSize > newSize) ? rightSize: newSize;
+ totalCost = (newSize - leftSize) * leftGraph->numElements +
+ (newSize - rightSize) * rightGraph->numElements;
+ }
+ double conversionfactor = 0.5;
+ if ((totalCost * conversionfactor) < eeValue) {
+ //add the edge
+ mergeNodes(left, right);
+ }
+ }
+}
+
static TunableDesc EdgeEncodingDesc(EDGE_UNASSIGNED, EDGE_MATCH, EDGE_UNASSIGNED);
EncodingEdge * EncodingGraph::getEdge(EncodingNode *left, EncodingNode *right, EncodingNode *dst) {
v2=v1;
v1=tmp;
}
- result->setEncoding((EdgeEncodingType)solver->getTuner()->getVarTunable(v1, v2, EDGEENCODING, &EdgeEncodingDesc));
+
+ if ((left != NULL && left->encoding==BINARYINDEX) &&
+ (right != NULL) && right->encoding==BINARYINDEX) {
+ EdgeEncodingType type=(EdgeEncodingType)solver->getTuner()->getVarTunable(v1, v2, EDGEENCODING, &EdgeEncodingDesc);
+ result->setEncoding(type);
+ if (type == EDGE_MATCH) {
+ mergeNodes(left, right);
+ }
+ }
edgeMap.put(result, result);
+ edgeVector.push(result);
+ if (left != NULL)
+ left->edges.add(result);
+ if (right != NULL)
+ right->edges.add(result);
+ if (dst != NULL)
+ dst->edges.add(result);
}
return result;
}
EncodingNode::EncodingNode(Set *_s) :
- s(_s),
- numElements(0) {
+ s(_s) {
}
-uint EncodingNode::getSize() {
+uint EncodingNode::getSize() const {
return s->getSize();
}
-VarType EncodingNode::getType() {
+VarType EncodingNode::getType() const {
return s->getType();
}
encodingMap.put(s, n);
}
n->addElement(e);
- if (discovered.add(e))
- n->numElements++;
return n;
}
return e1->left == e2->left && e1->right == e2->right && e1->dst == e2->dst;
}
-EncodingSubGraph::EncodingSubGraph() {
-}
-
-void EncodingSubGraph::addNode(EncodingNode *n) {
- nodes.add(n);
- Set *s=n->s;
- uint size=s->getSize();
- for(uint i=0; i<size; i++) {
- uint64_t val=s->getElement(i);
- values.add(val);
- }
+uint64_t EncodingEdge::getValue() const {
+ uint lSize = (left != NULL) ? left->getSize() : 1;
+ uint rSize = (right != NULL) ? right->getSize() : 1;
+ uint min = (lSize < rSize) ? lSize : rSize;
+ return numEquals * min + numComparisons * lSize * rSize;
}
-SetIteratorEncodingNode * EncodingSubGraph::nodeIterator() {
- return nodes.iterator();
-}
-uint EncodingSubGraph::computeIntersection(Set *s) {
- uint intersect=0;
- uint size=s->getSize();
- for(uint i=0; i<size; i++) {
- uint64_t val=s->getElement(i);
- if (values.contains(val))
- intersect++;
- }
- return intersect;
-}
-
-uint EncodingSubGraph::computeIntersection(EncodingSubGraph *g) {
- if (g->values.getSize() > values.getSize()) {
- //iterator over smaller set
- return g->computeIntersection(this);
- }
-
- uint intersect=0;
- SetIterator64Int * iter=g->values.iterator();
- while(iter->hasNext()) {
- uint64_t val=iter->next();
- if (values.contains(val))
- intersect++;
- }
- delete iter;
- return intersect;
-}
#define ENCODINGGRAPH_H
#include "classlist.h"
#include "structs.h"
-
-uint hashEncodingEdge(EncodingEdge *edge);
-bool equalsEncodingEdge(EncodingEdge *e1, EncodingEdge *e2);
-class EncodingSubGraph;
-
-
-typedef Hashtable<EncodingEdge *, EncodingEdge *, uintptr_t, PTRSHIFT, hashEncodingEdge, equalsEncodingEdge> HashtableEdge;
-typedef Hashset<EncodingNode *, uintptr_t, PTRSHIFT> HashsetEncodingNode;
-typedef SetIterator<EncodingNode *, uintptr_t, PTRSHIFT> SetIteratorEncodingNode;
-typedef Hashtable<EncodingNode *, EncodingSubGraph *, uintptr_t, PTRSHIFT> HashtableNodeToSubGraph;
+#include "graphstructs.h"
class EncodingGraph {
public:
EncodingGraph(CSolver * solver);
void buildGraph();
+ void encode();
CMEMALLOC;
private:
CSolver * solver;
HashtableEncoding encodingMap;
HashtableEdge edgeMap;
+ Vector<EncodingEdge *> edgeVector;
HashsetElement discovered;
HashtableNodeToSubGraph graphMap;
-
+ HashsetEncodingSubGraph subgraphs;
+ void decideEdges();
void mergeNodes(EncodingNode *first, EncodingNode *second);
void processElement(Element *e);
void processFunction(ElementFunction *f);
public:
EncodingNode(Set *_s);
void addElement(Element *e);
- uint getSize();
- VarType getType();
+ uint getSize() const;
+ VarType getType() const;
void setEncoding(ElementEncodingType e) {encoding=e;}
CMEMALLOC;
private:
Set *s;
HashsetElement elements;
- uint numElements;
+ HashsetEncodingEdge edges;
ElementEncodingType encoding;
friend class EncodingGraph;
friend class EncodingSubGraph;
};
-class EncodingSubGraph {
- public:
- EncodingSubGraph();
- void addNode(EncodingNode *n);
- SetIteratorEncodingNode * nodeIterator();
- uint computeIntersection(Set *s);
- uint computeIntersection(EncodingSubGraph *g);
-
- CMEMALLOC;
- private:
- HashsetEncodingNode nodes;
- Hashset64Int values;
-};
-
enum EdgeEncodingType { EDGE_UNASSIGNED, EDGE_BREAK, EDGE_MATCH};
typedef enum EdgeEncodingType EdgeEncodingType;
EncodingEdge(EncodingNode *_l, EncodingNode *_r);
EncodingEdge(EncodingNode *_l, EncodingNode *_r, EncodingNode *_d);
void setEncoding(EdgeEncodingType e) {encoding=e;}
+ uint64_t getValue() const;
CMEMALLOC;
private:
friend uint hashEncodingEdge(EncodingEdge *edge);
friend bool equalsEncodingEdge(EncodingEdge *e1, EncodingEdge *e2);
friend class EncodingGraph;
+ friend class EncodingSubGraph;
};
#endif
--- /dev/null
+#ifndef GRAPHSTRUCTS_H
+#define GRAPHSTRUCTS_H
+#include "classlist.h"
+#include "structs.h"
+
+uint hashEncodingEdge(EncodingEdge *edge);
+bool equalsEncodingEdge(EncodingEdge *e1, EncodingEdge *e2);
+class EncodingSubGraph;
+
+
+typedef Hashtable<EncodingEdge *, EncodingEdge *, uintptr_t, PTRSHIFT, hashEncodingEdge, equalsEncodingEdge> HashtableEdge;
+typedef Hashset<EncodingNode *, uintptr_t, PTRSHIFT> HashsetEncodingNode;
+typedef SetIterator<EncodingNode *, uintptr_t, PTRSHIFT> SetIteratorEncodingNode;
+typedef Hashset<EncodingEdge *, uintptr_t, PTRSHIFT> HashsetEncodingEdge;
+typedef SetIterator<EncodingEdge *, uintptr_t, PTRSHIFT> SetIteratorEncodingEdge;
+
+typedef Hashtable<EncodingNode *, EncodingSubGraph *, uintptr_t, PTRSHIFT> HashtableNodeToSubGraph;
+typedef Hashset<EncodingSubGraph *, uintptr_t, PTRSHIFT> HashsetEncodingSubGraph;
+typedef SetIterator<EncodingSubGraph *, uintptr_t, PTRSHIFT> SetIteratorEncodingSubGraph;
+#endif
--- /dev/null
+#include "subgraph.h"
+#include "encodinggraph.h"
+#include "set.h"
+#include "qsort.h"
+
+EncodingSubGraph::EncodingSubGraph() :
+ encodingSize(0),
+ numElements(0),
+ maxEncodingVal(0) {
+}
+
+uint hashNodeValuePair(NodeValuePair *nvp) {
+ return (uint) (nvp->value ^ ((uintptr_t)nvp->node));
+}
+
+bool equalsNodeValuePair(NodeValuePair *nvp1, NodeValuePair *nvp2) {
+ return nvp1->value == nvp2->value && nvp1->node == nvp2->node;
+}
+
+int sortEncodingValue(const void *p1, const void *p2) {
+ const EncodingValue * e1 = * (const EncodingValue **) p1;
+ const EncodingValue * e2 = * (const EncodingValue **) p2;
+ uint se1=e1->notequals.getSize();
+ uint se2=e2->notequals.getSize();
+ if (se1 > se2)
+ return -1;
+ else if (se2 == se1)
+ return 0;
+ else
+ return 1;
+}
+
+void EncodingSubGraph::solveEquals() {
+ Vector<EncodingValue *> toEncode;
+ Vector<bool> encodingArray;
+ SetIteratorEncodingValue *valIt=values.iterator();
+ while(valIt->hasNext()) {
+ EncodingValue *ev=valIt->next();
+ if (!ev->inComparison)
+ toEncode.push(ev);
+ else
+ ev->assigned = true;
+ }
+ delete valIt;
+ bsdqsort(toEncode.expose(), toEncode.getSize(), sizeof(EncodingValue *), sortEncodingValue);
+ uint toEncodeSize=toEncode.getSize();
+ for(uint i=0; i<toEncodeSize; i++) {
+ EncodingValue * ev=toEncode.get(i);
+ encodingArray.clear();
+ SetIteratorEncodingValue *conflictIt=ev->notequals.iterator();
+ while(conflictIt->hasNext()) {
+ EncodingValue * conflict=conflictIt->next();
+ if (conflict->assigned) {
+ encodingArray.setExpand(conflict->encoding, true);
+ }
+ }
+ delete conflictIt;
+ uint encoding=0;
+ for(;encoding<encodingArray.getSize();encoding++) {
+ //See if this is unassigned
+ if (!encodingArray.get(encoding))
+ break;
+ }
+ if (encoding > maxEncodingVal)
+ maxEncodingVal = encoding;
+ ev->encoding = encoding;
+ ev->assigned = true;
+ }
+}
+
+void EncodingSubGraph::solveComparisons() {
+ HashsetEncodingValue discovered;
+ Vector<EncodingValue *> tovisit;
+ SetIteratorEncodingValue *valIt=values.iterator();
+ while(valIt->hasNext()) {
+ EncodingValue *ev=valIt->next();
+ if (discovered.add(ev)) {
+ tovisit.push(ev);
+ while(tovisit.getSize()!=0) {
+ EncodingValue * val=tovisit.last(); tovisit.pop();
+ SetIteratorEncodingValue *nextIt=val->larger.iterator();
+ uint minVal = val->encoding + 1;
+ while(nextIt->hasNext()) {
+ EncodingValue *nextVal=nextIt->next();
+ if (nextVal->encoding < minVal) {
+ if (minVal > maxEncodingVal)
+ maxEncodingVal = minVal;
+ nextVal->encoding = minVal;
+ discovered.add(nextVal);
+ tovisit.push(nextVal);
+ }
+ }
+ delete nextIt;
+ }
+ }
+ }
+ delete valIt;
+}
+
+uint EncodingSubGraph::estimateNewSize(EncodingSubGraph *sg) {
+ uint newSize=0;
+ SetIteratorEncodingNode * nit = sg->nodes.iterator();
+ while(nit->hasNext()) {
+ EncodingNode *en = nit->next();
+ uint size=estimateNewSize(en);
+ if (size > newSize)
+ newSize = size;
+ }
+ delete nit;
+ return newSize;
+}
+
+uint EncodingSubGraph::estimateNewSize(EncodingNode *n) {
+ SetIteratorEncodingEdge * eeit = n->edges.iterator();
+ uint newsize=n->getSize();
+ while(eeit->hasNext()) {
+ EncodingEdge * ee = eeit->next();
+ if (ee->left != NULL && ee->left != n && nodes.contains(ee->left)) {
+ uint intersectSize = n->s->getUnionSize(ee->left->s);
+ if (intersectSize > newsize)
+ newsize = intersectSize;
+ }
+ if (ee->right != NULL && ee->right != n && nodes.contains(ee->right)) {
+ uint intersectSize = n->s->getUnionSize(ee->right->s);
+ if (intersectSize > newsize)
+ newsize = intersectSize;
+ }
+ if (ee->dst != NULL && ee->dst != n && nodes.contains(ee->dst)) {
+ uint intersectSize = n->s->getUnionSize(ee->dst->s);
+ if (intersectSize > newsize)
+ newsize = intersectSize;
+ }
+ }
+ delete eeit;
+ return newsize;
+}
+
+void EncodingSubGraph::addNode(EncodingNode *n) {
+ nodes.add(n);
+ uint newSize=estimateNewSize(n);
+ numElements += n->elements.getSize();
+ if (newSize > encodingSize)
+ encodingSize=newSize;
+}
+
+SetIteratorEncodingNode * EncodingSubGraph::nodeIterator() {
+ return nodes.iterator();
+}
+
+void EncodingSubGraph::encode() {
+ computeEncodingValue();
+ computeComparisons();
+ computeEqualities();
+ solveComparisons();
+ solveEquals();
+}
+
+void EncodingSubGraph::computeEqualities() {
+ SetIteratorEncodingNode *nodeit=nodes.iterator();
+ while(nodeit->hasNext()) {
+ EncodingNode *node=nodeit->next();
+ generateEquals(node, node);
+
+ SetIteratorEncodingEdge *edgeit=node->edges.iterator();
+ while(edgeit->hasNext()) {
+ EncodingEdge *edge=edgeit->next();
+ //skip over comparisons as we have already handled them
+ if (edge->numComparisons != 0)
+ continue;
+ if (edge->numEquals == 0)
+ continue;
+ if (edge->left == NULL || !nodes.contains(edge->left))
+ continue;
+ if (edge->right == NULL || !nodes.contains(edge->right))
+ continue;
+ //examine only once
+ if (edge->left != node)
+ continue;
+ //We have a comparison edge between two nodes in the subgraph
+ //For now we don't support multiple encoding values with the same encoding....
+ //So we enforce != constraints for every Set...
+ if (edge->left != edge->right)
+ generateEquals(edge->left, edge->right);
+ }
+ delete edgeit;
+ }
+ delete nodeit;
+}
+
+void EncodingSubGraph::computeComparisons() {
+ SetIteratorEncodingNode *nodeit=nodes.iterator();
+ while(nodeit->hasNext()) {
+ EncodingNode *node=nodeit->next();
+ SetIteratorEncodingEdge *edgeit=node->edges.iterator();
+ while(edgeit->hasNext()) {
+ EncodingEdge *edge=edgeit->next();
+ if (edge->numComparisons == 0)
+ continue;
+ if (edge->left == NULL || !nodes.contains(edge->left))
+ continue;
+ if (edge->right == NULL || !nodes.contains(edge->right))
+ continue;
+ //examine only once
+ if (edge->left != node)
+ continue;
+ //We have a comparison edge between two nodes in the subgraph
+ generateComparison(edge->left, edge->right);
+ }
+ delete edgeit;
+ }
+ delete nodeit;
+
+
+}
+
+void EncodingSubGraph::orderEV(EncodingValue *earlier, EncodingValue *later) {
+ earlier->larger.add(later);
+}
+
+void EncodingSubGraph::generateEquals(EncodingNode *left, EncodingNode *right) {
+ Set *lset=left->s;
+ Set *rset=right->s;
+ uint lSize=lset->getSize(), rSize=rset->getSize();
+ for(uint lindex=0; lindex < lSize; lindex++) {
+ for(uint rindex=0; rindex < rSize; rindex++) {
+ uint64_t lVal=lset->getElement(lindex);
+ NodeValuePair nvp1(left, lVal);
+ EncodingValue *lev = map.get(&nvp1);
+ uint64_t rVal=rset->getElement(rindex);
+ NodeValuePair nvp2(right, rVal);
+ EncodingValue *rev = map.get(&nvp2);
+ if (lev != rev) {
+ if (lev->inComparison && rev->inComparison) {
+ //Need to assign during comparison stage...
+ //Thus promote to comparison
+ if (lVal < rVal) {
+ orderEV(lev, rev);
+ } else {
+ orderEV(rev, lev);
+ }
+ } else {
+ lev->notequals.add(rev);
+ rev->notequals.add(lev);
+ }
+ }
+ }
+ }
+}
+
+void EncodingSubGraph::generateComparison(EncodingNode *left, EncodingNode *right) {
+ Set *lset=left->s;
+ Set *rset=right->s;
+ uint lindex=0, rindex=0;
+ uint lSize=lset->getSize(), rSize=rset->getSize();
+ uint64_t lVal=lset->getElement(lindex);
+ NodeValuePair nvp1(left, lVal);
+ EncodingValue *lev = map.get(&nvp1);
+ lev->inComparison = true;
+ uint64_t rVal=rset->getElement(rindex);
+ NodeValuePair nvp2(right, rVal);
+ EncodingValue *rev = map.get(&nvp2);
+ rev->inComparison = true;
+ EncodingValue *last = NULL;
+
+ while(lindex < lSize || rindex < rSize) {
+ if (last != NULL) {
+ if (lev != NULL)
+ orderEV(last, lev);
+ if (rev != NULL && lev != rev)
+ orderEV(last, rev);
+ }
+ if (lev != rev) {
+ if (rev == NULL || lVal < rVal) {
+ if (rev != NULL)
+ orderEV(lev, rev);
+ last = lev;
+ if (++lindex < lSize) {
+ lVal=lset->getElement(lindex);
+ NodeValuePair nvpl(left, lVal);
+ lev = map.get(&nvpl);
+ lev->inComparison = true;
+ } else
+ lev = NULL;
+ } else {
+ if (lev != NULL)
+ orderEV(rev, lev);
+ last = rev;
+ if (++rindex < rSize) {
+ rVal=rset->getElement(rindex);
+ NodeValuePair nvpr(right, rVal);
+ rev = map.get(&nvpr);
+ rev->inComparison = true;
+ } else
+ rev = NULL;
+ }
+ } else {
+ last = lev;
+ if (++lindex < lSize) {
+ lVal=lset->getElement(lindex);
+ NodeValuePair nvpl(left, lVal);
+ lev = map.get(&nvpl);
+ lev->inComparison = true;
+ } else
+ lev = NULL;
+
+ if (++rindex < rSize) {
+ rVal=rset->getElement(rindex);
+ NodeValuePair nvpr(right, rVal);
+ rev = map.get(&nvpr);
+ rev->inComparison = true;
+ } else
+ rev = NULL;
+ }
+ }
+}
+
+void EncodingSubGraph::computeEncodingValue() {
+ SetIteratorEncodingNode *nodeit=nodes.iterator();
+ while(nodeit->hasNext()) {
+ EncodingNode *node=nodeit->next();
+ Set * set = node->s;
+ uint setSize = set->getSize();
+ for(uint i=0; i<setSize; i++) {
+ uint64_t val = set->getElement(i);
+ NodeValuePair nvp(node, val);
+ if (!map.contains(&nvp)) {
+ traverseValue(node, val);
+ }
+ }
+ }
+ delete nodeit;
+}
+
+void EncodingSubGraph::traverseValue(EncodingNode *node, uint64_t value) {
+ EncodingValue *ecv=new EncodingValue(value);
+ values.add(ecv);
+ HashsetEncodingNode discovered;
+ Vector<EncodingNode *> tovisit;
+ tovisit.push(node);
+ discovered.add(node);
+ while(tovisit.getSize()!=0) {
+ EncodingNode *n=tovisit.last();tovisit.pop();
+ //Add encoding node to structures
+ ecv->nodes.add(n);
+ NodeValuePair *nvp=new NodeValuePair(n, value);
+ map.put(nvp, ecv);
+ SetIteratorEncodingEdge *edgeit=node->edges.iterator();
+ while(edgeit->hasNext()) {
+ EncodingEdge *ee=edgeit->next();
+ if (!discovered.contains(ee->left) && nodes.contains(ee->left) && ee->left->s->exists(value)) {
+ tovisit.push(ee->left);
+ discovered.add(ee->left);
+ }
+ if (!discovered.contains(ee->right) && nodes.contains(ee->right) && ee->right->s->exists(value)) {
+ tovisit.push(ee->right);
+ discovered.add(ee->right);
+ }
+ }
+ delete edgeit;
+ }
+}
+
--- /dev/null
+#ifndef SUBGRAPH_H
+#define SUBGRAPH_H
+#include "classlist.h"
+#include "structs.h"
+#include "graphstructs.h"
+
+class NodeValuePair {
+ public:
+ NodeValuePair(EncodingNode *n, uint64_t val) : node(n), value(val) {}
+ EncodingNode *node;
+ uint64_t value;
+};
+
+class EncodingValue;
+
+typedef Hashset<EncodingValue *, uintptr_t, PTRSHIFT> HashsetEncodingValue;
+typedef SetIterator<EncodingValue *, uintptr_t, PTRSHIFT> SetIteratorEncodingValue;
+
+class EncodingValue {
+ public:
+ EncodingValue(uint64_t _val) : value(_val), encoding(0), inComparison(false), assigned(false) {}
+ void merge(EncodingValue *value);
+ uint64_t value;
+ uint encoding;
+ bool inComparison;
+ bool assigned;
+ HashsetEncodingNode nodes;
+ HashsetEncodingValue larger;
+ HashsetEncodingValue notequals;
+};
+
+uint hashNodeValuePair(NodeValuePair *nvp);
+bool equalsNodeValuePair(NodeValuePair *nvp1, NodeValuePair *nvp2);
+
+typedef Hashtable<NodeValuePair *, EncodingValue *, uintptr_t, 0, hashNodeValuePair, equalsNodeValuePair> NVPMap;
+
+class EncodingSubGraph {
+ public:
+ EncodingSubGraph();
+ void addNode(EncodingNode *n);
+ SetIteratorEncodingNode * nodeIterator();
+ void encode();
+
+ CMEMALLOC;
+ private:
+ uint estimateNewSize(EncodingNode *n);
+ uint estimateNewSize(EncodingSubGraph *sg);
+ void traverseValue(EncodingNode *node, uint64_t value);
+ void computeEncodingValue();
+ void computeComparisons();
+ void computeEqualities();
+ void solveComparisons();
+ void solveEquals();
+ void generateComparison(EncodingNode *left, EncodingNode *right);
+ void generateEquals(EncodingNode *left, EncodingNode *right);
+ void orderEV(EncodingValue *smaller, EncodingValue *larger);
+
+ HashsetEncodingValue values;
+ HashsetEncodingNode nodes;
+ NVPMap map;
+ uint encodingSize;
+ uint numElements;
+ uint maxEncodingVal;
+
+ friend class EncodingGraph;
+};
+
+#endif
}
}
- type get(uint index) {
+ type get(uint index) const {
return array[index];
}
array[index] = item;
}
- uint getSize() {
+ uint getSize() const {
return size;
}
size--;
}
- type last() {
+ type last() const {
return array[size - 1];
}
array[size++] = item;
}
- type get(uint index) {
+ type get(uint index) const {
return array[index];
}
array[index] = item;
}
- uint getSize() {
+ uint getSize() const {
return size;
}
return true;
}
- unsigned int getSize() {
+ unsigned int getSize() const {
return table->getSize();
}
- bool isEmpty() {
+ bool isEmpty() const {
return getSize() == 0;
}
void setVector ## name(Vector ## name * vector, uint index, type item) { \
vector->array[index] = item; \
} \
- uint getSizeVector ## name(Vector ## name * vector) { \
+ uint getSizeVector ## name(const Vector ## name * vector) { \
return vector->size; \
} \
void deleteVector ## name(Vector ## name * vector) { \