+++ /dev/null
-/*******************************************************************************\r
- * ============LICENSE_START====================================================\r
- * * org.onap.aaf\r
- * * ===========================================================================\r
- * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.\r
- * * ===========================================================================\r
- * * Licensed under the Apache License, Version 2.0 (the "License");\r
- * * you may not use this file except in compliance with the License.\r
- * * You may obtain a copy of the License at\r
- * * \r
- * * http://www.apache.org/licenses/LICENSE-2.0\r
- * * \r
- * * Unless required by applicable law or agreed to in writing, software\r
- * * distributed under the License is distributed on an "AS IS" BASIS,\r
- * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * * See the License for the specific language governing permissions and\r
- * * limitations under the License.\r
- * * ============LICENSE_END====================================================\r
- * *\r
- * * ECOMP is a trademark and service mark of AT&T Intellectual Property.\r
- * *\r
- ******************************************************************************/\r
-package com.att.cache;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Date;\r
-import java.util.HashMap;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Set;\r
-import java.util.Timer;\r
-import java.util.TimerTask;\r
-import java.util.concurrent.ConcurrentHashMap;\r
-import java.util.logging.Level;\r
-\r
-import com.att.inno.env.Env;\r
-import com.att.inno.env.Trans;\r
-\r
-/**\r
- * Create and maintain a Map of Maps used for Caching\r
- * \r
- *\r
- * @param <TRANS>\r
- * @param <DATA>\r
- */\r
-public class Cache<TRANS extends Trans, DATA> {\r
- private static Clean clean;\r
- private static Timer cleanseTimer;\r
-\r
- public static final String CACHE_HIGH_COUNT = "CACHE_HIGH_COUNT";\r
- public static final String CACHE_CLEAN_INTERVAL = "CACHE_CLEAN_INTERVAL";\r
-// public static final String CACHE_MIN_REFRESH_INTERVAL = "CACHE_MIN_REFRESH_INTERVAL";\r
-\r
- private static final Map<String,Map<String,Dated>> cacheMap;\r
-\r
- static {\r
- cacheMap = new HashMap<String,Map<String,Dated>>();\r
- }\r
-\r
- /**\r
- * Dated Class - store any Data with timestamp\r
- * \r
- *\r
- */\r
- public final static class Dated { \r
- public Date timestamp;\r
- public List<?> data;\r
- \r
- public Dated(List<?> data) {\r
- timestamp = new Date();\r
- this.data = data;\r
- }\r
-\r
- public <T> Dated(T t) {\r
- timestamp = new Date();\r
- ArrayList<T> al = new ArrayList<T>(1);\r
- al.add(t);\r
- data = al;\r
- }\r
-\r
- public void touch() {\r
- timestamp = new Date();\r
- }\r
- }\r
- \r
- public static Map<String,Dated> obtain(String key) {\r
- Map<String, Dated> m = cacheMap.get(key);\r
- if(m==null) {\r
- m = new ConcurrentHashMap<String, Dated>();\r
- synchronized(cacheMap) {\r
- cacheMap.put(key, m);\r
- }\r
- }\r
- return m;\r
- }\r
-\r
- /**\r
- * Clean will examine resources, and remove those that have expired.\r
- * \r
- * If "highs" have been exceeded, then we'll expire 10% more the next time. This will adjust after each run\r
- * without checking contents more than once, making a good average "high" in the minimum speed.\r
- * \r
- *\r
- */\r
- private final static class Clean extends TimerTask {\r
- private final Env env;\r
- private Set<String> set;\r
- \r
- // The idea here is to not be too restrictive on a high, but to Expire more items by \r
- // shortening the time to expire. This is done by judiciously incrementing "advance"\r
- // when the "highs" are exceeded. This effectively reduces numbers of cached items quickly.\r
- private final int high;\r
- private long advance;\r
- private final long timeInterval;\r
- \r
- public Clean(Env env, long cleanInterval, int highCount) {\r
- this.env = env;\r
- high = highCount;\r
- timeInterval = cleanInterval;\r
- advance = 0;\r
- set = new HashSet<String>();\r
- }\r
- \r
- public synchronized void add(String key) {\r
- set.add(key);\r
- }\r
-\r
- public void run() {\r
- int count = 0;\r
- int total = 0;\r
- // look at now. If we need to expire more by increasing "now" by "advance"\r
- Date now = new Date(System.currentTimeMillis() + advance);\r
- \r
- \r
- for(String name : set) {\r
- Map<String,Dated> map = cacheMap.get(name);\r
- if(map!=null) for(Map.Entry<String,Dated> me : map.entrySet()) {\r
- ++total;\r
- if(me.getValue().timestamp.before(now)) {\r
- map.remove(me.getKey());\r
- ++count;\r
- }\r
- }\r
-// if(count>0) {\r
-// env.info().log(Level.INFO, "Cache removed",count,"expired",name,"Elements");\r
-// }\r
- }\r
- \r
- if(count>0) {\r
- env.info().log(Level.INFO, "Cache removed",count,"expired Cached Elements out of", total);\r
- }\r
-\r
- // If High (total) is reached during this period, increase the number of expired services removed for next time.\r
- // There's no point doing it again here, as there should have been cleaned items.\r
- if(total>high) {\r
- // advance cleanup by 10%, without getting greater than timeInterval.\r
- advance = Math.min(timeInterval, advance+(timeInterval/10));\r
- } else {\r
- // reduce advance by 10%, without getting lower than 0.\r
- advance = Math.max(0, advance-(timeInterval/10));\r
- }\r
- }\r
- }\r
-\r
- public static synchronized void startCleansing(Env env, String ... keys) {\r
- if(cleanseTimer==null) {\r
- cleanseTimer = new Timer("Cache Cleanup Timer");\r
- int cleanInterval = Integer.parseInt(env.getProperty(CACHE_CLEAN_INTERVAL,"60000")); // 1 minute clean cycles \r
- int highCount = Integer.parseInt(env.getProperty(CACHE_HIGH_COUNT,"5000"));\r
- cleanseTimer.schedule(clean = new Clean(env, cleanInterval, highCount), cleanInterval, cleanInterval);\r
- }\r
- \r
- for(String key : keys) {\r
- clean.add(key);\r
- }\r
- }\r
-\r
- public static void stopTimer() {\r
- if(cleanseTimer!=null) {\r
- cleanseTimer.cancel();\r
- cleanseTimer = null;\r
- }\r
- }\r
-\r
- public static void addShutdownHook() {\r
- Runtime.getRuntime().addShutdownHook(new Thread() {\r
- @Override\r
- public void run() {\r
- Cache.stopTimer();\r
- }\r
- }); \r
- }\r
-\r
-}\r