📄 procedurecache.java
字号:
//jTDS JDBC Driver for Microsoft SQL Server and Sybase//Copyright (C) 2004 The jTDS Project////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 (at your option) 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 net.sourceforge.jtds.jdbc.cache;import java.util.ArrayList;import java.util.Collection;import java.util.HashMap;import java.util.Iterator;import net.sourceforge.jtds.jdbc.ProcEntry;/** * LRU cache for procedures and statement handles. * * @version $Id: ProcedureCache.java,v 1.1 2005/05/25 09:24:02 alin_sinpalean Exp $ */public class ProcedureCache implements StatementCache { /** * Encapsulates the cached Object and implements the linked list used to * implement the LRU logic. */ private static class CacheEntry { String key; ProcEntry value; CacheEntry next; CacheEntry prior; /** * Constructs a new cache entry encapsulating the supplied key and * value. * * @param key key used to identify the cache entry * @param value object being cached */ CacheEntry(String key, ProcEntry value) { this.key = key; this.value = value; } /** * Unlinks this CacheEntry from the linked list. */ void unlink() { next.prior = prior; prior.next = next; } /** * Links this CacheEntry into the linked list after the node specified. * * @param ce node after which this entry will be linked */ void link(CacheEntry ce) { next = ce.next; prior = ce; next.prior = this; ce.next = this; } } /** The actual cache instance. */ private HashMap cache; /** Maximum cache size or 0 to disable. */ int cacheSize; /** Head node of the linked list. */ CacheEntry head; /** Tail node of the linked list. */ CacheEntry tail; /** List of redundant cache entries. */ ArrayList free; /** * Constructs a new statement cache. * * @param cacheSize maximum cache size or 0 to disable caching */ public ProcedureCache(int cacheSize) { this.cacheSize = cacheSize; if (cacheSize > 0) { cache = new HashMap(Math.min(1000, cacheSize)); } head = new CacheEntry(null, null); tail = new CacheEntry(null, null); head.next = tail; tail.prior = head; free = new ArrayList(); } /** * Retrieves a ProcEntry object from the cache. * <p/> * If the entry exists it is moved to the front of the linked list to keep * it alive as long as possible. * * @param key the key value identifying the required entry * @return the keyed entry as an <code>Object</code> or null if the entry * does not exist */ public synchronized Object get(String key) { if (cache == null) { // cache disabled. return null; } CacheEntry ce = (CacheEntry) cache.get(key); if (ce != null) { // remove entry from linked list ce.unlink(); // Relink at Head ce.link(head); // Increment usage count ce.value.addRef(); return ce.value; } return null; } /** * Inserts a new entry, identified by a key, into the cache. * <p/> * If the cache is full then one or more entries are removed and * transferred to a list for later destruction. * * @param key value used to identify the entry * @param handle proc entry to be inserted into the cache */ public synchronized void put(String key, Object handle) { // Increment usage count ((ProcEntry) handle).addRef(); if (cache == null) { // cache disabled. return; } // Need to scavenge some existing entries CacheEntry ce = tail.prior; while (ce != head && cache.size() >= cacheSize) { if (ce.value.getRefCount() == 0) { // remove entry from linked list ce.unlink(); // Add to free list for reclaiming free.add(ce.value); // Remove from HashMap cache.remove(ce.key); break; } ce = ce.prior; } // // Now add new entry to cache // ce = new CacheEntry(key, (ProcEntry) handle); cache.put(key, ce); ce.link(head); } /** * Removes a redundant entry from the cache. * * @param key value that identifies the cache entry */ public synchronized void remove(String key) { if (cache == null) { // cache disabled. return; } CacheEntry ce = (CacheEntry) cache.get(key); if (ce != null) { // remove entry from linked list ce.unlink(); // Remove from HashMap cache.remove(key); } } /** * Obtains a list of statement handles or procedures that can now be * dropped. * * @param handles a collection of single use statements that will be * returned for dropping if the cache is disabled * @return the collection of redundant statments for dropping */ public synchronized Collection getObsoleteHandles(Collection handles) { if (handles != null) { // Update the usage count for handles belonging to statements // that are being closed. for (Iterator iterator = handles.iterator(); iterator.hasNext();) { ProcEntry handle = (ProcEntry) iterator.next(); handle.release(); } } if (cache != null) { // Ok the cache is enabled if (free.size() > 0) { // There are redundant entries to drop Collection list = free; free = new ArrayList(); return list; } else { // Nothing to do this time return null; } } else { // Cache is disabled so return the callers statement list. // This will result in statements being prepared and unprepared // with each statement creation/close. return handles; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -