com.strobel.collections.concurrent.ConcurrentRefValueIntObjectHashMap Maven / Gradle / Ivy
package com.strobel.collections.concurrent;
import com.strobel.annotations.NotNull;
import com.strobel.util.ContractUtils;
import java.lang.ref.ReferenceQueue;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* @author strobelm
*/
abstract class ConcurrentRefValueIntObjectHashMap implements ConcurrentIntObjectMap {
private final ConcurrentIntObjectHashMap> _map = new ConcurrentIntObjectHashMap<>();
private final ReferenceQueue _queue = new ReferenceQueue<>();
protected interface IntReference {
int key();
V get();
}
protected abstract IntReference createReference(final int key, @NotNull final V value, final ReferenceQueue queue);
@SuppressWarnings("unchecked")
private void processQueue() {
while (true) {
final IntReference reference = (IntReference)_queue.poll();
if (reference == null) {
return;
}
_map.remove(reference.key(), reference);
}
}
@NotNull
@Override
public V addOrGet(final int key, @NotNull final V value) {
processQueue();
final IntReference newReference = createReference(key, value, _queue);
while (true) {
final IntReference oldReference = _map.putIfAbsent(key, newReference);
if (oldReference == null) {
return value;
}
final V oldValue = oldReference.get();
if (oldValue != null) {
return oldValue;
}
final boolean replaced = _map.replace(key, oldReference, newReference);
if (replaced) {
return value;
}
}
}
@Override
public V putIfAbsent(final int key, @NotNull final V value) {
processQueue();
final IntReference newReference = createReference(key, value, _queue);
while (true) {
final IntReference oldReference = _map.putIfAbsent(key, newReference);
if (oldReference == null) {
return null;
}
final V oldValue = oldReference.get();
if (oldValue != null) {
return oldValue;
}
final boolean replaced = _map.replace(key, oldReference, newReference);
if (replaced) {
return null;
}
}
}
@Override
public boolean remove(final int key, @NotNull final V value) {
processQueue();
return _map.remove(key, createReference(key, value, _queue));
}
@Override
public boolean replace(final int key, @NotNull final V oldValue, @NotNull final V newValue) {
processQueue();
return _map.replace(
key,
createReference(key, oldValue, _queue),
createReference(key, newValue, _queue)
);
}
@Override
public V put(final int key, @NotNull final V value) {
processQueue();
final IntReference oldReference = _map.put(key, createReference(key, value, _queue));
return oldReference != null ? oldReference.get()
: null;
}
@Override
public V get(final int key) {
final IntReference reference = _map.get(key);
return reference != null ? reference.get()
: null;
}
@Override
public V remove(final int key) {
processQueue();
final IntReference reference = _map.remove(key);
return reference != null ? reference.get()
: null;
}
@Override
public int size() {
return _map.size();
}
@Override
public boolean isEmpty() {
return _map.isEmpty();
}
@Override
public boolean contains(final int key) {
return _map.contains(key);
}
@Override
public void clear() {
_map.clear();
processQueue();
}
@NotNull
@Override
public int[] keys() {
return _map.keys();
}
@NotNull
@Override
public Iterable> entries() {
return new Iterable>() {
@Override
public Iterator> iterator() {
return new Iterator>() {
final Iterator>> entryIterator = _map.entries().iterator();
IntObjectEntry next = nextLiveEntry();
@Override
public boolean hasNext() {
return next != null;
}
@Override
public IntObjectEntry next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
final IntObjectEntry result = next;
next = nextLiveEntry();
return result;
}
@Override
public void remove() {
throw ContractUtils.unsupported();
}
private IntObjectEntry nextLiveEntry() {
while (entryIterator.hasNext()) {
final IntObjectEntry> entry = entryIterator.next();
final V value = entry.value().get();
if (value == null) {
continue;
}
final int key = entry.key();
return new IntObjectEntry() {
@Override
public int key() {
return key;
}
@NotNull
@Override
public V value() {
return value;
}
};
}
return null;
}
};
}
};
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy