/* * Copyright (C) 2012-2013 University of Freiburg * * This file is part of SMTInterpol. * * SMTInterpol is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SMTInterpol is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with SMTInterpol. If not, see <http://www.gnu.org/licenses/>. */ package de.uni_freiburg.informatik.ultimate.util; public final class HashUtils { // deadbeaf leads to hash conflicts on f... private final static int BASE = 0xcafebabe; private HashUtils() { // Hide constructor } public static int hashJenkins(int init, Object... vals) { if (vals == null || vals.length == 0) { return init; } int a,b,c; a = b = c = BASE + (vals.length << 2) + init; int pos = 0; while (vals.length - pos > 3) { //NOCHECKSTYLE a += vals[pos].hashCode(); b += vals[pos + 1].hashCode(); c += vals[pos + 2].hashCode(); a -= c; a ^= ((c << 4) | (c >> 28)); c += b; //NOCHECKSTYLE b -= a; b ^= ((a << 6) | (c >> 26)); a += c; //NOCHECKSTYLE c -= b; c ^= ((b << 8) | (b >> 24)); b += a; //NOCHECKSTYLE a -= c; a ^= ((c << 16) | (c >> 16)); c += b; //NOCHECKSTYLE b -= a; b ^= ((a << 19) | (c >> 13)); a += c; //NOCHECKSTYLE c -= b; c ^= ((b << 4) | (b >> 28)); b += a; //NOCHECKSTYLE pos += 3; //NOCHECKSTYLE } switch (vals.length - pos) { case 3: c += vals[pos++].hashCode(); //NOCHECKSTYLE case 2: b += vals[pos++].hashCode(); //NOCHECKSTYLE case 1: a += vals[pos].hashCode(); //NOCHECKSTYLE c ^= b; c -= ((b << 14) | (b >> 18)); //NOCHECKSTYLE a ^= c; a -= ((c << 11) | (c >> 21)); //NOCHECKSTYLE b ^= a; b -= ((a << 25) | (a >> 7)); //NOCHECKSTYLE c ^= b; c -= ((b << 16) | (b >> 16)); //NOCHECKSTYLE a ^= c; a -= ((c << 4) | (c >> 28)); //NOCHECKSTYLE b ^= a; b -= ((a << 14) | (a >> 18)); //NOCHECKSTYLE c ^= b; c -= ((b << 24) | (b >> 8)); //NOCHECKSTYLE // fallthrough case 0: // fallthrough default: break; } return c; } public static int hashJenkins(int init, Object val) { int a,b,c; a = b = BASE + 4 + init; //NOCHECKSTYLE a += val.hashCode(); c = -((b << 14) | (b >> 18)); //NOCHECKSTYLE a ^= c; a -= ((c << 11) | (c >> 21)); //NOCHECKSTYLE b ^= a; b -= ((a << 25) | (a >> 7)); //NOCHECKSTYLE c ^= b; c -= ((b << 16) | (b >> 16)); //NOCHECKSTYLE a ^= c; a -= ((c << 4) | (c >> 28)); //NOCHECKSTYLE b ^= a; b -= ((a << 14) | (a >> 18)); //NOCHECKSTYLE c ^= b; c -= ((b << 24) | (b >> 8)); //NOCHECKSTYLE return c; } public static int hashHsieh(int init, Object... vals) { if (vals == null || vals.length == 0) { return init; } int hash = init; /* Main loop */ for (final Object o : vals) { final int thingHash = o.hashCode(); hash += (thingHash >>> 16); //NOCHECKSTYLE final int tmp = ((thingHash & 0xffff) << 11) ^ hash; //NOCHECKSTYLE hash = (hash << 16) ^ tmp; //NOCHECKSTYLE hash += (hash >> 11); //NOCHECKSTYLE } /* Force "avalanching" of final 127 bits */ hash ^= hash << 3; //NOCHECKSTYLE hash += hash >> 5; //NOCHECKSTYLE hash ^= hash << 4; //NOCHECKSTYLE hash += hash >> 17; //NOCHECKSTYLE hash ^= hash << 25; //NOCHECKSTYLE hash += hash >> 6; //NOCHECKSTYLE return hash; } public static int hashHsieh(int init, Object val) { int hash = init; final int thingHash = val.hashCode(); hash += (thingHash >>> 16); //NOCHECKSTYLE final int tmp = ((thingHash & 0xffff) << 11) ^ hash; //NOCHECKSTYLE hash = (hash << 16) ^ tmp; //NOCHECKSTYLE hash += (hash >> 11); //NOCHECKSTYLE /* Force "avalanching" of final 127 bits */ hash ^= hash << 3; //NOCHECKSTYLE hash += hash >> 5; //NOCHECKSTYLE hash ^= hash << 4; //NOCHECKSTYLE hash += hash >> 17; //NOCHECKSTYLE hash ^= hash << 25; //NOCHECKSTYLE hash += hash >> 6; //NOCHECKSTYLE return hash; } }