001/* 002 * Stallion Core: A Modern Web Framework 003 * 004 * Copyright (C) 2015 - 2016 Stallion Software LLC. 005 * 006 * This program is free software: you can redistribute it and/or modify it under the terms of the 007 * GNU General Public License as published by the Free Software Foundation, either version 2 of 008 * the License, or (at your option) any later version. This program is distributed in the hope that 009 * it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 011 * License for more details. You should have received a copy of the GNU General Public License 012 * along with this program. If not, see <http://www.gnu.org/licenses/gpl-2.0.html>. 013 * 014 * 015 * 016 */ 017 018package io.stallion.dataAccess.filtering; 019 020import io.stallion.settings.Settings; 021import net.sf.ehcache.Cache; 022import net.sf.ehcache.CacheManager; 023import net.sf.ehcache.Element; 024import net.sf.ehcache.config.CacheConfiguration; 025import net.sf.ehcache.config.Configuration; 026import net.sf.ehcache.config.PersistenceConfiguration; 027import net.sf.ehcache.config.SizeOfPolicyConfiguration; 028 029import java.util.Timer; 030import java.util.TimerTask; 031 032/** 033 * A cache used by filters to cache the results of filtering queries, 034 * default TTL is 25 seconds, the cache is expired every time there is 035 * any sort of update to an item in the bucket. 036 * 037 */ 038public class FilterCache { 039 040 private static CacheManager manager; 041 private static TimerTask evictThread; 042 private static Timer evictThreadTimer; 043 044 045 public static void start() { 046 if (manager == null) { 047 load(); 048 } 049 050 // Every 5 minutes, evict all expired elements from the cache so they do not build up over time 051 evictThread = new TimerTask() { 052 public void run() { 053 Thread.currentThread().setName("stallion-ehcache-evict-task"); 054 if (manager == null) { 055 return; 056 } 057 for(String name: manager.getCacheNames()) { 058 manager.getCache(name).evictExpiredElements(); 059 } 060 } 061 }; 062 063 evictThreadTimer = new Timer("stallion-ehcache-evict-timer"); 064 evictThreadTimer.scheduleAtFixedRate(evictThread, 0, 5 * 60 * 1000); 065 } 066 067 public static void shutdown() { 068 if (evictThreadTimer != null) { 069 evictThreadTimer.cancel(); 070 evictThreadTimer = null; 071 } 072 if (evictThread != null) { 073 evictThread.cancel(); 074 evictThread = null; 075 } 076 if (manager != null) { 077 manager.shutdown(); 078 manager = null; 079 } 080 } 081 082 083 public static void load() { 084 085 Configuration config = new Configuration(); 086 config.setName("stallionFilterCache"); 087 CacheManager.create(config); 088 manager = CacheManager.create(); 089 } 090 091 public static void initCache(String bucket) { 092 if (manager == null) { 093 load(); 094 } 095 if (manager.getCache(bucket) != null) { 096 return; 097 } 098 // We have to do this way because there is no way to programmmatically configured the 099 // sizeOfEngine 100 System.setProperty("net.sf.ehcache.sizeofengine.stallionFilterCache." + bucket, "io.stallion.dataAccess.filtering.EstimatedSizeOfEngine"); 101 102 CacheConfiguration config = new CacheConfiguration(); 103 config.setName(bucket); 104 // Max cache size is very approximately, 50MB 105 106 config.setMaxBytesLocalHeap(Settings.instance().getFilterCacheSize()); 107 //config.setDiskPersistent(false); 108 //config.setMaxElementsOnDisk(0); 109 //config.setMaxBytesLocalDisk(0L); 110 config.setOverflowToOffHeap(false); 111 PersistenceConfiguration persistenceConfiguration = new PersistenceConfiguration(); 112 persistenceConfiguration.strategy(PersistenceConfiguration.Strategy.NONE); 113 114 config.persistence(persistenceConfiguration); 115 //SizeOfPolicyConfiguration sizeOfPolicyConfiguration = new SizeOfPolicyConfiguration(); 116 //sizeOfPolicyConfiguration. 117 //config.addSizeOfPolicy(); 118 //config.set 119 Cache cache = new Cache(config); 120 121 manager.addCache(cache); 122 123 //Cache cache = manager.getCache(bucket); 124 //CacheConfiguration config = cache.getCacheConfiguration(); 125 126 127 //config.setMaxBytesLocalHeap(150000000L); 128 } 129 130 131 public static Object get(String bucket, String key) { 132 if (manager == null) { 133 return null; 134 } 135 Cache cache = manager.getCache(bucket); 136 if (cache == null) { 137 return null; 138 } 139 Element element = cache.get(key); 140 if (element != null) { 141 return element.getObjectValue(); 142 } 143 return null; 144 145 } 146 147 public static void set(String bucket, String key, Object value) { 148 if (manager == null) { 149 load(); 150 } 151 if (!manager.cacheExists(bucket)) { 152 initCache(bucket); 153 } 154 Element element = new Element(key, value); 155 element.setTimeToLive(60); 156 manager.getCache(bucket).put(element); 157 } 158 159 public static void clearBucket(String bucket) { 160 if (manager.cacheExists(bucket) && manager.getCache(bucket).getSize() > 0) { 161 manager.getCache(bucket).removeAll(); 162 } 163 } 164 165}