1 /*
2 * ModeShape (http://www.modeshape.org)
3 * See the COPYRIGHT.txt file distributed with this work for information
4 * regarding copyright ownership. Some portions may be licensed
5 * to Red Hat, Inc. under one or more contributor license agreements.
6 * See the AUTHORS.txt file in the distribution for a full listing of
7 * individual contributors.
8 *
9 * ModeShape is free software. Unless otherwise indicated, all code in ModeShape
10 * is licensed to you under the terms of the GNU Lesser General Public License as
11 * published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
13 *
14 * ModeShape is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this software; if not, write to the Free
21 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
23 */
24 package org.modeshape.common.util;
25
26 import java.util.Arrays;
27 import net.jcip.annotations.Immutable;
28
29 /**
30 * Utilities for easily computing hash codes. The algorithm should generally produce good distributions for use in hash-based
31 * containers or collections, but as expected does always result in repeatable hash codes given the inputs.
32 */
33 @Immutable
34 public class HashCode {
35
36 // Prime number used in improving distribution: 1,000,003
37 private static final int PRIME = 103;
38
39 /**
40 * Compute a combined hash code from the supplied objects. This method always returns 0 if no objects are supplied.
41 *
42 * @param objects the objects that should be used to compute the hash code
43 * @return the hash code
44 */
45 public static int compute( Object... objects ) {
46 return compute(0, objects);
47 }
48
49 /**
50 * Compute a combined hash code from the supplied objects using the supplied seed.
51 *
52 * @param seed a value upon which the hash code will be based; may be 0
53 * @param objects the objects that should be used to compute the hash code
54 * @return the hash code
55 */
56 protected static int compute( int seed,
57 Object... objects ) {
58 if (objects == null || objects.length == 0) {
59 return seed * HashCode.PRIME;
60 }
61 // Compute the hash code for all of the objects ...
62 int hc = seed;
63 for (Object object : objects) {
64 hc = HashCode.PRIME * hc;
65 if (object instanceof byte[]) {
66 hc += Arrays.hashCode((byte[])object);
67 } else if (object instanceof boolean[]) {
68 hc += Arrays.hashCode((boolean[])object);
69 } else if (object instanceof short[]) {
70 hc += Arrays.hashCode((short[])object);
71 } else if (object instanceof int[]) {
72 hc += Arrays.hashCode((int[])object);
73 } else if (object instanceof long[]) {
74 hc += Arrays.hashCode((long[])object);
75 } else if (object instanceof float[]) {
76 hc += Arrays.hashCode((float[])object);
77 } else if (object instanceof double[]) {
78 hc += Arrays.hashCode((double[])object);
79 } else if (object instanceof char[]) {
80 hc += Arrays.hashCode((char[])object);
81 } else if (object instanceof Object[]) {
82 hc += Arrays.hashCode((Object[])object);
83 } else if (object != null) {
84 hc += object.hashCode();
85 }
86 }
87 return hc;
88 }
89
90 }