InMemoryMessageListStore.java
package net.morimekta.providence.storage;
import net.morimekta.providence.PMessage;
import net.morimekta.providence.descriptor.PField;
import net.morimekta.util.collect.UnmodifiableList;
import net.morimekta.util.concurrent.ReadWriteMutex;
import net.morimekta.util.concurrent.ReentrantReadWriteMutex;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
/**
* Simple in-memory storage of lists providence messages. Uses a local hash map for
* storing the instances.The store is thread safe through using reentrand
* read-write mutex handling, so reading can happen in parallel.
*
* @param <K> The key type.
* @param <M> The stored message type.
*/
public class InMemoryMessageListStore<K, M extends PMessage<M>> implements MessageListStore<K,M> {
private final Map<K, List<M>> map;
private final ReadWriteMutex mutex;
public InMemoryMessageListStore() {
map = new HashMap<>();
mutex = new ReentrantReadWriteMutex();
}
@Nonnull
@Override
public Map<K, List<M>> getAll(@Nonnull Collection<K> keys) {
return mutex.lockForReading(() -> {
Map<K, List<M>> out = new HashMap<>();
for (K key : keys) {
if (map.containsKey(key)) {
out.put(key, map.get(key));
}
}
return out;
});
}
@Override
public boolean containsKey(@Nonnull K key) {
return mutex.lockForReading(() -> map.containsKey(key));
}
@Override @Nonnull
public Collection<K> keys() {
return mutex.lockForReading(() -> new HashSet<>(map.keySet()));
}
@Override
public int size() {
return mutex.lockForReading(map::size);
}
@Override
public void putAll(@Nonnull Map<K, List<M>> values) {
mutex.lockForWriting(() -> {
for (Map.Entry<K,List<M>> entry : values.entrySet()) {
map.put(entry.getKey(), UnmodifiableList.copyOf(entry.getValue()));
}
});
}
@Override
public void removeAll(Collection<K> keys) {
mutex.lockForWriting(() -> map.keySet().removeAll(keys));
}
}