/*
 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
 */
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 com.sun.org.apache.xerces.internal.util;


/**
 * This class is an unsynchronized hash table primary used for String
 * to Object mapping.
 * <p>
 * The hash code uses the same algorithm as SymbolTable class.
 *
 * @author Elena Litani
 * @version $Id: SymbolHash.java,v 1.7 2010-11-01 04:40:14 joehw Exp $
 */
public class SymbolHash {

    //
    // Constants
    //

    /** Default table size. */
    protected static final int TABLE_SIZE = 101;

    /** Maximum hash collisions per bucket. */
    protected static final int MAX_HASH_COLLISIONS = 40;

    protected static final int MULTIPLIERS_SIZE = 1 << 5;
    protected static final int MULTIPLIERS_MASK = MULTIPLIERS_SIZE - 1;

    //
    // Data
    //

    /** Actual table size **/
    protected int fTableSize;

    /** Buckets. */
    protected Entry[] fBuckets;

    /** Number of elements. */
    protected int fNum = 0;

    /**
     * Array of randomly selected hash function multipliers or <code>null</code>
     * if the default String.hashCode() function should be used.
     */
    protected int[] fHashMultipliers;

    //
    // Constructors
    //

    /** Constructs a key table with the default size. */
    public SymbolHash() {
        this(TABLE_SIZE);
    }

    /**
     * Constructs a key table with a given size.
     *
     * @param size  the size of the key table.
     */
    public SymbolHash(int size) {
        fTableSize = size;
        fBuckets = new Entry[fTableSize];
    }

    //
    // Public methods
    //

    /**
     * Adds the key/value mapping to the key table. If the key already exists,
     * the previous value associated with this key is overwritten by the new
     * value.
     *
     * @param key
     * @param value
     */
    public void put(Object key, Object value) {

        // search for identical key
        int collisionCount = 0;
        final int hash = hash(key);
        int bucket = hash % fTableSize;
        for (Entry entry = fBuckets[bucket]; entry != null; entry = entry.next) {
            if (key.equals(entry.key)) {
                // replace old value
                entry.value = value;
                return;
            }
            ++collisionCount;
        }

        if (fNum >= fTableSize) {
            // Rehash the table if the number of entries
            // would exceed the number of buckets.
            rehash();
            bucket = hash % fTableSize;
        }
        else if (collisionCount >= MAX_HASH_COLLISIONS && key instanceof String) {
            // Select a new hash function and rehash the table if
            // MAX_HASH_COLLISIONS is exceeded.
            rebalance();
            bucket = hash(key) % fTableSize;
        }

        // create new entry
        Entry entry = new Entry(key, value, fBuckets[bucket]);
        fBuckets[bucket] = entry;
        ++fNum;
    }

    /**
     * Get the value associated with the given key.
     *
     * @param key
     * @return the value associated with the given key.
     */
    public Object get(Object key) {
        int bucket = hash(key) % fTableSize;
        Entry entry = search(key, bucket);
        if (entry != null) {
            return entry.value;
        }
        return null;
    }

    /**
     * Get the number of key/value pairs stored in this table.
     *
     * @return the number of key/value pairs stored in this table.
     */
    public int getLength() {
        return fNum;
    }

    /**
     * Add all values to the given array. The array must have enough entry.
     *
     * @param elements  the array to store the elements
     * @param from      where to start store element in the array
     * @return          number of elements copied to the array
     */
    public int getValues(Object[] elements, int from) {
        for (int i=0, j=0; i<fTableSize && j<fNum; i++) {
            for (Entry entry = fBuckets[i]; entry != null; entry = entry.next) {
                elements[from+j] = entry.value;
                j++;
            }
        }
        return fNum;
    }

    /**
     * Return key/value pairs of all entries in the map
     */
    public Object[] getEntries() {
        Object[] entries = new Object[fNum << 1];
        for (int i=0, j=0; i<fTableSize && j<fNum << 1; i++) {
            for (Entry entry = fBuckets[i]; entry != null; entry = entry.next) {
                entries[j] = entry.key;
                entries[++j] = entry.value;
                j++;
            }
        }
        return entries;
    }

