1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.portals.applications.transform.impl;
18
19 import java.util.Collections;
20 import java.util.Date;
21 import java.util.Iterator;
22 import java.util.LinkedList;
23 import java.util.List;
24 import java.util.Observable;
25 import java.util.TreeMap;
26
27 import org.apache.portals.applications.transform.Transform;
28 import org.apache.portals.applications.transform.TransformCache;
29 import org.apache.portals.applications.transform.TransformCacheEntry;
30
31
32 /***
33 * TransformCacheComponent
34 *
35 * @author <a href="mailto:taylor@apache.org">David Sean Taylor </a>
36 * @version $Id: MemoryTransformCache.java 517719 2007-03-13 15:05:48Z ate $
37 */
38 public class MemoryTransformCache implements TransformCache
39 {
40 private boolean debug = false;
41 private int maxSize = 100;
42 private int evictionPercentage = 10;
43 private boolean enable = true;
44
45 private TreeMap cache = null;
46 private Object lock = new Object();
47
48 /***
49 * Spring constructor injection
50 *
51 */
52 public MemoryTransformCache(Transform transform, int maxSize, int evictionPercentage, boolean enable, boolean debug)
53 {
54 cache = new TreeMap();
55 this.maxSize = maxSize;
56 this.evictionPercentage = evictionPercentage;
57
58 transform.getPublisher().addObserver(this);
59 }
60
61 public int getMaxSize()
62 {
63 return maxSize;
64 }
65
66 public void setMaxSize(int maxSize)
67 {
68 this.maxSize = maxSize;
69 }
70
71 public int getEvictionPercentage()
72 {
73 return this.evictionPercentage;
74 }
75
76 public boolean isEnabled()
77 {
78 return enable;
79 }
80
81 public void put(String key, Object document, long timeToLive)
82 {
83 TransformCacheEntry entry = new TransformCacheEntry(key, document, timeToLive);
84 if (cache.size() > getMaxSize())
85 {
86 evict();
87 }
88 synchronized(lock)
89 {
90 cache.put(key, entry);
91 }
92 if (debug)
93 {
94 System.out.println("Transformed content put in cache! Transform: "
95 + key);
96 }
97 }
98
99 /***
100 * The eviction policy will keep n items in the cache, and then start evicting
101 * x items ordered-by least used first.
102 * n = max size of cache
103 * x = (eviction_percentage/100) * n
104 *
105 */
106 protected void evict()
107 {
108 if (debug)
109 {
110 System.out.println("Calling evict... cacheSize: "+
111 cache.size()+" maxSize: "+getMaxSize());
112 }
113 synchronized (lock)
114 {
115 if (this.getMaxSize() >= cache.size())
116 {
117 return;
118 }
119
120 List list = new LinkedList( cache.values());
121 Collections.sort(list, this);
122
123 int count = 0;
124 int limit = (getMaxSize() * getEvictionPercentage())/100 ;
125 if (limit <= 0) limit = 1;
126
127 for (Iterator it = list.iterator(); it.hasNext(); )
128 {
129 if (count >= limit)
130 {
131 break;
132 }
133
134 TransformCacheEntry entry = (TransformCacheEntry) it.next();
135 if (debug)
136 {
137 System.out.println("Evicting: "+ entry.getKey());
138 }
139 cache.remove(entry.getKey());
140
141 count++;
142 }
143 }
144 }
145
146
147
148
149
150 public Object remove(String key)
151 {
152 TransformCacheEntry entry = (TransformCacheEntry)cache.get(key);
153 if (entry == null)
154 {
155 return null;
156 }
157 synchronized(lock)
158 {
159 entry = (TransformCacheEntry)cache.remove(key);
160 }
161 return entry;
162
163 }
164
165
166
167
168 public TransformCacheEntry get(String key)
169 {
170 TransformCacheEntry entry = (TransformCacheEntry)cache.get(key);
171 if (entry == null)
172 {
173 return null;
174 }
175 long now = new Date().getTime();
176 long lifeTime = entry.getTimeToLive() * 1000;
177 if ((entry.getLastAccessed() + lifeTime) < now)
178 {
179 return null;
180 }
181 if (debug)
182 {
183 System.out.println("Transformed content found in cache! Transform: "
184 + key);
185 }
186 return entry;
187 }
188
189 public Object getDocument(String key)
190 {
191 TransformCacheEntry entry = get(key);
192 if (entry != null)
193 {
194 return entry.getDocument();
195 }
196 return null;
197 }
198
199 public int compare(Object o1, Object o2)
200 {
201 TransformCacheEntry e1 = (TransformCacheEntry)o1;
202 TransformCacheEntry e2 = (TransformCacheEntry)o2;
203 if (e1.getLastAccessed() < e2.getLastAccessed())
204 {
205 return -1;
206 }
207 else if (e1.getLastAccessed() == e2.getLastAccessed())
208 {
209 return 0;
210 }
211 return 1;
212 }
213
214 public String constructKey(String url, String stylesheet)
215 {
216 return url + ":" + stylesheet;
217 }
218
219 public void clearCache()
220 {
221 cache.clear();
222 }
223
224 public void update(Observable o, Object arg)
225 {
226
227 }
228
229 }
230