com.launchdarkly.client.InMemoryFeatureStore Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of launchdarkly-client Show documentation
Show all versions of launchdarkly-client Show documentation
Official LaunchDarkly SDK for Java
package com.launchdarkly.client;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* A thread-safe, versioned store for {@link FeatureFlag} objects and related data based on a
* {@link HashMap}. This is the default implementation of {@link FeatureStore}.
*/
public class InMemoryFeatureStore implements FeatureStore {
private static final Logger logger = LoggerFactory.getLogger(InMemoryFeatureStore.class);
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private final Map, Map> allData = new HashMap<>();
private volatile boolean initialized = false;
@Override
public T get(VersionedDataKind kind, String key) {
try {
lock.readLock().lock();
Map items = allData.get(kind);
if (items == null) {
logger.debug("[get] no objects exist for \"{}\". Returning null", kind.getNamespace());
return null;
}
Object o = items.get(key);
if (o == null) {
logger.debug("[get] Key: {} not found in \"{}\". Returning null", key, kind.getNamespace());
return null;
}
if (!kind.getItemClass().isInstance(o)) {
logger.warn("[get] Unexpected object class {} found for key: {} in \"{}\". Returning null",
o.getClass().getName(), key, kind.getNamespace());
return null;
}
T item = kind.getItemClass().cast(o);
if (item.isDeleted()) {
logger.debug("[get] Key: {} has been deleted. Returning null", key);
return null;
}
logger.debug("[get] Key: {} with version: {} found in \"{}\".", key, item.getVersion(), kind.getNamespace());
return item;
} finally {
lock.readLock().unlock();
}
}
@Override
public Map all(VersionedDataKind kind) {
try {
lock.readLock().lock();
Map fs = new HashMap<>();
Map items = allData.get(kind);
if (items != null) {
for (Map.Entry entry : items.entrySet()) {
if (!entry.getValue().isDeleted()) {
fs.put(entry.getKey(), kind.getItemClass().cast(entry.getValue()));
}
}
}
return fs;
} finally {
lock.readLock().unlock();
}
}
@SuppressWarnings("unchecked")
@Override
public void init(Map, Map> allData) {
try {
lock.writeLock().lock();
this.allData.clear();
for (Map.Entry, Map> entry: allData.entrySet()) {
this.allData.put(entry.getKey(), (Map)entry.getValue());
}
initialized = true;
} finally {
lock.writeLock().unlock();
}
}
@Override
public void delete(VersionedDataKind kind, String key, int version) {
try {
lock.writeLock().lock();
Map items = allData.get(kind);
if (items == null) {
items = new HashMap<>();
allData.put(kind, items);
}
VersionedData item = items.get(key);
if (item == null || item.getVersion() < version) {
items.put(key, kind.makeDeletedItem(key, version));
}
} finally {
lock.writeLock().unlock();
}
}
@Override
public void upsert(VersionedDataKind kind, T item) {
try {
lock.writeLock().lock();
Map items = (Map) allData.get(kind);
if (items == null) {
items = new HashMap<>();
allData.put(kind, items);
}
VersionedData old = items.get(item.getKey());
if (old == null || old.getVersion() < item.getVersion()) {
items.put(item.getKey(), item);
}
} finally {
lock.writeLock().unlock();
}
}
@Override
public boolean initialized() {
return initialized;
}
/**
* Does nothing; this class does not have any resources to release
*
* @throws IOException will never happen
*/
@Override
public void close() throws IOException {
return;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy