Slim3のMemcacheを利用してDatastoreアクセスを少なくする その2
Slim3のMemcacheを利用してDatastoreアクセスを少なくする その1 - GAE + GWT プログラミングメモ
の続き
overwrite実装
上書き保存のための実装。
Slim3では、保存しようとしているKeyが既に存在する場合は、上書きする。
public class DataAccessor<T extends Slim3Model> { private DaoBase<T> dao; private KeyMemcache memcache = new KeyMemcache(); public List<Key> overwrite(Collection<T> modelCollection) { Map<Key, T> map = new HashMap<Key, T>(); for (T model : modelCollection) { map.put(model.getKey(), model); } memcache.putAll(map); return dao.put(new ArrayList<T>(modelCollection)); } }
dao.putするついでに、memcache.putAllして、Memcacheに保存し、次回アクセスを速くする。
write実装
writeはDatastoreに既にKeyが存在する場合、上書きしたくないときのための実装。
public class DataAccessor<T extends Slim3Model> { public List<Key> write(Collection<T> modelCollection) { List<T> storedList = read(toKeyList(modelCollection)); Collection<T> subtract = CollectionUtils.subtract(modelCollection, storedList); return overwrite(subtract); } private List<Key> toKeyList(Collection<T> modelCollection) { List<Key> keyList = new ArrayList<Key>(); for (T model : modelCollection) { keyList.add(model.getKey()); } return keyList; } }
readで保存してあるListを取得し、書き込もうとしている集合との差集合subtractをとる。
この差集合のみoverwriteする。
全実装
public class DataAccessor<T extends Slim3Model> { private DaoBase<T> dao; private KeyMemcache memcache = new KeyMemcache(); public DataAccessor(DaoBase<T> dao) { this.dao = dao; } public T read(Key key) { List<Key> keyList = new ArrayList<Key>(); keyList.add(key); return read(keyList).get(0); } public List<T> read(List<Key> keyList) { Map<Key, T> memcachedModelMap = memcache.getAll(keyList); Map<Key, T> daoModelMap = getDaoModelMap(keyList, memcachedModelMap); memcache.putAll(daoModelMap); List<T> modelList = new ArrayList<T>(); for (Key key : keyList) { if (memcachedModelMap.containsKey(key)) { modelList.add(memcachedModelMap.get(key)); } else if (daoModelMap.containsKey(key)) { modelList.add(daoModelMap.get(key)); } } return modelList; } private Map<Key, T> getDaoModelMap(List<Key> keyList, Map<Key, T> memcachedModelMap) { Collection<Key> subtractedCollection = CollectionUtils.subtract(keyList, memcachedModelMap.keySet()); List<Key> subtractedList = new ArrayList<Key>(subtractedCollection); return dao.getAsMap(subtractedList); } public List<Key> overwrite(Collection<T> modelCollection) { Map<Key, T> map = new HashMap<Key, T>(); for (T model : modelCollection) { map.put(model.getKey(), model); } memcache.putAll(map); return dao.put(new ArrayList<T>(modelCollection)); } public List<Key> write(Collection<T> modelCollection) { List<T> storedList = read(toKeyList(modelCollection)); Collection<T> subtract = CollectionUtils.subtract(modelCollection, storedList); return overwrite(subtract); } private List<Key> toKeyList(Collection<T> modelCollection) { List<Key> keyList = new ArrayList<Key>(); for (T model : modelCollection) { keyList.add(model.getKey()); } return keyList; } private class KeyMemcache { public void putAll(Map<Key, T> values) { Map<Object, Object> objectMap = new HashMap<Object, Object>(); for (Entry<Key, T> entry : values.entrySet()) { Object key = entry.getKey(); Object model = entry.getValue(); objectMap.put(key, model); } Memcache.putAll(objectMap); } public Map<Key, T> getAll(List<Key> keyList) { Map<Key, T> map = new HashMap<Key, T>(); Map<Object, Object> memcachedMap = Memcache.getAll(keyList); for (Entry<Object, Object> entry : memcachedMap.entrySet()) { Key key = (Key) entry.getKey(); @SuppressWarnings("unchecked") T model = (T) entry.getValue(); map.put(key, model); } return map; } } }