/*
 * XAPool: Open Source XA JDBC Pool
 * Copyright (C) 2003 Objectweb.org
 * Initial Developer: Lutris Technologies Inc.
 * Contact: xapool-public@lists.debian-sf.objectweb.org
 *
 * This library 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 2.1 of the License, or any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 */
package org.enhydra.jdbc.util;

import java.util.Hashtable;
import java.util.LinkedList;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
import java.util.Enumeration;

Simple implementation of a cache, using Least Recently Used algorithm for discarding members when the cache fills up
/** * Simple implementation of a cache, using Least Recently Used algorithm * for discarding members when the cache fills up */
public class LRUCache {
The cache
/** The cache */
private Hashtable cache = new Hashtable();
The linked list to keep track of least/most recently used
/** The linked list to keep track of least/most recently used */
private LinkedList lru = new LinkedList();
The maximum size of the cache
/** The maximum size of the cache */
private int maxSize; public Logger log;
Constructor
/** * Constructor */
public LRUCache(int maxSize) { this.maxSize = maxSize; } public int LRUSize() { return lru.size(); } public int cacheSize() { return cache.size(); }
Puts a new object in the cache. If the cache is full, it removes the least recently used object. The new object becomes the most recently used object.
/** * Puts a new object in the cache. If the cache is full, it removes * the least recently used object. The new object becomes the most * recently used object. */
public void put(Object key, Object value) { List removed = new ArrayList(); synchronized (this) { // make room if needed while (cache.size() + 1 > maxSize) { removed.add(removeLRU()); } // remove the key from the list if it's in the cache already if (cache.containsKey(key)) { lru.remove(key); } // the last item in the list is the most recently used lru.addLast(key); // put it in the actual cache cache.put(key, value); } cleanupAll(removed); }
Gets an object from the cache. This object is set to be the most recenty used
/** * Gets an object from the cache. This object is set to be the * most recenty used */
public synchronized Object get(Object key) { // check for existence in cache if (!cache.containsKey(key)) { return null; } // set to most recently used lru.remove(key); lru.addLast(key); // return the object return cache.get(key); }
Removes the object from the cache and the lru list
/** * Removes the object from the cache and the lru list */
public synchronized Object remove(Object key) { // check for existence in cache if (!cache.containsKey(key)) { return null; } // remove from lru list lru.remove(key); // remove from cache Object obj = cache.remove(key); return obj; } private synchronized Object removeLRU() { Object obj = cache.remove(lru.getFirst()); lru.removeFirst(); return obj; }
Resize the cache
/** * Resize the cache */
public void resize(int newSize) { if (newSize <= 0) { return; } List removed = new ArrayList(); synchronized (this) { maxSize = newSize; while (cache.size() > maxSize) { removed.add(removeLRU()); } } cleanupAll(removed); } private void cleanupAll(List removed) { Iterator it = removed.iterator(); while (it.hasNext()) { cleanupObject(it.next()); } }
Override this method to do special cleanup on an object, such as closing a statement or a connection
/** * Override this method to do special cleanup on an object, * such as closing a statement or a connection */
protected void cleanupObject(Object o) {} public void cleanupAll() { for (Enumeration enum = cache.keys();enum.hasMoreElements();) { Object o = remove(enum.nextElement()); cleanupObject(o); } } public void setLogger(Logger alog) { log = alog; } }