edits
[satune.git] / src / AST / asthash.cc
index 9fed23623616133b54dfa36e6fcf54bb6470d70f..347e5faa7e9f5fa67dd47404b81b925c9eb4488f 100644 (file)
@@ -4,7 +4,10 @@
 #include "boolean.h"
 #include "element.h"
 
-bool compareArray(Array<Boolean *> *inputs1, Array<Boolean *> *inputs2) {
+#define HASHNEXT(hash, newval) {hash += newval; hash += hash << 10; hash ^= hash >> 6;}
+#define HASHFINAL(hash) {hash += hash << 3; hash ^= hash >> 11; hash += hash << 15;}
+
+bool compareArray(Array<BooleanEdge> *inputs1, Array<BooleanEdge> *inputs2) {
        if (inputs1->getSize() != inputs2->getSize())
                return false;
        for (uint i = 0; i < inputs1->getSize(); i++) {
@@ -24,23 +27,23 @@ bool compareArray(Array<Element *> *inputs1, Array<Element *> *inputs2) {
        return true;
 }
 
-uint hashArray(Array<Boolean *> *inputs) {
-       uint hash = inputs->getSize();
+uint hashArray(Array<BooleanEdge> *inputs) {
+       uint hash = 0;
        for (uint i = 0; i < inputs->getSize(); i++) {
-               uint newval = (uint)(uintptr_t) inputs->get(i);
-               hash ^= newval;
-               hash = (hash << 3) | (hash >> 29);
+               uint newval = (uint)(uintptr_t) inputs->get(i).getRaw();
+               HASHNEXT(hash, newval);
        }
+       HASHFINAL(hash);
        return hash;
 }
 
 uint hashArray(Array<Element *> *inputs) {
-       uint hash = inputs->getSize();
+       uint hash = 0;
        for (uint i = 0; i < inputs->getSize(); i++) {
                uint newval = (uint)(uintptr_t) inputs->get(i);
-               hash ^= newval;
-               hash = (hash << 3) | (hash >> 29);
+               HASHNEXT(hash, newval);
        }
+       HASHFINAL(hash);
        return hash;
 }
 
@@ -48,20 +51,29 @@ uint hashBoolean(Boolean *b) {
        switch (b->type) {
        case ORDERCONST: {
                BooleanOrder *o = (BooleanOrder *)b;
-               return ((uint)(uintptr_t) o->order) ^ ((uint) o->first) ^ (((uint)(o->second)) << 2);
+               uint hash = 0;
+               HASHNEXT(hash, (uint) o->first);
+               HASHNEXT(hash, (uint) o->second);
+               HASHNEXT(hash, (((uint)(uintptr_t) o->order) & 0xffff));
+               HASHFINAL(hash);
+               return hash;
        }
+
        case BOOLEANVAR: {
                return (uint)(uintptr_t) b;
        }
        case LOGICOP: {
                BooleanLogic *l = (BooleanLogic *)b;
-               return ((uint)l->op) ^ hashArray(&l->inputs);
+               return ((uint)l->op) + 43 * hashArray(&l->inputs);
        }
        case PREDICATEOP: {
                BooleanPredicate *p = (BooleanPredicate *)b;
-               return ((uint)(uintptr_t) p->predicate) ^
-                                        (((uint)(uintptr_t) p->undefStatus) << 1) ^
-                                        hashArray(&p->inputs);
+               uint hash = 0;
+               HASHNEXT(hash, hashArray(&p->inputs));
+               HASHNEXT(hash, (uint)(uintptr_t) p->predicate);
+               HASHNEXT(hash, (uint)(uintptr_t) p->undefStatus);
+               HASHFINAL(hash);
+               return hash;
        }
        default:
                ASSERT(0);
@@ -104,9 +116,12 @@ uint hashElement(Element *e) {
        }
        case ELEMFUNCRETURN: {
                ElementFunction *ef = (ElementFunction *) e;
-               return ((uint)(uintptr_t) ef->function) ^
-                                        ((uint)(uintptr_t) ef->overflowstatus) ^
-                                        hashArray(&ef->inputs);
+               uint hash = 0;
+               HASHNEXT(hash, hashArray (&ef->inputs));
+               HASHNEXT(hash, (uint)(uintptr_t) ef->getFunction());
+               HASHNEXT(hash, (uint)(uintptr_t) ef->overflowstatus);
+               HASHFINAL(hash);
+               return hash;
        }
        case ELEMCONST: {
                ElementConst *ec = (ElementConst *) e;
@@ -127,7 +142,7 @@ bool compareElement(Element *e1, Element *e2) {
        case ELEMFUNCRETURN: {
                ElementFunction *ef1 = (ElementFunction *) e1;
                ElementFunction *ef2 = (ElementFunction *) e2;
-               return (ef1->function == ef2->function) &&
+               return (ef1->getFunction() == ef2->getFunction()) &&
                                         (ef1->overflowstatus == ef2->overflowstatus) &&
                                         compareArray(&ef1->inputs, &ef2->inputs);
        }