001: /* ThreadLocalCache.java
002:
003: {{IS_NOTE
004: Purpose:
005:
006: Description:
007:
008: History:
009: Thu Sep 6 16:33:52 2007, Created by tomyeh
010: }}IS_NOTE
011:
012: Copyright (C) 2007 Potix Corporation. All Rights Reserved.
013:
014: {{IS_RIGHT
015: This program is distributed under GPL Version 2.0 in the hope that
016: it will be useful, but WITHOUT ANY WARRANTY.
017: }}IS_RIGHT
018: */
019: package org.zkoss.util;
020:
021: import java.util.Map;
022:
023: /**
024: * A cache that resides on the thread local memory.
025: * The performance is excellent since no need to synchronize the access.
026: * However, it takes more memory since each thread has its own map.
027: *
028: * @author tomyeh
029: * @since 3.0.0
030: */
031: public class ThreadLocalCache implements Cache {
032: private final ThreadLocal _cache = new ThreadLocal();
033: private int _maxsize, _lifetime;
034:
035: /** Constucts a thread-local cache with the specified max size
036: * and the lifetime.
037: */
038: public ThreadLocalCache(int maxSize, int lifetime) {
039: _maxsize = maxSize;
040: _lifetime = lifetime;
041: }
042:
043: /** Constructs a thread-local cache with the default setting:
044: * max size=128 and lifetime=30minutes.
045: */
046: public ThreadLocalCache() {
047: _lifetime = DEFAULT_LIFETIME;
048: _maxsize = 128;
049: }
050:
051: //extra//
052: /** Returns whether the cache for the current thread is empty.
053: */
054: public boolean isEmpty() {
055: return getCache().isEmpty();
056: }
057:
058: /** Puts all object cached in the current thread to the specifed map.
059: */
060: public void copyTo(Map map) {
061: map.putAll(getCache());
062: }
063:
064: //Cache//
065: public boolean containsKey(Object key) {
066: return getCache().containsKey(key);
067: }
068:
069: public Object get(Object key) {
070: return getCache().get(key);
071: }
072:
073: public Object put(Object key, Object value) {
074: return getCache().put(key, value);
075: }
076:
077: public Object remove(Object key) {
078: return getCache().remove(key);
079: }
080:
081: public void clear() {
082: getCache().clear();
083: }
084:
085: private CacheMap getCache() {
086: CacheMap cache = (CacheMap) _cache.get();
087: if (cache == null)
088: _cache.set(cache = new CacheMap(_maxsize, _lifetime));
089: return cache;
090: }
091:
092: public int getLifetime() {
093: return _lifetime;
094: }
095:
096: public void setLifetime(int lifetime) {
097: final Cache cache = (Cache) _cache.get();
098: if (cache != null)
099: cache.setLifetime(lifetime);
100: _lifetime = lifetime;
101: }
102:
103: /**
104: * Returns the maximal allowed size.
105: *
106: * <p>Defalut: 128 (it is smaller than most cache since this cache
107: * one per thread).
108: *
109: * An mapping won't be removed by GC unless the minimal lifetime
110: * or the maximal allowed size exceeds.
111: * @see #getLifetime
112: */
113: public int getMaxSize() {
114: return _maxsize;
115: }
116:
117: public void setMaxSize(int maxsize) {
118: final Cache cache = (Cache) _cache.get();
119: if (cache != null)
120: cache.setMaxSize(maxsize);
121: _maxsize = maxsize;
122: }
123: }
|