/* * This file or a portion of this file is licensed under the terms of * the Globus Toolkit Public License, found in file ../GTPL, or at * http://www.globus.org/toolkit/download/license.html. This notice must * appear in redistributions of this file, with or without modification. * * Redistributions of this Software, with or without modification, must * reproduce the GTPL in: (1) the Software, or (2) the Documentation or * some other similar material which is provided with the Software (if * any). * * Copyright 1999-2004 University of Chicago and The University of * Southern California. All rights reserved. */ package org.griphyn.vdl.router; import java.util.*; import org.griphyn.vdl.util.Logging; /** * @author Jens-S. Vöckler * @author Yong Zhao * @version $Revision$ */ public class Cache { /** * remember how long to save a cache entry. */ long m_ttl = 0; /** * Interior class to encapsulate cached objects and their additional * management keys. */ public class CacheEntry { /** * This is the cached object. */ Object m_value; /** * This is expiration date of the object. */ long m_expire; /** * Constructs a cache item with its management data. The time to live * is determined from the member variable. * * @param value is the object to be cached. */ CacheEntry( Object value ) { this.m_value = value; this.m_expire = System.currentTimeMillis() + m_ttl; } } /** * remember the objects to cache for. The cache consists of a concise * key to locate any object, a value for the located large object, and * a lifetime for the object. */ java.util.Map m_cache = null; /** * Maintains statistics. */ static long[] m_stats = null; /** * ctor: Initialize the base functionalities of the cache. * @param ttl is the lifetime of a positive entry in seconds. */ public Cache( int ttl ) { this.m_ttl = 1000*ttl; this.m_cache = new java.util.HashMap(); if ( m_stats == null ) { // Singleton: Cache.m_stats = new long[5]; // insert, update, miss, expired, hit Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { Logging.instance().log( "cache", 0, "ins=" + Cache.m_stats[0] + ",updt=" + Cache.m_stats[1] + ",miss=" + Cache.m_stats[2] + ",hit=" + Cache.m_stats[4] ); } }); } } /** * Enters a value into the cache. * @param key is a concise, unique description of the object. * @param value is the object to be cached. * @return <code>null</code> for a fresh object, or the old CacheEntry. */ public Object set( Object key, Object value ) { CacheEntry ce = (CacheEntry) this.m_cache.put( key, new CacheEntry(value) ); this.m_stats[ ce == null ? 0 : 1]++; // count insert or update return ( ce == null ? null : ce.m_value ); } /** * Requests an item from the cache. * @param key is the descriptor of the object. */ public Object get( Object key ) { CacheEntry ce = (CacheEntry) this.m_cache.get(key); // new object? if ( ce == null ) { this.m_stats[2]++; // count MISS return null; } // expired object? if ( ce.m_expire < System.currentTimeMillis() ) { this.m_stats[3]++; // count EXPIRED this.m_cache.remove(key); return null; } // known object! this.m_stats[4]++; return ce.m_value; } /** * Requests a copy of the statistics counters. * @return the counter values. */ public long[] getStatistics() { long[] result = new long[5]; System.arraycopy(this.m_stats,0,result,0,5); return result; } }