1 /**
2 * This file is part of GoldenGate Project (named also GoldenGate or GG).
3 *
4 * Copyright 2009, Frederic Bregier, and individual contributors by the @author
5 * tags. See the COPYRIGHT.txt in the distribution for a full listing of
6 * individual contributors.
7 *
8 * All GoldenGate Project is free software: you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version.
12 *
13 * GoldenGate is distributed in the hope that it will be useful, but WITHOUT ANY
14 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * GoldenGate . If not, see <http://www.gnu.org/licenses/>.
19 */
20 package goldengate.common.lru;
21
22 import java.util.Collection;
23 import java.util.Iterator;
24
25 /**
26 * Threadsafe synchronized implementation of LruCache based on LinkedHashMap.
27 * Threadsafety is provided by method synchronization.
28 *
29 * This cache implementation should be used with low number of threads.
30 *
31 * @author Frederic Bregier
32 * @author Damian Momot
33 */
34 public class SynchronizedLruCache<K, V> extends AbstractLruCache<K, V> {
35 public static final int DEFAULT_INITIAL_CAPACITY = 16;
36
37 public static final float DEFAULT_LOAD_FACTOR = 0.75f;
38
39 private final CapacityLruLinkedHashMap<K, InterfaceLruCacheEntry<V>> cacheMap;
40
41 /**
42 * Creates new SynchronizedLruCache
43 *
44 * @param capacity
45 * max cache capacity
46 * @param ttl
47 * time to live in milliseconds
48 * @param initialCapacity
49 * initial cache capacity
50 * @param loadFactor
51 */
52 public SynchronizedLruCache(int capacity, long ttl, int initialCapacity,
53 float loadFactor) {
54 super(ttl);
55
56 cacheMap = new CapacityLruLinkedHashMap<K, InterfaceLruCacheEntry<V>>(
57 capacity, initialCapacity, loadFactor);
58 }
59
60 /**
61 * Creates new SynchronizedLruCache with DEFAULT_LOAD_FACTOR
62 *
63 * @param capacity
64 * max cache capacity
65 * @param ttl
66 * time to live in milliseconds
67 * @param initialCapacity
68 * initial cache capacity
69 */
70 public SynchronizedLruCache(int capacity, long ttl, int initialCapacity) {
71 this(capacity, ttl, initialCapacity, DEFAULT_LOAD_FACTOR);
72 }
73
74 /**
75 * Creates new SynchronizedLruCache with DEFAULT_LOAD_FACTOR and
76 * DEFAULT_INITIAL_CAPACITY
77 *
78 * @param capacity
79 * max cache capacity
80 * @param ttl
81 * time to live in milliseconds
82 */
83 public SynchronizedLruCache(int capacity, long ttl) {
84 this(capacity, ttl, DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
85 }
86
87 @Override
88 synchronized public void clear() {
89 cacheMap.clear();
90 }
91
92 @Override
93 synchronized public V get(K key) {
94 return super.get(key);
95 }
96
97 @Override
98 public int getCapacity() {
99 return cacheMap.getCapacity();
100 }
101
102 @Override
103 protected InterfaceLruCacheEntry<V> getEntry(K key) {
104 return cacheMap.get(key);
105 }
106
107 @Override
108 synchronized public int getSize() {
109 return cacheMap.size();
110 }
111
112 synchronized public void put(K key, V value, long ttl) {
113 super.put(key, value, ttl);
114 }
115
116 @Override
117 protected void putEntry(K key, InterfaceLruCacheEntry<V> entry) {
118 cacheMap.put(key, entry);
119 }
120
121 @Override
122 synchronized public void remove(K key) {
123 cacheMap.remove(key);
124 }
125
126 @Override
127 synchronized public void forceClearOldest() {
128 long timeRef = System.currentTimeMillis();
129 Collection<InterfaceLruCacheEntry<V>> collection = cacheMap.values();
130 Iterator<InterfaceLruCacheEntry<V>> iterator = collection.iterator();
131 while (iterator.hasNext()) {
132 InterfaceLruCacheEntry<V> v = iterator.next();
133 if (!v.isStillValid(timeRef)) {
134 iterator.remove();
135 }
136 }
137 }
138
139 }