/* * ARX: Powerful Data Anonymization * Copyright 2012 - 2017 Fabian Prasser, Florian Kohlmayer and contributors * * 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 org.deidentifier.arx.framework.check.groupify; /** * This class implements several helper methods for hash tables. * * @author Fabian Prasser * @author Florian Kohlmayer */ public class HashTableUtil { /** The Constant ALENGTH. */ private static final int ALENGTH = 1000; /** The Constant ARRAY. */ private static final Object[] ARRAY = new Object[ALENGTH]; /** * Calculates a new capacity. * * @param x * the parameter * @return the capacity */ public static final int calculateCapacity(int x) { if (x >= (1 << 30)) { return 1 << 30; } if (x == 0) { return 16; } x = x - 1; x |= x >> 1; x |= x >> 2; x |= x >> 4; x |= x >> 8; x |= x >> 16; return x + 1; } /** * Computes the threshold for rehashing. * * @param buckets * @param loadFactor * @return */ public static final int calculateThreshold(final int buckets, final float loadFactor) { return (int) (buckets * loadFactor); } /** * Equality check for integer arrays. * * @param a an array * @param a2 another array * @return true, if equal */ public static final boolean equals(final int[] a, final int[] a2) { switch (a.length) { case 20: if (a[19] != a2[19]) { return false; } case 19: if (a[18] != a2[18]) { return false; } case 18: if (a[17] != a2[17]) { return false; } case 17: if (a[16] != a2[16]) { return false; } case 16: if (a[15] != a2[15]) { return false; } case 15: if (a[14] != a2[14]) { return false; } case 14: if (a[13] != a2[13]) { return false; } case 13: if (a[12] != a2[12]) { return false; } case 12: if (a[11] != a2[11]) { return false; } case 11: if (a[10] != a2[10]) { return false; } case 10: if (a[9] != a2[9]) { return false; } case 9: if (a[8] != a2[8]) { return false; } case 8: if (a[7] != a2[7]) { return false; } case 7: if (a[6] != a2[6]) { return false; } case 6: if (a[5] != a2[5]) { return false; } case 5: if (a[4] != a2[4]) { return false; } case 4: if (a[3] != a2[3]) { return false; } case 3: if (a[2] != a2[2]) { return false; } case 2: if (a[1] != a2[1]) { return false; } case 1: if (a[0] != a2[0]) { return false; } break; default: for (int i = 0; i < a.length; i++) { if (a[i] != a2[i]) { return false; } } } return true; } /** * Computes a hashcode for an integer array, partially unrolled. * * @param array * @return the hashcode */ public static final int hashcode(final int[] array) { final int len = array.length; int result = 23; int i = 0; // Do blocks of four ints unrolled. for (; (i + 3) < len; i += 4) { result = (1874161 * result) + // 37 * 37 * 37 * 37 (50653 * array[i]) + // 37 * 37 * 37 (1369 * array[i + 1]) + // 37 * 37 (37 * array[i + 2]) + array[i + 3]; } // Do the rest for (; i < len; i++) { result = (37 * result) + array[i]; } return result; } /** * Computes a hashcode for an integer array. * * @param array * the array * @return the hashcode */ public static final int hashcode_old(final int[] array) { int result = 23; for (int i = 0; i < array.length; i++) { result = (37 * result) + array[i]; } return result; } /** * Returns the same result as Arrays.fill(array, null) * * @param array * the array */ public static final void nullifyArray(final Object[] array) { final int full = array.length / ALENGTH; final int part = (full == 0) ? array.length : (array.length % ALENGTH); int i = 0; for (i = 0; i < (full * ALENGTH); i += ALENGTH) { System.arraycopy(ARRAY, 0, array, i, ALENGTH); } System.arraycopy(ARRAY, 0, array, i, part); } }