/* * Copyright (C) 2015 Actor LLC. <https://actor.im> */ package im.actor.runtime.js.storage; import com.google.gwt.storage.client.Storage; import java.util.HashSet; import java.util.List; import java.util.Set; import im.actor.runtime.Log; import im.actor.runtime.bser.DataInput; import im.actor.runtime.bser.DataOutput; import im.actor.runtime.storage.KeyValueRecord; import im.actor.runtime.storage.KeyValueStorage; import static im.actor.runtime.crypto.Base64Utils.fromBase64; import static im.actor.runtime.crypto.Base64Utils.toBase64; public class JsKeyValueStorage implements KeyValueStorage { private static final String TAG = "JsKeyValueStorage"; private Storage storage; private String prefix; private Set<Long> items = new HashSet<Long>(); public JsKeyValueStorage(String prefix, Storage storage) { this.storage = storage; this.prefix = prefix; try { String index = storage.getItem("kv_" + prefix + "_index"); if (index != null) { byte[] data = fromBase64(index); DataInput dataInput = new DataInput(data, 0, data.length); int count = dataInput.readInt(); for (int i = 0; i < count; i++) { items.add(dataInput.readLong()); } } } catch (Exception e) { Log.e(TAG, e); } } @Override public void addOrUpdateItem(long id, byte[] data) { storage.setItem(getId(id), toBase64(data)); if (!items.contains(id)) { items.add(id); saveIndex(); } } @Override public void addOrUpdateItems(List<KeyValueRecord> values) { boolean isAdded = false; for (KeyValueRecord record : values) { long id = record.getId(); storage.setItem(getId(id), toBase64(record.getData())); if (!items.contains(id)) { items.add(id); isAdded = true; } } if (isAdded) { saveIndex(); } } @Override public void removeItem(long id) { if (!items.contains(id)) { return; } storage.removeItem(getId(id)); items.remove(id); saveIndex(); } @Override public void removeItems(long[] ids) { boolean isRemoved = false; for (long id : ids) { if (items.contains(id)) { storage.removeItem(getId(id)); items.remove(id); isRemoved = true; } } if (isRemoved) { saveIndex(); } } @Override public byte[] loadItem(long key) { String res = storage.getItem(getId(key)); if (res == null) { return null; } else { return fromBase64(res); } } @Override public List<KeyValueRecord> loadItems(long[] keys) { // TODO: Implement return null; } @Override public List<KeyValueRecord> loadAllItems() { // TODO: Implement return null; } @Override public void clear() { for (long id : items) { storage.removeItem(getId(id)); } storage.removeItem("kv_" + prefix + "_index"); items.clear(); } private void saveIndex() { DataOutput dataOutput = new DataOutput(); dataOutput.writeInt(items.size()); for (long l : items) { dataOutput.writeLong(l); } storage.setItem("kv_" + prefix + "_index", toBase64(dataOutput.toByteArray())); } private String getId(long id) { return "kv_" + prefix + "_" + id; } }