HashCodeHelpers.java revision 0819c75680c81a4e9c8a1ec518ac62cceccf3f56
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.hardware.camera2.utils;
18
19/**
20 * Provide hashing functions using the Modified Bernstein hash
21 */
22public final class HashCodeHelpers {
23
24    /**
25     * Hash every element uniformly using the Modified Bernstein hash.
26     *
27     * <p>Useful to implement a {@link Object#hashCode} for uniformly distributed data.</p>
28     *
29     * @param array a non-{@code null} array of integers
30     *
31     * @return the numeric hash code
32     */
33    public static int hashCode(int... array) {
34        if (array == null) {
35            return 0;
36        }
37
38        /*
39         *  Note that we use 31 here instead of 33 since it's preferred in Effective Java
40         *  and used elsewhere in the runtime (e.g. Arrays#hashCode)
41         *
42         *  That being said 33 and 31 are nearly identical in terms of their usefulness
43         *  according to http://svn.apache.org/repos/asf/apr/apr/trunk/tables/apr_hash.c
44         */
45        int h = 1;
46        for (int x : array) {
47            // Strength reduction; in case the compiler has illusions about divisions being faster
48            h = ((h << 5) - h) ^ x; // (h * 31) XOR x
49        }
50
51        return h;
52    }
53
54    /**
55     * Hash every element uniformly using the Modified Bernstein hash.
56     *
57     * <p>Useful to implement a {@link Object#hashCode} for uniformly distributed data.</p>
58     *
59     * @param array a non-{@code null} array of floats
60     *
61     * @return the numeric hash code
62     */
63    public static int hashCode(float... array) {
64        if (array == null) {
65            return 0;
66        }
67
68        int h = 1;
69        for (float f : array) {
70            int x = Float.floatToIntBits(f);
71            h = ((h << 5) - h) ^ x; // (h * 31) XOR x
72        }
73
74        return h;
75    }
76
77    /**
78     * Hash every element uniformly using the Modified Bernstein hash.
79     *
80     * <p>Useful to implement a {@link Object#hashCode} for uniformly distributed data.</p>
81     *
82     * @param array a non-{@code null} array of objects
83     *
84     * @return the numeric hash code
85     */
86    public static <T> int hashCodeGeneric(T... array) {
87        if (array == null) {
88            return 0;
89        }
90
91        int h = 1;
92        for (T o : array) {
93            int x = (o == null) ? 0 : o.hashCode();
94            h = ((h << 5) - h) ^ x; // (h * 31) XOR x
95        }
96
97        return h;
98    }
99
100}
101