com.epam.deltix.util.collections.generated.LongToDoubleHashMap 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 LongToDoubleHashMap
extends LongHashMapBase
{
protected double [] values;
public LongToDoubleHashMap () {
super ();
}
public LongToDoubleHashMap (int cap) {
super (cap);
}
public LongToDoubleHashMap (HashCodeComputer hashCodeComputer) {
super (0, hashCodeComputer);
}
public LongToDoubleHashMap (int cap, HashCodeComputer hashCodeComputer) {
super (cap, hashCodeComputer);
}
@Override
protected void allocTable (int cap) {
super.allocTable (cap);
values = new double [cap];
}
@Override
public long getSizeInMemory () {
return (
super.getSizeInMemory () + (SIZE_OF_POINTER + ARRAY_OVERHEAD) +
values.length * SIZE_OF_DOUBLE
);
}
protected void resizeTable (int newSize) {
final int curLength = values.length;
final long [] saveKeys = keys;
final double [] 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 double get (long key, double 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 double remove (long key, double notFoundValue) {
int idx = find (key);
if (idx == NULL)
return (notFoundValue);
double value = values [idx];
free (idx);
return (value);
}
private void putNewNoSpaceCheck (long key, double 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 (long key, double 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 double putAndGet (
long key,
double value,
double notFoundValue
)
{
int hidx = hashIndex (key);
int idx = find (hidx, key);
if (idx != NULL) {
double 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 double putAndGetIfEmpty (
long key,
double 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 (
long key,
double 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 (double value) {
int tabSize = values.length;
for (int ii = 0; ii < tabSize; ii++)
if (isFilled (ii) && values [ii] == value)
return (true);
return (false);
}
public final double [] valuesToArray (double [] ret) {
if (ret == null || ret.length < count)
ret = new double [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 DoubleEnumeration, LongEntry
{
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 Double nextElement () {
double ret = values [pos];
move ();
return (ret);
}
@Override
public double nextDoubleElement () {
double ret = values [pos];
move ();
return (ret);
}
@Override
public Long key () {
return keys [pos];
}
@Override
public long keyLong () {
return (keys [pos]);
}
}
public DoubleEnumeration 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.writeLong (keys [ii]);
out.writeDouble (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++) {
long key = in.readLong ();
double value = in.readDouble ();
put (key, value);
}
}
}