package com.quickserverlab.quickcached.cache.impl; import java.util.LinkedHashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import com.quickserverlab.quickcached.CommandHandler; import com.quickserverlab.quickcached.DataCarrier; import com.quickserverlab.quickcached.QuickCached; import com.quickserverlab.quickcached.cache.CacheException; import com.quickserverlab.quickcached.cache.CacheInterface; /** * BaseCacheImpl implementation * @author akshath */ public abstract class BaseCacheImpl implements CacheInterface { private static final Logger logger = Logger.getLogger(BaseCacheImpl.class.getName()); public abstract String getName(); public abstract long getSize(); public abstract void setToCache(String key, Object value, int objectSize, int expInSec) throws Exception; public abstract void updateToCache(String key, Object value, int objectSize, int expInSec) throws Exception; public abstract void updateToCache(String key, Object value, int objectSize) throws Exception; public abstract Object getFromCache(String key) throws Exception; public abstract boolean deleteFromCache(String key) throws Exception; public abstract void flushCache() throws Exception; private long totalItems; private long cmdGets; private long cmdSets; private long cmdDeletes; private long cmdFlushs; private long cmdTouchs; private long getHits; private long getMisses; private long deleteMisses; private long deleteHits; private long touchMisses; private long touchHits; private double avgKeySize = -1; private double avgValueSize = -1; private double avgTtl = -1; public void saveStats(Map stats) { if(stats==null) stats = new LinkedHashMap(); //curr_items - Current number of items stored by the server stats.put("curr_items", "" + getSize()); //total_items - Total number of items stored by this server ever since it started stats.put("total_items", "" + totalItems); //cmd_get Cumulative number of retrieval reqs stats.put("cmd_get", "" + cmdGets); //cmd_set Cumulative number of storage reqs stats.put("cmd_set", "" + cmdSets); //cmd_delete stats.put("cmd_delete", "" + cmdDeletes); //cmd_touch stats.put("cmd_touch", "" + cmdTouchs); //cmd_flush stats.put("cmd_flush", "" + cmdFlushs); //get_hits Number of keys that have been requested and found present stats.put("get_hits", "" + getHits); //get_misses Number of items that have been requested and not found stats.put("get_misses", "" + getMisses); //delete_misses Number of deletions reqs for missing keys stats.put("delete_misses", "" + deleteMisses); //delete_hits Number of deletion reqs resulting in stats.put("delete_hits", "" + deleteHits); //touch_hits Numer of keys that have been touched with a new expiration time stats.put("touch_hits", "" + touchHits); //touch_misses Numer of items that have been touched and not found stats.put("touch_misses", "" + touchMisses); if(CommandHandler.isComputeAvgForSetCmd()) { stats.put("avg_key_size", "" + (long)(0.5+avgKeySize)); stats.put("avg_value_size", "" + (long)(0.5+avgValueSize)); stats.put("avg_ttl", "" + (long)(0.5+avgTtl)); } } public void set(String key, Object value, int objectSize, int expInSec) throws CacheException { if(QuickCached.DEBUG) logger.log(Level.FINE, "set key: {0}; objectsize: {1};", new Object[]{key, objectSize}); cmdSets++; try { setToCache(key, value, objectSize, expInSec); totalItems++; if(CommandHandler.isComputeAvgForSetCmd()) { long cmdSetsCurrent = cmdSets; if(avgKeySize==-1) { avgKeySize = (avgKeySize*(cmdSetsCurrent-1) + key.length())/cmdSetsCurrent; } else { avgKeySize = key.length(); } if(avgValueSize==-1) { avgValueSize = (avgValueSize*(cmdSetsCurrent-1) + objectSize)/cmdSetsCurrent; } else { avgValueSize = objectSize; } if(avgTtl==-1) { avgTtl = (avgTtl*(cmdSetsCurrent-1) + expInSec)/cmdSetsCurrent; } else { avgTtl = expInSec; } } } catch (Exception ex) { Logger.getLogger(BaseCacheImpl.class.getName()).log(Level.SEVERE, "Error: "+ex, ex); throw new CacheException(ex.toString()); } } public boolean touch(String key, int expInSec) throws CacheException { if(QuickCached.DEBUG) logger.log(Level.FINE, "touch key: {0}", key); cmdTouchs++; DataCarrier dc = (DataCarrier) get_(key); if (dc == null) { touchMisses++; return false; } else { set(key, dc, dc.getSize(), expInSec); touchHits++; return true; } } public void update(String key, Object value, int objectSize) throws CacheException { if(QuickCached.DEBUG) logger.log(Level.FINE, "update key: {0}; objectsize: {1};", new Object[]{key, objectSize}); try { updateToCache(key, value, objectSize); } catch (Exception ex) { Logger.getLogger(BaseCacheImpl.class.getName()).log(Level.SEVERE, "Error: "+ex, ex); throw new CacheException(ex.toString()); } } public void update(String key, Object value, int objectSize, int expInSec) throws CacheException { if(QuickCached.DEBUG) logger.log(Level.FINE, "update key: {0}; objectsize: {1};", new Object[]{key, objectSize}); try { updateToCache(key, value, objectSize, expInSec); } catch (Exception ex) { Logger.getLogger(BaseCacheImpl.class.getName()).log(Level.SEVERE, "Error: "+ex, ex); throw new CacheException(ex.toString()); } } public Object get(String key) throws CacheException { return get(key, true); } public Object get(String key, boolean incrementCount) throws CacheException { if(QuickCached.DEBUG) logger.log(Level.FINE, "get key: {0}", key); if(incrementCount) { cmdGets++; } Object obj = get_(key); if(incrementCount) { if(obj!=null) { getHits++; } else { if(QuickCached.DEBUG) logger.log(Level.FINE, "no value for key: {0}", key); getMisses++; } } return obj; } private Object get_(String key) throws CacheException { Object obj = null; try { obj = getFromCache(key); } catch (Exception ex) { Logger.getLogger(BaseCacheImpl.class.getName()).log(Level.SEVERE, "Error: "+ex, ex); throw new CacheException(ex.toString()); } return obj; } public boolean delete(String key) throws CacheException { if(QuickCached.DEBUG) logger.log(Level.FINE, "delete key: {0};", key); cmdDeletes++; boolean flag = false; try { flag = deleteFromCache(key); } catch (Exception ex) { Logger.getLogger(BaseCacheImpl.class.getName()).log(Level.SEVERE, "Error: "+ex, ex); throw new CacheException(ex.toString()); } if(flag) { deleteHits++; } else { deleteMisses++; } return flag; } public void flush() throws CacheException { if(QuickCached.DEBUG) logger.log(Level.FINE, "flush"); try { flushCache(); cmdFlushs++; } catch (Exception ex) { Logger.getLogger(BaseCacheImpl.class.getName()).log(Level.SEVERE, "Error: "+ex, ex); throw new CacheException(ex.toString()); } } }