All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.epam.deltix.util.collections.generated.CharacterToIntegerHashMap Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2021 EPAM Systems, Inc
 *
 * See the NOTICE file distributed with this work for additional information
 * regarding copyright ownership. 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 com.epam.deltix.util.collections.generated;

import com.epam.deltix.util.collections.hash.*;
import com.epam.deltix.util.collections.*;
import java.io.*;
import java.util.*;

@SuppressWarnings ("unchecked")
public class CharacterToIntegerHashMap 

    extends CharacterHashMapBase 
{
    protected int [] values;

    public CharacterToIntegerHashMap () {
        super ();
    }

    public CharacterToIntegerHashMap (int cap) {
        super (cap);
    }

    public CharacterToIntegerHashMap (HashCodeComputer hashCodeComputer) {
        super (0, hashCodeComputer);
    }

    public CharacterToIntegerHashMap (int cap, HashCodeComputer hashCodeComputer) {
        super (cap, hashCodeComputer);
    }

    @Override
    protected void              allocTable (int cap) {
        super.allocTable (cap);

        values = new int [cap];
    }

    @Override
    public long                 getSizeInMemory () {
        return (
            super.getSizeInMemory () + (SIZE_OF_POINTER + ARRAY_OVERHEAD) +
            values.length * SIZE_OF_INT
        );
    }


    protected void              resizeTable (int newSize) {
        final int                   curLength = values.length;
        final char []            saveKeys = keys;
        final int []             saveValues = values;
        final int []                savePrev = prev;

        allocTable (newSize);

        for (int ii = 0; ii < curLength; ii++)
            if (savePrev [ii] != NULL)
                putNewNoSpaceCheck (saveKeys [ii], saveValues [ii]);
    }

    public int               get (char key, int notFoundValue) {
        int         pos = find (key);

        return (pos == NULL ? notFoundValue : values [pos]);
    }

    /**
     *  Remove a value, if existed.
     *
     *  @param key          The key
     *  @param notFoundValue This will be returned if the key was not associated with a value.
     *  @return The old value associated with the key, or notFoundValue.
     */
    public int               remove (char key, int notFoundValue) {
        int         idx = find (key);

        if (idx == NULL)
            return (notFoundValue);

        int        value = values [idx];

        free (idx);

        return (value);
    }

    private void                putNewNoSpaceCheck (char key, int value) {
        int         hidx = hashIndex (key);
        int         idx = find (hidx, key);

        if (idx != NULL)
            throw new IllegalArgumentException (
                "Value for key " + key + " already exists = " + value
            );

        idx = allocEntry (hidx);

        values [idx] = value;
        putKey(idx, key);
    }

    /**
     *  Put new element into the map
     *
     *  @param key       The key
     *  @param value     The value
     *  @return  true if the element is new, false if the key was found.
     */
    public boolean              put (char key, int value) {
        int         hidx = hashIndex (key);
        int         idx = find (hidx, key);

        if (idx != NULL) {
            values [idx] = value;
            return (false);
        }

        if (freeHead == NULL) {
            resizeTable (values.length * 2);
            hidx = hashIndex (key); // recompute!
        }

        idx = allocEntry (hidx);

        values [idx] = value;
        putKey (idx, key);

        return (true);
    }

    /**
     *  Replace a value and return the old one.
     *  @param key          The key
     *  @param value        The new value to put in table
     *  @param notFoundValue This will be returned if the key was not associated with a value.
     *  @return The old value associated with the key, or notFoundValue.
     */
    public int               putAndGet (
        char                       key,
        int                     value,
        int                     notFoundValue
    )
    {
        int         hidx = hashIndex (key);
        int         idx = find (hidx, key);

        if (idx != NULL) {
            int    old = values [idx];

            values [idx] = value;

            return (old);
        }

        if (freeHead == NULL) {
            resizeTable (values.length * 2);
            hidx = hashIndex (key); // recompute!
        }

        idx = allocEntry (hidx);

        values [idx] = value;
        putKey(idx, key);

        return (notFoundValue);
    }

    /**
     *  Put new value into the map only if there is no previously stored value under the same key.
     *
     *  @param key          The key
     *  @param value        The new value to put in table (but only if the key is not occupied)
     *  @return             Value that remains in the map.
     */
    public int               putAndGetIfEmpty (
        char                   key,
        int                 value
    )
    {
        int         hidx = hashIndex (key);
        int         idx = find (hidx, key);

        if (idx != NULL) {
            return  values [idx];
        }

        if (freeHead == NULL) {
            resizeTable (values.length * 2);
            hidx = hashIndex (key); // recompute!
        }

        idx = allocEntry (hidx);

        values [idx] = value;
        putKey(idx, key);

        return value;
    }

    /**
     *  Put new value into the map only if there is no previously stored value under the same key.
     *
     *  @param key          The key
     *  @param value        The new value to put in table (but only if the key is not occupied)
     *  @return             True if this map has changed as the result of this call.
     */
    public boolean               putIfEmpty (
        char                   key,
        int                 value
    )
    {
        int         hidx = hashIndex (key);
        int         idx = find (hidx, key);

        if (idx != NULL) {
            return false;
        }

        if (freeHead == NULL) {
            resizeTable (values.length * 2);
            hidx = hashIndex (key); // recompute!
        }

        idx = allocEntry (hidx);

        values [idx] = value;
        putKey(idx, key);

        return true;
    }


    /**
     *	Linearly searches for the specified value.
     *
     *  @param value    The value to search.
     *  @return         Whether the specified value is found.
     */
    public final boolean        containsValue (int value) {
    	int         tabSize = values.length;

    	for (int ii = 0; ii < tabSize; ii++)
    		if (isFilled (ii) && values [ii] == value)
    			return (true);

    	return (false);
    }

    public final int []   valuesToArray (int [] ret) {
        if (ret == null || ret.length < count)
            ret = new int [count];

        final int       tabSize = values.length;
        int             outIdx = 0;

        for (int ii = 0; ii < tabSize; ii++)
            if (isFilled (ii))
                ret [outIdx++] = values [ii];

        assert outIdx == count;

        return ret;
    }


    protected final class ElementEnumeration
        implements IntegerEnumeration, CharacterEntry
    {
    	private int             pos = -1;

    	public ElementEnumeration () {
    		move ();
    	}

    	private void            move () {
    		do {
    			pos++;
    		} while (pos < values.length && isEmpty (pos));
    	}

        @Override
    	public boolean          hasMoreElements () {
    		return (pos < values.length);
    	}

        @Override
        public void             reset() {
            pos = -1;
            move();
        }

        @Override
    	public Integer           nextElement () {
    		int   ret = values [pos];
    		move ();
    		return (ret);
    	}

        @Override
	    public int           nextIntElement () {
    		int   ret = values [pos];
    		move ();
    		return (ret);
    	}

        @Override
	    public Character            key () {
           return keys [pos];
        }

        @Override
	    public char            keyCharacter () {
           return (keys [pos]);
        }
    }

    public IntegerEnumeration    elements () {
    	return (new ElementEnumeration ());
    }

    @Override
    public final boolean        equals (Object o) {
        throw new UnsupportedOperationException ();
    }

    @Override
    public int                  hashCode () {
        throw new UnsupportedOperationException ();
    }

    static final long           serialVersionUID = 1L;

    private void                writeObject (ObjectOutputStream out)
        throws IOException
    {
        out.writeShort (1);
        out.writeInt (size ());

        final int       tabSize = values.length;
        int             numWritten = 0;

        for (int ii = 0; ii < tabSize; ii++) {
            if (isFilled (ii)) {
                numWritten++;
 				out.writeChar (keys [ii]);
                out.writeInt (values [ii]);
            }
        }

        if (numWritten != size ())
            throw new RuntimeException (
                "Size mismatch: " + numWritten + " instead of " + size ()
            );
    }

    private void                readObject (ObjectInputStream in)
        throws IOException, ClassNotFoundException
    {
    	@SuppressWarnings("unused")
        short           readSerialVersion = in.readShort();

        int             inCount = in.readInt ();

        allocTable (Math.max(inCount, MIN_CAPACITY)); // allocate not less than MIN_CAPACITY

        for (int ii = 0; ii < inCount; ii++) {
            char       key = in.readChar ();
            int     value = in.readInt ();

            put (key, value);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy