package org.qrone.memcached; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.mozilla.javascript.Scriptable; import org.qrone.mongo.MongoTable; import org.qrone.r7.script.AbstractScriptable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.danga.MemCached.MemCachedClient; import com.danga.MemCached.SockIOPool; public class LocalMemcachedService extends AbstractScriptable implements MemcachedService{ private static Logger log = LoggerFactory.getLogger(LocalMemcachedService.class); private static SockIOPool pool; private String domain; private MemCachedClient client; private Map<String, LocalMemcached> map = new Hashtable<String, LocalMemcached>(); public LocalMemcachedService(String[] serverlist, String domain) { if (pool == null) { SockIOPool pool = SockIOPool.getInstance(); pool.setServers(serverlist); pool.initialize(); } client = new MemCachedClient(); this.domain = domain; } @Override public Memcached getKeyValueStore(String name) { LocalMemcached t = map.get(name); if(t == null){ t = new LocalMemcached(client, domain + "/" + name); map.put(name, t); } return t; } @Override public Object get(String key, Scriptable start) { return getKeyValueStore(key); } @Override public Object[] getIds() { return map.keySet().toArray(new Object[map.size()]); } public static class LocalMemcached implements Memcached{ private String collection; private MemCachedClient client; public LocalMemcached(MemCachedClient client, String collection) { this.collection = collection; this.client = client; } @Override public void clearAll() { log.debug("Memcached FLUSHALL (collection:{})", collection); client.flushAll(); } @Override public boolean contains(String key) { log.debug("Memcached KEYEXISTS (collection:{} key:{})", collection, key); return client.keyExists(collection + key); } @Override public boolean remove(String key) { log.debug("Memcached DELETE (collection:{} key:{})", collection, key); return client.delete(collection + key); } @Override public boolean remove(String key, long millisNoReAdd) { log.debug("Memcached DELETE (collection:{} key:{})", collection, key); return client.delete(collection + key, new Date(System.currentTimeMillis()+millisNoReAdd)); } @Override public Set<String> removeAll(Collection<String> keys) { Set<String> set = new HashSet<String>(); for (Iterator<String> i = keys.iterator(); i.hasNext();) { String string = i.next(); if(remove(string)) set.add(string); } return set; } @Override public Set<String> removeAll(Collection<String> keys, long millisNoReAdd) { Set<String> set = new HashSet<String>(); for (Iterator<String> i = keys.iterator(); i.hasNext();) { String string = i.next(); if(remove(string,millisNoReAdd)) set.add(string); } return set; } @Override public Object get(String key) { log.debug("Memcached GET (collection:{} key:{})", collection, key); return client.get(collection + key); } @Override public Map<String, Object> getAll(Collection<String> keys) { log.debug("Memcached GETMULTI (collection:{} key:{})", collection, keys); String[] keysori = keys.toArray(new String[keys.size()]); String[] keysary = new String[keys.size()]; for (int i = 0; i < keysary.length; i++) { keysary[i] = collection + keysori[i]; } return client.getMulti(keysary); } @Override public long increment(String key, long delta) { log.debug("Memcached INCREMENT (collection:{} key:{})", collection, key); return client.incr(collection + key, delta); } @Override public void put(String key, Object value) { log.debug("Memcached SET (collection:{} key:{})", collection, key); client.set(collection + key, value); } @Override public void put(String key, Object value, int ttlmillis) { log.debug("Memcached SET (collection:{} key:{})", collection, key); client.set(collection + key, value, new Date(System.currentTimeMillis()+ttlmillis)); } @Override public void put(String key, Object value, Date expire) { log.debug("Memcached SET (collection:{} key:{})", collection, key); client.set(collection + key, value, expire); } @Override public void put(String key, Object value, int ttlmillis, SetPolicy policy) { put(key, value, new Date(System.currentTimeMillis()+ttlmillis), policy); } @Override public void put(String key, Object value, Date expire, SetPolicy policy) { if(policy == SetPolicy.SET_ALWAYS){ client.set(collection + key, value, expire); }else if(policy == SetPolicy.REPLACE_ONLY_IF_PRESENT){ client.replace(collection + key, value, expire); }else if(policy == SetPolicy.ADD_ONLY_IF_NOT_PRESENT){ if(!client.keyExists(collection + key)) client.set(collection + key, value, expire); } } @Override public void putAll(Map<String, Object> values) { for (Iterator<Entry<String, Object>> i = values.entrySet().iterator(); i .hasNext();) { Entry<String, Object> v = i.next(); put(v.getKey(),v.getValue()); } } @Override public void putAll(Map<String, Object> values, int ttlmillis) { for (Iterator<Entry<String, Object>> i = values.entrySet().iterator(); i .hasNext();) { Entry<String, Object> v = i.next(); put(v.getKey(),v.getValue(),ttlmillis); } } @Override public void putAll(Map<String, Object> values, Date expire) { for (Iterator<Entry<String, Object>> i = values.entrySet().iterator(); i .hasNext();) { Entry<String, Object> v = i.next(); put(v.getKey(),v.getValue(),expire); } } @Override public void putAll(Map<String, Object> values, int ttlmillis, SetPolicy policy) { for (Iterator<Entry<String, Object>> i = values.entrySet().iterator(); i .hasNext();) { Entry<String, Object> v = i.next(); put(v.getKey(),v.getValue(),ttlmillis, policy); } } @Override public void putAll(Map<String, Object> values, Date expire, SetPolicy policy) { for (Iterator<Entry<String, Object>> i = values.entrySet().iterator(); i .hasNext();) { Entry<String, Object> v = i.next(); put(v.getKey(),v.getValue(),expire, policy); } } } }