17dd252788645e940eada959bdde927426e2531c9Paul Duffin/* 27dd252788645e940eada959bdde927426e2531c9Paul Duffin * Copyright (C) 2011 The Guava Authors 37dd252788645e940eada959bdde927426e2531c9Paul Duffin * 47dd252788645e940eada959bdde927426e2531c9Paul Duffin * Licensed under the Apache License, Version 2.0 (the "License"); 57dd252788645e940eada959bdde927426e2531c9Paul Duffin * you may not use this file except in compliance with the License. 67dd252788645e940eada959bdde927426e2531c9Paul Duffin * You may obtain a copy of the License at 77dd252788645e940eada959bdde927426e2531c9Paul Duffin * 87dd252788645e940eada959bdde927426e2531c9Paul Duffin * http://www.apache.org/licenses/LICENSE-2.0 97dd252788645e940eada959bdde927426e2531c9Paul Duffin * 107dd252788645e940eada959bdde927426e2531c9Paul Duffin * Unless required by applicable law or agreed to in writing, software 117dd252788645e940eada959bdde927426e2531c9Paul Duffin * distributed under the License is distributed on an "AS IS" BASIS, 127dd252788645e940eada959bdde927426e2531c9Paul Duffin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137dd252788645e940eada959bdde927426e2531c9Paul Duffin * See the License for the specific language governing permissions and 147dd252788645e940eada959bdde927426e2531c9Paul Duffin * limitations under the License. 157dd252788645e940eada959bdde927426e2531c9Paul Duffin */ 161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.hash; 181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 197dd252788645e940eada959bdde927426e2531c9Paul Duffinimport static com.google.common.base.Preconditions.checkNotNull; 207dd252788645e940eada959bdde927426e2531c9Paul Duffin 211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.nio.charset.Charset; 221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/** 241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * An abstract composition of multiple hash functions. {@linkplain #newHasher()} delegates to the 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code Hasher} objects of the delegate hash functions, and in the end, they are used by 261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@linkplain #makeHash(Hasher[])} that constructs the final {@code HashCode}. 277dd252788645e940eada959bdde927426e2531c9Paul Duffin * 287dd252788645e940eada959bdde927426e2531c9Paul Duffin * @author Dimitris Andreou 291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertabstract class AbstractCompositeHashFunction extends AbstractStreamingHashFunction { 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final HashFunction[] functions; 327dd252788645e940eada959bdde927426e2531c9Paul Duffin 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AbstractCompositeHashFunction(HashFunction... functions) { 347dd252788645e940eada959bdde927426e2531c9Paul Duffin for (HashFunction function : functions) { 357dd252788645e940eada959bdde927426e2531c9Paul Duffin checkNotNull(function); 367dd252788645e940eada959bdde927426e2531c9Paul Duffin } 371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.functions = functions; 381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 397dd252788645e940eada959bdde927426e2531c9Paul Duffin 401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Constructs a {@code HashCode} from the {@code Hasher} objects of the functions. Each of them 421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * has consumed the entire input and they are ready to output a {@code HashCode}. The order of 431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the hashers are the same order as the functions given to the constructor. 441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // this could be cleaner if it passed HashCode[], but that would create yet another array... 460888a09821a98ac0680fad765217302858e70fa4Paul Duffin /* protected */ abstract HashCode makeHash(Hasher[] hashers); 477dd252788645e940eada959bdde927426e2531c9Paul Duffin 480888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override 491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Hasher newHasher() { 501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final Hasher[] hashers = new Hasher[functions.length]; 511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < hashers.length; i++) { 521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hashers[i] = functions[i].newHasher(); 531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new Hasher() { 550888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Hasher putByte(byte b) { 561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Hasher hasher : hashers) { 571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hasher.putByte(b); 581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 620888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Hasher putBytes(byte[] bytes) { 631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Hasher hasher : hashers) { 641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hasher.putBytes(bytes); 651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 690888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Hasher putBytes(byte[] bytes, int off, int len) { 701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Hasher hasher : hashers) { 711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hasher.putBytes(bytes, off, len); 721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 760888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Hasher putShort(short s) { 771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Hasher hasher : hashers) { 781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hasher.putShort(s); 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 830888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Hasher putInt(int i) { 841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Hasher hasher : hashers) { 851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hasher.putInt(i); 861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 900888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Hasher putLong(long l) { 911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Hasher hasher : hashers) { 921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hasher.putLong(l); 931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 970888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Hasher putFloat(float f) { 981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Hasher hasher : hashers) { 991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hasher.putFloat(f); 1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1040888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Hasher putDouble(double d) { 1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Hasher hasher : hashers) { 1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hasher.putDouble(d); 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1110888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Hasher putBoolean(boolean b) { 1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Hasher hasher : hashers) { 1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hasher.putBoolean(b); 1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1180888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Hasher putChar(char c) { 1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Hasher hasher : hashers) { 1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hasher.putChar(c); 1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1250888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Hasher putUnencodedChars(CharSequence chars) { 1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Hasher hasher : hashers) { 1270888a09821a98ac0680fad765217302858e70fa4Paul Duffin hasher.putUnencodedChars(chars); 1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1320888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public Hasher putString(CharSequence chars, Charset charset) { 1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Hasher hasher : hashers) { 1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hasher.putString(chars, charset); 1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1390888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public <T> Hasher putObject(T instance, Funnel<? super T> funnel) { 1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Hasher hasher : hashers) { 1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert hasher.putObject(instance, funnel); 1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1460888a09821a98ac0680fad765217302858e70fa4Paul Duffin @Override public HashCode hash() { 1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return makeHash(hashers); 1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1517dd252788645e940eada959bdde927426e2531c9Paul Duffin 1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0L; 1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} 154