Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
package org.elasticsearch.common.util;
import org.elasticsearch.core.Releasables;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* A hash table from native longs to objects. This implementation resolves collisions
* using open-addressing and does not support null values. This class is not thread-safe.
*/
public class LongObjectPagedHashMap extends AbstractPagedHashMap implements Iterable> {
private LongArray keys;
private ObjectArray values;
public LongObjectPagedHashMap(long capacity, BigArrays bigArrays) {
this(capacity, DEFAULT_MAX_LOAD_FACTOR, bigArrays);
}
public LongObjectPagedHashMap(long capacity, float maxLoadFactor, BigArrays bigArrays) {
super(capacity, maxLoadFactor, bigArrays);
boolean success = false;
try {
// `super` allocates a big array so we have to `close` if we fail here or we'll leak it.
keys = bigArrays.newLongArray(capacity(), false);
values = bigArrays.newObjectArray(capacity());
success = true;
} finally {
if (false == success) {
close();
}
}
}
/**
* Get the value that is associated with key or null if key
* was not present in the hash table.
*/
public T get(long key) {
for (long i = slot(hash(key), mask);; i = nextSlot(i, mask)) {
final T value = values.get(i);
if (value == null) {
return null;
} else if (keys.get(i) == key) {
return value;
}
}
}
/**
* Put this new (key, value) pair into this hash table and return the value
* that was previously associated with key or null in case of
* an insertion.
*/
public T put(long key, T value) {
if (size >= maxSize) {
assert size == maxSize;
grow();
}
assert size < maxSize;
return set(key, value);
}
/**
* Remove the entry which has this key in the hash table and return the
* associated value or null if there was no entry associated with this key.
*/
public T remove(long key) {
for (long i = slot(hash(key), mask);; i = nextSlot(i, mask)) {
final T previous = values.set(i, null);
if (previous == null) {
return null;
} else if (keys.get(i) == key) {
--size;
for (long j = nextSlot(i, mask); used(j); j = nextSlot(j, mask)) {
removeAndAdd(j);
}
return previous;
} else {
// repair and continue
values.set(i, previous);
}
}
}
private T set(long key, T value) {
if (value == null) {
throw new IllegalArgumentException("Null values are not supported");
}
for (long i = slot(hash(key), mask);; i = nextSlot(i, mask)) {
final T previous = values.set(i, value);
if (previous == null) {
// slot was free
keys.set(i, key);
++size;
return null;
} else if (key == keys.get(i)) {
// we just updated the value
return previous;
} else {
// not the right key, repair and continue
values.set(i, previous);
}
}
}
@Override
public Iterator> iterator() {
return new Iterator>() {
boolean cached;
final Cursor cursor;
{
cursor = new Cursor<>();
cursor.index = -1;
cached = false;
}
@Override
public boolean hasNext() {
if (cached == false) {
while (true) {
++cursor.index;
if (cursor.index >= capacity()) {
break;
} else if (used(cursor.index)) {
cursor.key = keys.get(cursor.index);
cursor.value = values.get(cursor.index);
break;
}
}
cached = true;
}
return cursor.index < capacity();
}
@Override
public Cursor next() {
if (hasNext() == false) {
throw new NoSuchElementException();
}
cached = false;
return cursor;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
@Override
public void close() {
Releasables.close(keys, values);
}
@Override
protected void resize(long capacity) {
keys = bigArrays.resize(keys, capacity);
values = bigArrays.resize(values, capacity);
}
@Override
protected boolean used(long bucket) {
return values.get(bucket) != null;
}
@Override
protected void removeAndAdd(long index) {
final long key = keys.get(index);
final T value = values.set(index, null);
--size;
final T removed = set(key, value);
assert removed == null;
}
public static final class Cursor {
public long index;
public long key;
public T value;
}
}