1
2
3
4
5
6
7
8
9
10 package org.mule.util.store;
11
12 import org.mule.config.i18n.CoreMessages;
13 import org.mule.util.monitor.ExpiryMonitor;
14
15 import java.util.Map;
16
17 import edu.emory.mathcs.backport.java.util.concurrent.helpers.Utils;
18 import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentSkipListMap;
19 import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
20
21
22
23
24
25
26
27
28 public class InMemoryObjectStore extends AbstractMonitoredObjectStore
29 {
30 protected ConcurrentSkipListMap store;
31
32 public InMemoryObjectStore()
33 {
34 this.store = new ConcurrentSkipListMap();
35 }
36
37
38
39
40
41
42
43
44
45
46
47
48
49 public boolean containsObject(String id) throws Exception
50 {
51 if (id == null)
52 {
53 throw new IllegalArgumentException(CoreMessages.objectIsNull("id").toString());
54 }
55
56
57 return store.values().contains(new StoredObject(id, null));
58 }
59
60
61
62
63
64
65
66
67
68
69
70
71 public boolean storeObject(String id, Object item) throws Exception
72 {
73 if (id == null)
74 {
75 throw new IllegalArgumentException(CoreMessages.objectIsNull("id").toString());
76 }
77
78
79
80
81
82 StoredObject obj = new StoredObject(id, item);
83 synchronized (store)
84 {
85 if (store.values().contains(obj))
86 {
87 return false;
88 }
89
90 boolean written = false;
91 while (!written)
92 {
93 written = (store.putIfAbsent(new Long(Utils.nanoTime()), obj) == null);
94 }
95
96 return true;
97 }
98 }
99
100
101
102
103
104
105
106
107
108
109
110 public Object retrieveObject(String id) throws Exception
111 {
112 StoredObject obj = (StoredObject)store.get(id);
113 if(obj!=null)
114 {
115 return obj.getItem();
116 }
117 return null;
118 }
119
120 public boolean removeObject(String id) throws Exception
121 {
122 StoredObject obj = (StoredObject)store.get(id);
123 if(obj!=null)
124 {
125 return store.remove(obj) !=null;
126 }
127 return true;
128 }
129
130 public final void expire()
131 {
132
133 int currentSize = store.size();
134
135
136 int excess = (currentSize - maxEntries);
137 if (excess > 0)
138 {
139 while (currentSize > maxEntries)
140 {
141 store.pollFirstEntry();
142 currentSize--;
143 }
144
145 if (logger.isDebugEnabled())
146 {
147 logger.debug("Expired " + excess + " excess entries");
148 }
149 }
150
151
152 if (entryTTL > 0 && currentSize != 0)
153 {
154 final long now = Utils.nanoTime();
155 int expiredEntries = 0;
156 Map.Entry oldestEntry;
157
158 purge:
159 while ((oldestEntry = store.firstEntry()) != null)
160 {
161 Long oldestKey = (Long) oldestEntry.getKey();
162 long oldestKeyValue = oldestKey.longValue();
163
164 if (TimeUnit.NANOSECONDS.toMillis(now - oldestKeyValue) >= entryTTL)
165 {
166 store.remove(oldestKey);
167 expiredEntries++;
168 }
169 else
170 {
171 break purge;
172 }
173 }
174
175 if (logger.isDebugEnabled())
176 {
177 logger.debug("Expired " + expiredEntries + " old entries");
178 }
179 }
180 }
181
182
183
184
185 protected static class StoredObject
186 {
187 private String id;
188 private Object item;
189
190 public StoredObject(String id, Object item)
191 {
192 this.id = id;
193 this.item = item;
194 }
195
196 public String getId()
197 {
198 return id;
199 }
200
201 public Object getItem()
202 {
203 return item;
204 }
205
206 public boolean equals(Object o)
207 {
208 if (this == o)
209 {
210 return true;
211 }
212 if (o == null || getClass() != o.getClass())
213 {
214 return false;
215 }
216
217 StoredObject that = (StoredObject) o;
218
219 if (!id.equals(that.id))
220 {
221 return false;
222 }
223
224 return true;
225 }
226
227 public int hashCode()
228 {
229 return id.hashCode();
230 }
231
232
233 public String toString()
234 {
235 final StringBuffer sb = new StringBuffer();
236 sb.append("StoredObject");
237 sb.append("{id='").append(id).append('\'');
238 sb.append(", item=").append(item);
239 sb.append('}');
240 return sb.toString();
241 }
242 }
243
244
245
246 }