/*
 * 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.hessian.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();
    }
}
