/*
 * Copyright (c) 2001-2008 Caucho Technology, Inc.  All rights reserved.
 *
 * The Apache Software License, Version 1.1
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:
 *       "This product includes software developed by the
 *        Caucho Technology (http://www.caucho.com/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "Burlap", "Resin", and "Caucho" must not be used to
 *    endorse or promote products derived from this software without prior
 *    written permission. For written permission, please contact
 *    info@caucho.com.
 *
 * 5. Products derived from this software may not be called "Resin"
 *    nor may "Resin" appear in their names without prior written
 *    permission of Caucho Technology.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * @author Scott Ferguson
 */

package com.alibaba.com.caucho.hessian3.util;

/**
 * The IntMap provides a simple hashmap from keys to integers.  The API is
 * an abbreviation of the HashMap collection API.
 * <p>
 * <p>The convenience of IntMap is avoiding all the silly wrapping of
 * integers.
 */
public class IdentityIntMap {
    /**
     * Encoding of a null entry.  Since NULL is equal to Integer.MIN_VALUE,
     * it's impossible to distinguish between the two.
     */
    public final static int NULL = 0xdeadbeef; // Integer.MIN_VALUE + 1;

    private static final Object DELETED = new Object();

    private Object[] _keys;
    private int[] _values;

    private int _size;
    private int _mask;

    /**
     * Create a new IntMap.  Default size is 16.
     */
    public IdentityIntMap() {
        _keys = new Object[256];
        _values = new int[256];

        _mask = _keys.length - 1;
        _size = 0;
    }

    /**
     * Clear the hashmap.
     */
    public void clear() {
        Object[] keys = _keys;
        int[] values = _values;

        for (int i = keys.length - 1; i >= 0; i--) {
            keys[i] = null;
            values[i] = 0;
        }

        _size = 0;
    }

    /**
     * Returns the current number of entries in the map.
     */
    public int size() {
        return _size;
    }

    /**
     * Puts a new value in the property table with the appropriate flags
     */
    public int get(Object key) {
        int mask = _mask;
        int hash = System.identityHashCode(key) % mask & mask;

        Object[] keys = _keys;

        while (true) {
            Object mapKey = keys[hash];

            if (mapKey == null)
                return NULL;
            else if (mapKey == key)
                return _values[hash];

            hash = (hash + 1) % mask;
        }
    }

    /**
     * Expands the property table
     */
    private void resize(int newSize) {
        Object[] newKeys = new Object[newSize];
        int[] newValues = new int[newSize];

        int mask = _mask = newKeys.length - 1;

        Object[] keys = _keys;
        int values[] = _values;

        for (int i = keys.length - 1; i >= 0; i--) {
            Object key = keys[i];

            if (key == null || key == DELETED)
                continue;

            int hash = System.identityHashCode(key) % mask & mask;

            while (true) {
                if (newKeys[hash] == null) {
                    newKeys[hash] = key;
                    newValues[hash] = values[i];
                    break;
                }

                hash = (hash + 1) % mask;
            }
        }

        _keys = newKeys;
        _values = newValues;
    }

    /**
     * Puts a new value in the property table with the appropriate flags
     */
    public int put(Object key, int value) {
        int mask = _mask;
        int hash = System.identityHashCode(key) % mask & mask;

        Object[] keys = _keys;

        while (true) {
            Object testKey = keys[hash];

            if (testKey == null || testKey == DELETED) {
                keys[hash] = key;
                _values[hash] = value;

                _size++;

                if (keys.length <= 4 * _size)
                    resize(4 * keys.length);

                return NULL;
            } else if (key != testKey) {
                hash = (hash + 1) % mask;

                continue;
            } else {
                int old = _values[hash];

                _values[hash] = value;

                return old;
            }
        }
    }

    /**
     * Deletes the entry.  Returns true if successful.
     */
    public int remove(Object key) {
        int mask = _mask;
        int hash = System.identityHashCode(key) % mask & mask;

        while (true) {
            Object mapKey = _keys[hash];

            if (mapKey == null)
                return NULL;
            else if (mapKey == key) {
                _keys[hash] = DELETED;

                _size--;

                return _values[hash];
            }

            hash = (hash + 1) % mask;
        }
    }

    @Override
    public String toString() {
        StringBuffer sbuf = new StringBuffer();

        sbuf.append("IntMap[");
        boolean isFirst = true;

        for (int i = 0; i <= _mask; i++) {
            if (_keys[i] != null && _keys[i] != DELETED) {
                if (!isFirst)
                    sbuf.append(", ");

                isFirst = false;
                sbuf.append(_keys[i]);
                sbuf.append(":");
                sbuf.append(_values[i]);
            }
        }
        sbuf.append("]");

        return sbuf.toString();
    }
}
