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 
17 package android.hardware.camera2.utils;
18 
19 import android.compat.annotation.UnsupportedAppUsage;
20 
21 /**
22  * Provide hashing functions using the Modified Bernstein hash
23  */
24 public final class HashCodeHelpers {
25 
26     /**
27      * Hash every element uniformly using the Modified Bernstein hash.
28      *
29      * <p>Useful to implement a {@link Object#hashCode} for uniformly distributed data.</p>
30      *
31      * @param array a non-{@code null} array of integers
32      *
33      * @return the numeric hash code
34      */
35     @UnsupportedAppUsage
hashCode(int... array)36     public static int hashCode(int... array) {
37         if (array == null) {
38             return 0;
39         }
40 
41         /*
42          *  Note that we use 31 here instead of 33 since it's preferred in Effective Java
43          *  and used elsewhere in the runtime (e.g. Arrays#hashCode)
44          *
45          *  That being said 33 and 31 are nearly identical in terms of their usefulness
46          *  according to http://svn.apache.org/repos/asf/apr/apr/trunk/tables/apr_hash.c
47          */
48         int h = 1;
49         for (int x : array) {
50             // Strength reduction; in case the compiler has illusions about divisions being faster
51             h = ((h << 5) - h) ^ x; // (h * 31) XOR x
52         }
53 
54         return h;
55     }
56 
57     /**
58      * Hash every element uniformly using the Modified Bernstein hash.
59      *
60      * <p>Useful to implement a {@link Object#hashCode} for uniformly distributed data.</p>
61      *
62      * @param array a non-{@code null} array of floats
63      *
64      * @return the numeric hash code
65      */
hashCode(float... array)66     public static int hashCode(float... array) {
67         if (array == null) {
68             return 0;
69         }
70 
71         int h = 1;
72         for (float f : array) {
73             int x = Float.floatToIntBits(f);
74             h = ((h << 5) - h) ^ x; // (h * 31) XOR x
75         }
76 
77         return h;
78     }
79 
80     /**
81      * Hash every element uniformly using the Modified Bernstein hash.
82      *
83      * <p>Useful to implement a {@link Object#hashCode} for uniformly distributed data.</p>
84      *
85      * @param array a non-{@code null} array of objects
86      *
87      * @return the numeric hash code
88      */
hashCodeGeneric(T... array)89     public static <T> int hashCodeGeneric(T... array) {
90         if (array == null) {
91             return 0;
92         }
93 
94         int h = 1;
95         for (T o : array) {
96             int x = (o == null) ? 0 : o.hashCode();
97             h = ((h << 5) - h) ^ x; // (h * 31) XOR x
98         }
99 
100         return h;
101     }
102 
103 }
104