InMemorySetStore.java

  1. package net.morimekta.providence.storage;

  2. import net.morimekta.util.concurrent.ReadWriteMutex;
  3. import net.morimekta.util.concurrent.ReentrantReadWriteMutex;

  4. import javax.annotation.Nonnull;
  5. import java.util.Collection;
  6. import java.util.HashMap;
  7. import java.util.HashSet;
  8. import java.util.Map;
  9. import java.util.function.Function;

  10. /**
  11.  * Simple in-memory set storage of providence messages. Uses a local hash map for
  12.  * storing the instances. The store is thread safe through using re-entrant
  13.  * read-write mutex handling, so reading can happen in parallel.
  14.  */
  15. public class InMemorySetStore<K, M> implements ReadWriteSetStore<K,M> {
  16.     private final Map<K, M>      map;
  17.     private final ReadWriteMutex mutex;
  18.     private final Function<M, K> messageToKey;

  19.     public InMemorySetStore(Function<M,K> messageToKey) {
  20.         this.messageToKey = messageToKey;
  21.         this.map   = new HashMap<>();
  22.         this.mutex = new ReentrantReadWriteMutex();
  23.     }

  24.     @Nonnull
  25.     @Override
  26.     public Map<K, M> getAll(@Nonnull Collection<K> keys) {
  27.         return mutex.lockForReading(() -> {
  28.             Map<K, M> out = new HashMap<>();
  29.             for (K key : keys) {
  30.                 if (map.containsKey(key)) {
  31.                     out.put(key, map.get(key));
  32.                 }
  33.             }
  34.             return out;
  35.         });
  36.     }

  37.     @Override
  38.     public boolean containsKey(@Nonnull K key) {
  39.         return mutex.lockForReading(() -> map.containsKey(key));
  40.     }

  41.     @Override @Nonnull
  42.     public Collection<K> keys() {
  43.         return mutex.lockForReading(() -> new HashSet<>(map.keySet()));
  44.     }

  45.     @Override
  46.     public int size() {
  47.         return mutex.lockForReading(map::size);
  48.     }

  49.     @Override
  50.     public void putAll(@Nonnull Collection<M> values) {
  51.         mutex.lockForWriting(() -> {
  52.             for (M entry : values) {
  53.                 map.put(messageToKey.apply(entry), entry);
  54.             }
  55.         });
  56.     }

  57.     @Override
  58.     public void removeAll(Collection<K> keys) {
  59.         mutex.lockForWriting(() -> map.keySet().removeAll(keys));
  60.     }
  61. }