    /**
     * Make a clone of this object.
     */
    public SymbolHash makeClone() {
        SymbolHash newTable = new SymbolHash(fTableSize);
        newTable.fNum = fNum;
        newTable.fHashMultipliers = fHashMultipliers != null ? (int[]) fHashMultipliers.clone() : null;
        for (int i = 0; i < fTableSize; i++) {
            if (fBuckets[i] != null) {
                newTable.fBuckets[i] = fBuckets[i].makeClone();
            }
        }
        return newTable;
    }

    /**
     * Remove all key/value association. This tries to save a bit of GC'ing
     * by at least keeping the fBuckets array around.
     */
    public void clear() {
        for (int i=0; i<fTableSize; i++) {
            fBuckets[i] = null;
        }
        fNum = 0;
        fHashMultipliers = null;
    } // clear():  void

    protected Entry search(Object key, int bucket) {
        // search for identical key
        for (Entry entry = fBuckets[bucket]; entry != null; entry = entry.next) {
            if (key.equals(entry.key))
                return entry;
        }
        return null;
    }

    /**
     * Returns a hashcode value for the specified key.
     *
     * @param key The key to hash.
     */
    protected int hash(Object key) {
        if (fHashMultipliers == null || !(key instanceof String)) {
            return key.hashCode() & 0x7FFFFFFF;
        }
        return hash0((String) key);
    } // hash(Object):int

    private int hash0(String symbol) {
        int code = 0;
        final int length = symbol.length();
        final int[] multipliers = fHashMultipliers;
        for (int i = 0; i < length; ++i) {
            code = code * multipliers[i & MULTIPLIERS_MASK] + symbol.charAt(i);
        }
        return code & 0x7FFFFFFF;
    } // hash0(String):int

    /**
     * Increases the capacity of and internally reorganizes this
     * SymbolHash, in order to accommodate and access its entries more
     * efficiently.  This method is called automatically when the
     * number of keys in the SymbolHash exceeds its number of buckets.
     */
    protected void rehash() {
        rehashCommon((fBuckets.length << 1) + 1);
    }

    /**
     * Randomly selects a new hash function and reorganizes this SymbolHash
     * in order to more evenly distribute its entries across the table. This
     * method is called automatically when the number keys in one of the
     * SymbolHash's buckets exceeds MAX_HASH_COLLISIONS.
     */
    protected void rebalance() {
        if (fHashMultipliers == null) {
            fHashMultipliers = new int[MULTIPLIERS_SIZE];
        }
        PrimeNumberSequenceGenerator.generateSequence(fHashMultipliers);
        rehashCommon(fBuckets.length);
    }

    private void rehashCommon(final int newCapacity) {

        final int oldCapacity = fBuckets.length;
        final Entry[] oldTable = fBuckets;

        final Entry[] newTable = new Entry[newCapacity];

        fBuckets = newTable;
        fTableSize = fBuckets.length;

        for (int i = oldCapacity; i-- > 0;) {
            for (Entry old = oldTable[i]; old != null; ) {
                Entry e = old;
                old = old.next;

                int index = hash(e.key) % newCapacity;
                e.next = newTable[index];
                newTable[index] = e;
            }
        }
    }

    //
    // Classes
    //

    /**
     * This class is a key table entry. Each entry acts as a node
     * in a linked list.
     */
    protected static final class Entry {
        // key/value
        public Object key;
        public Object value;
        /** The next entry. */
        public Entry next;

        public Entry() {
            key = null;
            value = null;
            next = null;
        }

        public Entry(Object key, Object value, Entry next) {
            this.key = key;
            this.value = value;
            this.next = next;
        }

        public Entry makeClone() {
            Entry entry = new Entry();
            entry.key = key;
            entry.value = value;
            if (next != null)
                entry.next = next.makeClone();
            return entry;
        }
    } // entry

} // class SymbolHash
