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

com.epam.deltix.util.collections.generated.ObjectToLongHashMap 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 ObjectToLongHashMap 

    extends ObjectHashMapBase 
{
    protected long [] values;

    public ObjectToLongHashMap () {
        super ();
    }

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

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

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

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

        values = new long [cap];
    }

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


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

        allocTable (newSize);

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

    public long               get (K key, long 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 long               remove (K key, long notFoundValue) {
        int         idx = find (key);

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

        long        value = values [idx];

        free (idx);

        return (value);
    }

    private void                putNewNoSpaceCheck (K key, long 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 (K key, long 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 long               putAndGet (
        K                       key,
        long                     value,
        long                     notFoundValue
    )
    {
        int         hidx = hashIndex (key);
        int         idx = find (hidx, key);

        if (idx != NULL) {
            long    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 long               putAndGetIfEmpty (
        K                   key,
        long                 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 (
        K                   key,
        long                 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 (long value) {
    	int         tabSize = values.length;

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

    	return (false);
    }

    public final long []   valuesToArray (long [] ret) {
        if (ret == null || ret.length < count)
            ret = new long [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 LongEnumeration, KeyEntry 
    {
    	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 Long           nextElement () {
    		long   ret = values [pos];
    		move ();
    		return (ret);
    	}

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

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

    public LongEnumeration    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.writeObject (keys [ii]);
                out.writeLong (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++) {
            K       key = (K)in.readObject ();
            long     value = in.readLong ();

            put (key, value);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy