/* * Copyright (C) 2010-2015 * fine people e.V. <opensdx@fnppl.org> * Henning Thieß <ht@fnppl.org> * * http://fnppl.org */ /* * Software license * * As far as this file or parts of this file is/are software, rather than documentation, this software-license applies / shall be applied. * * This file is part of openSDX * openSDX is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * openSDX is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * and GNU General Public License along with openSDX. * If not, see <http://www.gnu.org/licenses/>. * */ /* * Documentation license * * As far as this file or parts of this file is/are documentation, rather than software, this documentation-license applies / shall be applied. * * This file is part of openSDX. * Permission is granted to copy, distribute and/or modify this document * under the terms of the GNU Free Documentation License, Version 1.3 * or any later version published by the Free Software Foundation; * with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. * A copy of the license is included in the section entitled "GNU * Free Documentation License" resp. in the file called "FDL.txt". * */ package org.fnppl.opensdx.keyserverfe; import java.util.*; public class OutDatingCache { public boolean noisy = false; public String name ="UNNAMED"; //TODO optimizing :: wahl hibernation-engine //TODO optimizing :: maxfillsize //TODO optimizing :: cleanup-behaviour private Hashtable cachico ;//(Object)key -> Object[]{value,puttime,outdatetime} private long default_alive = 1000*60*60;//1h /** Creates a new instance of OutdatingCache */ public OutDatingCache() { cachico = new Hashtable(); } public OutDatingCache(long defaultAliveTime) { this(); default_alive = defaultAliveTime; } public static int cleancountmax = 1000; public static int cleancount = 0; private void put(Object key, Object value, long aliveTime) { synchronized(cachico) { cleancount++; if(cleancount>=cleancountmax) { cleancount = 0; int r = cleanup(); if(noisy) { System.err.println(name+"::OutdatingCache::cleanup: "+r); System.err.println(name+"::OutdatingCache::cache-size now: "+cachico.size()); } cleancount = 0; } if(noisy) { System.err.println(name+"::OutdatingCache::put: "+key.toString()); } cachico.put(key, new Object[]{value, new Long(System.currentTimeMillis()), new Long(aliveTime)}); } } public void put(OutDatingCache.ComposedKey key, Object value) { put(key.toString(), value, default_alive); } public void put(String key, String value) { put(key, value, default_alive); } public void put(String key, Object value) { put(key, value, default_alive); } public void put(Object key, Object value) { put(key, value, default_alive); } public void remove(Object key) { cachico.remove(key); } public void remove(OutDatingCache.ComposedKey key) { cachico.remove(key.toString()); } public String getS(String key) { return (String)get(key); } public Object get(OutDatingCache.ComposedKey key) { return get(key.toString()); } public boolean contains(Object key) { Object o = get(key); if(o!=null) { return true; } return false; } public Object get(Object key) { Object[] o = null; synchronized(cachico) { o = (Object[])cachico.get(key); } if(o==null) { if(noisy) { System.err.println(name+"::get: "+key.toString()+" NOTHING IN CACHE FOR THAT KEY"); } return null; } else { if(noisy) { System.err.println(name+"::get: "+key.toString()+" -> CACHED"); } } Object value = o[0]; long puttime = ((Long)o[1]).longValue(); long ttl = ((Long)o[2]).longValue(); if(puttime+ttl < System.currentTimeMillis()) { if(noisy) { System.err.println(name+"::get: "+key.toString()+" -> outdated (ttl: "+ttl+" puttime: "+puttime+")"); } cachico.remove(key); return null; } return value; } private int cleanup() { int ret = 0; synchronized(cachico) { Enumeration en = cachico.keys(); long l = System.currentTimeMillis(); while(en.hasMoreElements()) { Object key = en.nextElement(); Object[] o = (Object[])cachico.get(key.toString()); if(o==null) { continue; } Object value = o[0]; long puttime = ((Long)o[1]).longValue(); long ttl = ((Long)o[2]).longValue(); if(puttime+ttl < l) { remove(key); ret++; // System.out.println("OutdatingCache::get: "+key.toString()+" -> outdated (ttl: "+ttl+" puttime: "+puttime+")"); } } } return ret; } public static class ComposedKey extends Vector { public ComposedKey() { super(); } @Override public void addElement(Object o) { if(o==null) { } else { super.addElement(o); } } @Override public String toString() { StringBuffer s = new StringBuffer(); for(int i=0;i<size();i++) { s.append(elementAt(i).toString()); if(i+1<size()) { s.append("::"); } } return s.toString(); } } }