package io.qdb.kvstore;
import java.io.*;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
/**
* Clustered in memory key/value store for objects. See README.md for more information. Create instances
* using {@link KeyValueStoreBuilder}.
*/
public interface KeyValueStore<K, V> extends Closeable {
/**
* Get a map for storing objects. It is only actually created when the first object is stored.
* All methods in the map might throw {@link KeyValueStoreException}.
*/
ConcurrentMap<K, V> getMap(String name);
/**
* Get a map for storing objects of a particular type. Note that the type restriction isn't enforced.
*/
<T extends V> ConcurrentMap<K, T> getMap(String name, Class<T> cls);
/**
* Save a snapshot. This is a NOP if we are already busy saving a snapshot or if no new transactions have been
* applied since the most recent snapshot was saved.
*/
void saveSnapshot() throws IOException;
/**
* Does this store contain no objects?
*/
boolean isEmpty();
/**
* Get the names of all of the maps in this store.
*/
List<String> getMapNames();
/** Extracts version numbers from objects for optimistic locking. */
interface VersionProvider<V> {
/** Get the version of value or null if it does not have a version. */
public Object getVersion(V value);
/** Bump up the version number of value. NOP if not using versioning. */
public void incVersion(V value);
}
/**
* Receives notification of changes to the store. Extend {@link ListenerAdapter} instead of implementing this
* interface directly so your code won't break if new methods are addeded.
*/
interface Listener<K, V> {
/** An object has been created, updated or deleted. */
void onObjectEvent(ObjectEvent<K, V> ev);
}
public static class ListenerAdapter<K, V> implements Listener<K, V> {
public void onObjectEvent(ObjectEvent<K, V> ev) { }
}
/**
* A data change to a store.
*/
public static class ObjectEvent<K, V> {
public enum Type { CREATED, UPDATED, DELETED }
public final KeyValueStore<K, V> store;
public final String map;
public final Type type;
public final K key;
public final V value;
public ObjectEvent(KeyValueStore<K, V> store, String map, Type type, K key, V value) {
this.store = store;
this.type = type;
this.map = map;
this.key = key;
this.value = value;
}
@Override
public String toString() {
return type + " " + map + "." + key + "=" + value;
}
}
}