/*
 * @author Ranides Atterwim <ranides@gmail.com>
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.collection.utils;

import net.ranides.assira.math.MathUtils;

public final class HashCollection {

    private HashCollection() {
        // utility class
    }
    
    /**
     * The initial default size of a hash table.
     */
    public static final int INITIAL_SIZE = 16;
    
    /**
     * The default load factor of a hash table.
     */
    public static final float LOAD_FACTOR = .75f;
    
    /**
     * Returns the maximum number of entries that can be filled before
     * rehashing.
     *
     * @param n the size of the backing array.
     * @param f the load factor.
     * @return the maximum number of entries before rehashing.
     */
    public static int factorsize(int n, float f) {
        return (int) Math.ceil(n * f);
    }

    /**
     * Returns the least power of two smaller than or equal to 2<sup>30</sup>
     * and larger than or equal to
     * <code>Math.ceil( expected / f )</code>.
     *
     * @param expected the expected number of elements in a hash table.
     * @param f the load factor.
     * @return the minimum possible size for a backing array.
     * @throws IllegalArgumentException if the necessary size is larger than
     * 2<sup>30</sup>.
     */
    public static int arraysize(int expected, float f) {
        final long s = MathUtils.pow2next((long) Math.ceil(expected / f));
        if (s > (1 << 30)) {
            throw new IllegalArgumentException("Too large (" + expected + " expected elements with load factor " + f + ")");
        }
        return (int) s;
    }

}