de.otto.synapse.state.ConcurrentMapStateRepository Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of synapse-core Show documentation
Show all versions of synapse-core Show documentation
A library used at otto.de to implement Spring Boot based event-sourcing microservices.
package de.otto.synapse.state;
import org.slf4j.Logger;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import static java.util.Collections.unmodifiableSet;
import static java.util.Objects.requireNonNull;
import static java.util.Optional.ofNullable;
import static org.slf4j.LoggerFactory.getLogger;
/**
* High performance in-memory StateRepository implemented using a ConcurrentMap.
*
* @param
*/
public class ConcurrentMapStateRepository implements StateRepository {
private static final Logger LOG = getLogger(ConcurrentMapStateRepository.class);
private final String name;
private final ConcurrentMap concurrentMap;
/**
* Creates a StateRepository with the given name, that is using a {@code ConcurrentHashMap} to store
* event-sourced entities.
*
* @param name the {@link #getName() name} of the repository.
*/
public ConcurrentMapStateRepository(final String name) {
this(name, new ConcurrentHashMap<>());
}
/**
* Creates a StateRepository with the given name, that is using the given {@code ConcurrentMap} to store
* event-sourced entities.
*
* Usable to create StateRepository instances from ConcurrentMap implementations like, for example,
* ChronicleMap
*
* @param name the {@link #getName() name} of the repository.
* @param map the delegate map used to store the entity state
*/
public ConcurrentMapStateRepository(final String name,
final ConcurrentMap map) {
this.name = requireNonNull(name, "Parameter 'name' must not be null");
this.concurrentMap = requireNonNull(map, "Parameter 'map' must not be null");
}
@Override
public String getName() {
return name;
}
@Override
public Optional compute(final String key, final BiFunction super String, ? super Optional, ? extends V> remappingFunction) {
return ofNullable(concurrentMap.compute(key, (k, v) -> remappingFunction.apply(k, ofNullable(v))));
}
@Override
public void consumeAll(BiConsumer super String, ? super V> consumer) {
concurrentMap.forEach(consumer);
}
@Override
public Optional put(final String key, final V value) {
return ofNullable(concurrentMap.put(key, value));
}
@Override
public Optional remove(final String key) {
return ofNullable(concurrentMap.remove(key));
}
@Override
public void clear() {
concurrentMap.clear();
}
@Override
public Optional get(final String key) {
return ofNullable(concurrentMap.get(key));
}
@Override
public Set keySet() {
return unmodifiableSet(concurrentMap.keySet());
}
@Override
public long size() {
return concurrentMap.size();
}
@Override
public void close() throws Exception {
LOG.info("Closing StateRepository.");
if (concurrentMap instanceof AutoCloseable) {
((AutoCloseable) concurrentMap).close();
}
}
}