com.epam.deltix.util.collections.generated.ShortToLongHashMap Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of timebase-collections Show documentation
Show all versions of timebase-collections Show documentation
Timebase Common utilities and collections
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 ShortToLongHashMap
extends ShortHashMapBase
{
protected long [] values;
public ShortToLongHashMap () {
super ();
}
public ShortToLongHashMap (int cap) {
super (cap);
}
public ShortToLongHashMap (HashCodeComputer hashCodeComputer) {
super (0, hashCodeComputer);
}
public ShortToLongHashMap (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 short [] saveKeys = keys;
final long [] 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 long get (short 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 (short key, long notFoundValue) {
int idx = find (key);
if (idx == NULL)
return (notFoundValue);
long value = values [idx];
free (idx);
return (value);
}
private void putNewNoSpaceCheck (short 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 (short 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 (
short 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 (
short 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 (
short 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, ShortEntry
{
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 Short key () {
return keys [pos];
}
@Override
public short keyShort () {
return (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.writeShort (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++) {
short key = in.readShort ();
long value = in.readLong ();
put (key, value);
}
}
}