11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert// Copyright 2011 Google Inc. All Rights Reserved. 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.hash; 41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.nio.charset.Charset; 61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/** 81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * An abstract composition of multiple hash functions. {@linkplain #newHasher()} delegates to the 91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code Hasher} objects of the delegate hash functions, and in the end, they are used by 101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@linkplain #makeHash(Hasher[])} that constructs the final {@code HashCode}. 111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author andreou@google.com (Dimitris Andreou) 131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertabstract class AbstractCompositeHashFunction extends AbstractStreamingHashFunction { 151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final HashFunction[] functions; 161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AbstractCompositeHashFunction(HashFunction... functions) { 181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.functions = functions; 191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Constructs a {@code HashCode} from the {@code Hasher} objects of the functions. Each of them 231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * has consumed the entire input and they are ready to output a {@code HashCode}. The order of 241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the hashers are the same order as the functions given to the constructor. 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // this could be cleaner if it passed HashCode[], but that would create yet another array... 271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /* protected */ abstract HashCode makeHash(Hasher[] hashers); 281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Hasher newHasher() { 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Hasher[] hashers = new Hasher[functions.length]; 321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < hashers.length; i++) { 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hashers[i] = functions[i].newHasher(); 341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new Hasher() { 361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Hasher putByte(byte b) { 371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Hasher hasher : hashers) { 381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hasher.putByte(b); 391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Hasher putBytes(byte[] bytes) { 441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Hasher hasher : hashers) { 451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hasher.putBytes(bytes); 461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Hasher putBytes(byte[] bytes, int off, int len) { 511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Hasher hasher : hashers) { 521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hasher.putBytes(bytes, off, len); 531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Hasher putShort(short s) { 581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Hasher hasher : hashers) { 591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hasher.putShort(s); 601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Hasher putInt(int i) { 651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Hasher hasher : hashers) { 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hasher.putInt(i); 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Hasher putLong(long l) { 721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Hasher hasher : hashers) { 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hasher.putLong(l); 741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Hasher putFloat(float f) { 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Hasher hasher : hashers) { 801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hasher.putFloat(f); 811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Hasher putDouble(double d) { 861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Hasher hasher : hashers) { 871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hasher.putDouble(d); 881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Hasher putBoolean(boolean b) { 931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Hasher hasher : hashers) { 941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hasher.putBoolean(b); 951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Hasher putChar(char c) { 1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Hasher hasher : hashers) { 1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hasher.putChar(c); 1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Hasher putString(CharSequence chars) { 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Hasher hasher : hashers) { 1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hasher.putString(chars); 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Hasher putString(CharSequence chars, Charset charset) { 1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Hasher hasher : hashers) { 1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hasher.putString(chars, charset); 1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public <T> Hasher putObject(T instance, Funnel<? super T> funnel) { 1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Hasher hasher : hashers) { 1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hasher.putObject(instance, funnel); 1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public HashCode hash() { 1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return makeHash(hashers); 1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0L; 1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} 135