2 #include "encodinggraph.h"
6 EncodingSubGraph::EncodingSubGraph() :
12 uint hashNodeValuePair(NodeValuePair *nvp) {
13 return (uint) (nvp->value ^ ((uintptr_t)nvp->node));
16 bool equalsNodeValuePair(NodeValuePair *nvp1, NodeValuePair *nvp2) {
17 return nvp1->value == nvp2->value && nvp1->node == nvp2->node;
20 int sortEncodingValue(const void *p1, const void *p2) {
21 const EncodingValue * e1 = * (const EncodingValue **) p1;
22 const EncodingValue * e2 = * (const EncodingValue **) p2;
23 uint se1=e1->notequals.getSize();
24 uint se2=e2->notequals.getSize();
33 void EncodingSubGraph::solveEquals() {
34 Vector<EncodingValue *> toEncode;
35 Vector<bool> encodingArray;
36 SetIteratorEncodingValue *valIt=values.iterator();
37 while(valIt->hasNext()) {
38 EncodingValue *ev=valIt->next();
39 if (!ev->inComparison)
45 bsdqsort(toEncode.expose(), toEncode.getSize(), sizeof(EncodingValue *), sortEncodingValue);
46 uint toEncodeSize=toEncode.getSize();
47 for(uint i=0; i<toEncodeSize; i++) {
48 EncodingValue * ev=toEncode.get(i);
49 encodingArray.clear();
50 SetIteratorEncodingValue *conflictIt=ev->notequals.iterator();
51 while(conflictIt->hasNext()) {
52 EncodingValue * conflict=conflictIt->next();
53 if (conflict->assigned) {
54 encodingArray.setExpand(conflict->encoding, true);
59 for(;encoding<encodingArray.getSize();encoding++) {
60 //See if this is unassigned
61 if (!encodingArray.get(encoding))
64 if (encoding > maxEncodingVal)
65 maxEncodingVal = encoding;
66 ev->encoding = encoding;
71 void EncodingSubGraph::solveComparisons() {
72 HashsetEncodingValue discovered;
73 Vector<EncodingValue *> tovisit;
74 SetIteratorEncodingValue *valIt=values.iterator();
75 while(valIt->hasNext()) {
76 EncodingValue *ev=valIt->next();
77 if (discovered.add(ev)) {
79 while(tovisit.getSize()!=0) {
80 EncodingValue * val=tovisit.last(); tovisit.pop();
81 SetIteratorEncodingValue *nextIt=val->larger.iterator();
82 uint minVal = val->encoding + 1;
83 while(nextIt->hasNext()) {
84 EncodingValue *nextVal=nextIt->next();
85 if (nextVal->encoding < minVal) {
86 if (minVal > maxEncodingVal)
87 maxEncodingVal = minVal;
88 nextVal->encoding = minVal;
89 discovered.add(nextVal);
90 tovisit.push(nextVal);
100 uint EncodingSubGraph::estimateNewSize(EncodingSubGraph *sg) {
102 SetIteratorEncodingNode * nit = sg->nodes.iterator();
103 while(nit->hasNext()) {
104 EncodingNode *en = nit->next();
105 uint size=estimateNewSize(en);
113 uint EncodingSubGraph::estimateNewSize(EncodingNode *n) {
114 SetIteratorEncodingEdge * eeit = n->edges.iterator();
115 uint newsize=n->getSize();
116 while(eeit->hasNext()) {
117 EncodingEdge * ee = eeit->next();
118 if (ee->left != NULL && ee->left != n && nodes.contains(ee->left)) {
119 uint intersectSize = n->s->getUnionSize(ee->left->s);
120 if (intersectSize > newsize)
121 newsize = intersectSize;
123 if (ee->right != NULL && ee->right != n && nodes.contains(ee->right)) {
124 uint intersectSize = n->s->getUnionSize(ee->right->s);
125 if (intersectSize > newsize)
126 newsize = intersectSize;
128 if (ee->dst != NULL && ee->dst != n && nodes.contains(ee->dst)) {
129 uint intersectSize = n->s->getUnionSize(ee->dst->s);
130 if (intersectSize > newsize)
131 newsize = intersectSize;
138 void EncodingSubGraph::addNode(EncodingNode *n) {
140 uint newSize=estimateNewSize(n);
141 numElements += n->elements.getSize();
142 if (newSize > encodingSize)
143 encodingSize=newSize;
146 SetIteratorEncodingNode * EncodingSubGraph::nodeIterator() {
147 return nodes.iterator();
150 void EncodingSubGraph::encode() {
151 computeEncodingValue();
152 computeComparisons();
158 void EncodingSubGraph::computeEqualities() {
159 SetIteratorEncodingNode *nodeit=nodes.iterator();
160 while(nodeit->hasNext()) {
161 EncodingNode *node=nodeit->next();
162 generateEquals(node, node);
164 SetIteratorEncodingEdge *edgeit=node->edges.iterator();
165 while(edgeit->hasNext()) {
166 EncodingEdge *edge=edgeit->next();
167 //skip over comparisons as we have already handled them
168 if (edge->numComparisons != 0)
170 if (edge->numEquals == 0)
172 if (edge->left == NULL || !nodes.contains(edge->left))
174 if (edge->right == NULL || !nodes.contains(edge->right))
177 if (edge->left != node)
179 //We have a comparison edge between two nodes in the subgraph
180 //For now we don't support multiple encoding values with the same encoding....
181 //So we enforce != constraints for every Set...
182 if (edge->left != edge->right)
183 generateEquals(edge->left, edge->right);
190 void EncodingSubGraph::computeComparisons() {
191 SetIteratorEncodingNode *nodeit=nodes.iterator();
192 while(nodeit->hasNext()) {
193 EncodingNode *node=nodeit->next();
194 SetIteratorEncodingEdge *edgeit=node->edges.iterator();
195 while(edgeit->hasNext()) {
196 EncodingEdge *edge=edgeit->next();
197 if (edge->numComparisons == 0)
199 if (edge->left == NULL || !nodes.contains(edge->left))
201 if (edge->right == NULL || !nodes.contains(edge->right))
204 if (edge->left != node)
206 //We have a comparison edge between two nodes in the subgraph
207 generateComparison(edge->left, edge->right);
216 void EncodingSubGraph::orderEV(EncodingValue *earlier, EncodingValue *later) {
217 earlier->larger.add(later);
220 void EncodingSubGraph::generateEquals(EncodingNode *left, EncodingNode *right) {
223 uint lSize=lset->getSize(), rSize=rset->getSize();
224 for(uint lindex=0; lindex < lSize; lindex++) {
225 for(uint rindex=0; rindex < rSize; rindex++) {
226 uint64_t lVal=lset->getElement(lindex);
227 NodeValuePair nvp1(left, lVal);
228 EncodingValue *lev = map.get(&nvp1);
229 uint64_t rVal=rset->getElement(rindex);
230 NodeValuePair nvp2(right, rVal);
231 EncodingValue *rev = map.get(&nvp2);
233 if (lev->inComparison && rev->inComparison) {
234 //Need to assign during comparison stage...
235 //Thus promote to comparison
242 lev->notequals.add(rev);
243 rev->notequals.add(lev);
250 void EncodingSubGraph::generateComparison(EncodingNode *left, EncodingNode *right) {
253 uint lindex=0, rindex=0;
254 uint lSize=lset->getSize(), rSize=rset->getSize();
255 uint64_t lVal=lset->getElement(lindex);
256 NodeValuePair nvp1(left, lVal);
257 EncodingValue *lev = map.get(&nvp1);
258 lev->inComparison = true;
259 uint64_t rVal=rset->getElement(rindex);
260 NodeValuePair nvp2(right, rVal);
261 EncodingValue *rev = map.get(&nvp2);
262 rev->inComparison = true;
263 EncodingValue *last = NULL;
265 while(lindex < lSize || rindex < rSize) {
269 if (rev != NULL && lev != rev)
273 if (rev == NULL || lVal < rVal) {
277 if (++lindex < lSize) {
278 lVal=lset->getElement(lindex);
279 NodeValuePair nvpl(left, lVal);
280 lev = map.get(&nvpl);
281 lev->inComparison = true;
288 if (++rindex < rSize) {
289 rVal=rset->getElement(rindex);
290 NodeValuePair nvpr(right, rVal);
291 rev = map.get(&nvpr);
292 rev->inComparison = true;
298 if (++lindex < lSize) {
299 lVal=lset->getElement(lindex);
300 NodeValuePair nvpl(left, lVal);
301 lev = map.get(&nvpl);
302 lev->inComparison = true;
306 if (++rindex < rSize) {
307 rVal=rset->getElement(rindex);
308 NodeValuePair nvpr(right, rVal);
309 rev = map.get(&nvpr);
310 rev->inComparison = true;
317 void EncodingSubGraph::computeEncodingValue() {
318 SetIteratorEncodingNode *nodeit=nodes.iterator();
319 while(nodeit->hasNext()) {
320 EncodingNode *node=nodeit->next();
322 uint setSize = set->getSize();
323 for(uint i=0; i<setSize; i++) {
324 uint64_t val = set->getElement(i);
325 NodeValuePair nvp(node, val);
326 if (!map.contains(&nvp)) {
327 traverseValue(node, val);
334 void EncodingSubGraph::traverseValue(EncodingNode *node, uint64_t value) {
335 EncodingValue *ecv=new EncodingValue(value);
337 HashsetEncodingNode discovered;
338 Vector<EncodingNode *> tovisit;
340 discovered.add(node);
341 while(tovisit.getSize()!=0) {
342 EncodingNode *n=tovisit.last();tovisit.pop();
343 //Add encoding node to structures
345 NodeValuePair *nvp=new NodeValuePair(n, value);
347 SetIteratorEncodingEdge *edgeit=node->edges.iterator();
348 while(edgeit->hasNext()) {
349 EncodingEdge *ee=edgeit->next();
350 if (!discovered.contains(ee->left) && nodes.contains(ee->left) && ee->left->s->exists(value)) {
351 tovisit.push(ee->left);
352 discovered.add(ee->left);
354 if (!discovered.contains(ee->right) && nodes.contains(ee->right) && ee->right->s->exists(value)) {
355 tovisit.push(ee->right);
356 discovered.add(ee->right);