/*
* Copyright (C) 2015 Actor LLC. <https://actor.im>
*/
package im.actor.runtime.generic.storage;
import java.util.ArrayList;
import java.util.List;
import im.actor.runtime.actors.ActorCreator;
import im.actor.runtime.actors.ActorRef;
import im.actor.runtime.actors.Props;
import im.actor.runtime.bser.BserCreator;
import im.actor.runtime.bser.BserObject;
import im.actor.runtime.storage.ListEngineDisplayLoadCallback;
import im.actor.runtime.storage.ListEngineItem;
import im.actor.runtime.storage.ListStorageDisplayEx;
import static im.actor.runtime.actors.ActorSystem.system;
class AsyncStorageInt<T extends BserObject & ListEngineItem> {
static {
system().addDispatcher("db", 1);
}
private static int NEXT_ID = 0;
private ActorRef storageActor;
public AsyncStorageInt(final ListStorageDisplayEx storage, final BserCreator<T> creator) {
storageActor = system().actorOf(Props.create(() -> new AsyncStorageActor<T>(storage, creator)).changeDispatcher("db"), "list_engine/" + NEXT_ID++);
}
public void addOrUpdateItems(List<T> items) {
storageActor.send(new AsyncStorageActor.AddOrUpdate<T>(items));
}
public void replaceItems(List<T> items) {
storageActor.send(new AsyncStorageActor.Replace<T>(items));
}
public void remove(long[] keys) {
storageActor.send(new AsyncStorageActor.Remove(keys));
}
public void clear() {
storageActor.send(new AsyncStorageActor.Clear());
}
// Sync
public T getValue(long value) {
final Object lock = new Object();
final List<T> resultList = new ArrayList<>();
synchronized (lock) {
storageActor.send(new AsyncStorageActor.LoadItem<T>(value, item -> {
synchronized (lock) {
if (item != null) {
resultList.add(item);
}
lock.notify();
}
}));
try {
lock.wait();
} catch (InterruptedException e) {
return null;
}
if (resultList.size() > 0) {
return resultList.get(0);
} else {
return null;
}
}
}
public T getHeadValue() {
final Object lock = new Object();
final List<T> resultList = new ArrayList<>();
synchronized (lock) {
storageActor.send(new AsyncStorageActor.LoadHead<T>(item -> {
synchronized (lock) {
if (item != null) {
resultList.add(item);
}
lock.notify();
}
}));
try {
lock.wait();
} catch (InterruptedException e) {
return null;
}
if (resultList.size() > 0) {
return resultList.get(0);
} else {
return null;
}
}
}
public int getCount() {
final Object lock = new Object();
final List<Integer> resultList = new ArrayList<>();
synchronized (lock) {
storageActor.send(new AsyncStorageActor.LoadCount(count -> {
synchronized (lock) {
resultList.add(count);
lock.notify();
}
}));
try {
lock.wait();
} catch (InterruptedException e) {
return 0;
}
if (resultList.size() > 0) {
return resultList.get(0);
} else {
return 0;
}
}
}
// Display list
public void loadForward(String query, Long afterSortKey, int limit, ListEngineDisplayLoadCallback<T> callback) {
storageActor.send(new AsyncStorageActor.LoadForward<T>(query, afterSortKey, limit, callback));
}
public void loadBackward(String query, Long beforeSortKey, int limit, ListEngineDisplayLoadCallback<T> callback) {
storageActor.send(new AsyncStorageActor.LoadBackward<T>(query, beforeSortKey, limit, callback));
}
public void loadCenter(long centerSortKey, int limit, ListEngineDisplayLoadCallback<T> callback) {
storageActor.send(new AsyncStorageActor.LoadCenter<T>(centerSortKey, limit, callback));
}
}