View Javadoc

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 }