001 package railo.runtime.cache.ram; 002 003 import java.io.IOException; 004 import java.util.ArrayList; 005 import java.util.HashMap; 006 import java.util.Iterator; 007 import java.util.List; 008 import java.util.Map; 009 import java.util.Map.Entry; 010 011 import railo.commons.io.SystemUtil; 012 import railo.commons.io.cache.Cache; 013 import railo.commons.io.cache.CacheEntry; 014 import railo.runtime.cache.CacheSupport; 015 import railo.runtime.config.Config; 016 import railo.runtime.op.Caster; 017 import railo.runtime.op.Constants; 018 import railo.runtime.type.Struct; 019 020 public class RamCache extends CacheSupport { 021 022 private static final int DEFAULT_CONTROL_INTERVALL = 60; 023 private Map<String, RamCacheEntry> entries= new HashMap<String, RamCacheEntry>(); 024 private long missCount; 025 private int hitCount; 026 027 private long idleTime; 028 private long until; 029 private int controlIntervall=DEFAULT_CONTROL_INTERVALL*1000; 030 031 032 public static void init(Config config,String[] cacheNames,Struct[] arguments) {//print.ds(); 033 034 } 035 036 037 public void init(Cache cache,String cacheName, Struct arguments) throws IOException { 038 init(cacheName, arguments); 039 } 040 041 public void init(String cacheName, Struct arguments) throws IOException { 042 until=Caster.toLongValue(arguments.get("timeToLiveSeconds",Constants.LONG_ZERO),Constants.LONG_ZERO)*1000; 043 idleTime=Caster.toLongValue(arguments.get("timeToIdleSeconds",Constants.LONG_ZERO),Constants.LONG_ZERO)*1000; 044 controlIntervall=Caster.toIntValue(arguments.get("controlIntervall",null),DEFAULT_CONTROL_INTERVALL)*1000; 045 new Controler(this).start(); 046 } 047 048 /** 049 * @see railo.commons.io.cache.Cache#contains(java.lang.String) 050 */ 051 public boolean contains(String key) { 052 return getQuiet(key,null)!=null; 053 } 054 055 056 057 058 public CacheEntry getQuiet(String key, CacheEntry defaultValue) { 059 RamCacheEntry entry = entries.get(key); 060 if(entry==null) { 061 return defaultValue; 062 } 063 if(!valid(entry)) { 064 entries.remove(key); 065 return defaultValue; 066 } 067 return entry; 068 } 069 070 /** 071 * @see railo.commons.io.cache.Cache#getCacheEntry(java.lang.String, railo.commons.io.cache.CacheEntry) 072 */ 073 public CacheEntry getCacheEntry(String key, CacheEntry defaultValue) { 074 RamCacheEntry ce = (RamCacheEntry) getQuiet(key, null); 075 if(ce!=null) { 076 hitCount++; 077 return ce.read(); 078 } 079 missCount++; 080 return defaultValue; 081 } 082 083 /** 084 * @see railo.commons.io.cache.Cache#hitCount() 085 */ 086 public long hitCount() { 087 return hitCount; 088 } 089 090 /** 091 * @see railo.commons.io.cache.Cache#missCount() 092 */ 093 public long missCount() { 094 return missCount; 095 } 096 097 public List keys() { 098 List<String> list=new ArrayList<String>(); 099 100 Iterator<Entry<String, RamCacheEntry>> it = entries.entrySet().iterator(); 101 RamCacheEntry entry; 102 while(it.hasNext()){ 103 entry=it.next().getValue(); 104 if(valid(entry))list.add(entry.getKey()); 105 } 106 return list; 107 } 108 109 public void put(String key, Object value, Long idleTime, Long until) { 110 111 RamCacheEntry entry= entries.get(key); 112 if(entry==null){ 113 entries.put(key, new RamCacheEntry(key,value, 114 idleTime==null?this.idleTime:idleTime.longValue(), 115 until==null?this.until:until.longValue())); 116 } 117 else 118 entry.update(value); 119 } 120 121 public boolean remove(String key) { 122 RamCacheEntry entry = entries.remove(key); 123 if(entry==null) { 124 return false; 125 } 126 return valid(entry); 127 128 } 129 130 public static class Controler extends Thread { 131 132 private RamCache ramCache; 133 134 public Controler(RamCache ramCache) { 135 this.ramCache=ramCache; 136 } 137 138 public void run(){ 139 while(true){ 140 try{ 141 _run(); 142 } 143 catch(Throwable t){ 144 t.printStackTrace(); 145 } 146 SystemUtil.sleep(ramCache.controlIntervall); 147 } 148 } 149 150 private void _run() { 151 RamCacheEntry[] values = ramCache.entries.values().toArray(new RamCacheEntry[ramCache.entries.size()]); 152 for(int i=0;i<values.length;i++){ 153 if(!CacheSupport.valid(values[i])){ 154 ramCache.entries.remove(values[i].getKey()); 155 } 156 } 157 } 158 } 159 160 }