/*
* Copyright (C) 2015 Actor LLC. <https://actor.im>
*/
package im.actor.core.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import im.actor.runtime.actors.messages.Void;
import im.actor.runtime.promise.Promise;
import im.actor.runtime.storage.KeyValueEngine;
import im.actor.runtime.storage.KeyValueItem;
import im.actor.runtime.storage.KeyValueRecord;
import im.actor.runtime.storage.KeyValueStorage;
public abstract class BaseKeyValueEngine<T extends KeyValueItem> implements KeyValueEngine<T> {
private final HashMap<Long, T> cache = new HashMap<>();
private KeyValueStorage storage;
protected BaseKeyValueEngine(KeyValueStorage storage) {
this.storage = storage;
}
protected abstract byte[] serialize(T value);
protected abstract T deserialize(byte[] data);
@Override
public synchronized void addOrUpdateItem(T item) {
cache.put(item.getEngineId(), item);
byte[] data = serialize(item);
storage.addOrUpdateItem(item.getEngineId(), data);
}
@Override
public synchronized void addOrUpdateItems(List<T> values) {
for (T t : values) {
cache.put(t.getEngineId(), t);
}
ArrayList<KeyValueRecord> records = new ArrayList<>();
for (T v : values) {
records.add(new KeyValueRecord(v.getEngineId(), serialize(v)));
}
storage.addOrUpdateItems(records);
}
@Override
public synchronized void removeItem(long id) {
cache.remove(id);
storage.removeItem(id);
}
@Override
public synchronized void removeItems(long[] ids) {
for (long l : ids) {
cache.remove(l);
}
storage.removeItems(ids);
}
@Override
public synchronized void clear() {
cache.clear();
storage.clear();
}
@Override
public synchronized T getValue(long id) {
if (cache.containsKey(id)) {
return cache.get(id);
}
byte[] data = storage.loadItem(id);
if (data != null) {
T res = deserialize(data);
if (res != null) {
cache.put(res.getEngineId(), res);
return res;
}
}
return null;
}
@Override
public Promise<T> getValueAsync(long key) {
T res = getValue(key);
if (res != null) {
return Promise.success(res);
} else {
return Promise.failure(new RuntimeException());
}
}
@Override
public Promise<Boolean> containsAsync(long key) {
T res = getValue(key);
return Promise.success(res != null);
}
}