content: /*
   * Copyright (C) 2014 The Android Open Source Project
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package android.hardware.camera2.utils;
  
  import android.annotation.UnsupportedAppUsage;
  
  /**
   * Provide hashing functions using the Modified Bernstein hash
   */
  public final class HashCodeHelpers {
  
      /**
       * Hash every element uniformly using the Modified Bernstein hash.
       *
       * <p>Useful to implement a {@link Object#hashCode} for uniformly distributed data.</p>
       *
       * @param array a non-{@code null} array of integers
       *
       * @return the numeric hash code
       */
      @UnsupportedAppUsage
      public static int hashCode(int... array) {
          if (array == null) {
              return 0;
          }
  
          /*
           *  Note that we use 31 here instead of 33 since it's preferred in Effective Java
           *  and used elsewhere in the runtime (e.g. Arrays#hashCode)
           *
           *  That being said 33 and 31 are nearly identical in terms of their usefulness
           *  according to http://svn.apache.org/repos/asf/apr/apr/trunk/tables/apr_hash.c
           */
          int h = 1;
          for (int x : array) {
              // Strength reduction; in case the compiler has illusions about divisions being faster
              h = ((h << 5) - h) ^ x; // (h * 31) XOR x
          }
  
          return h;
      }
  
      /**
       * Hash every element uniformly using the Modified Bernstein hash.
       *
       * <p>Useful to implement a {@link Object#hashCode} for uniformly distributed data.</p>
       *
       * @param array a non-{@code null} array of floats
       *
       * @return the numeric hash code
       */
      public static int hashCode(float... array) {
          if (array == null) {
              return 0;
          }
  
          int h = 1;
          for (float f : array) {
              int x = Float.floatToIntBits(f);
              h = ((h << 5) - h) ^ x; // (h * 31) XOR x
          }
  
          return h;
      }
  
      /**
       * Hash every element uniformly using the Modified Bernstein hash.
       *
       * <p>Useful to implement a {@link Object#hashCode} for uniformly distributed data.</p>
       *
       * @param array a non-{@code null} array of objects
       *
       * @return the numeric hash code
       */
      public static <T> int hashCodeGeneric(T... array) {
          if (array == null) {
              return 0;
          }
  
          int h = 1;
          for (T o : array) {
              int x = (o == null) ? 0 : o.hashCode();
              h = ((h << 5) - h) ^ x; // (h * 31) XOR x
          }
  
          return h;
      }
  
  }
  