001: /*
002: * Copyright (c) 2002-2007 by OpenSymphony
003: * All rights reserved.
004: */
005: package com.opensymphony.oscache.extra;
006:
007: import com.opensymphony.oscache.base.Cache;
008: import com.opensymphony.oscache.base.events.CacheEntryEvent;
009: import com.opensymphony.oscache.base.events.CacheEntryEventListener;
010: import com.opensymphony.oscache.base.events.CacheGroupEvent;
011: import com.opensymphony.oscache.base.events.CacheMapAccessEvent;
012: import com.opensymphony.oscache.base.events.CacheMapAccessEventListener;
013: import com.opensymphony.oscache.base.events.CacheMapAccessEventType;
014: import com.opensymphony.oscache.base.events.CachePatternEvent;
015: import com.opensymphony.oscache.base.events.CachewideEvent;
016: import com.opensymphony.oscache.base.events.ScopeEvent;
017: import com.opensymphony.oscache.base.events.ScopeEventListener;
018: import com.opensymphony.oscache.extra.ScopeEventListenerImpl;
019:
020: /**
021: * A simple implementation of a statistic reporter which uses the
022: * event listeners. It uses the events to count the cache hit and
023: * misses and of course the flushes.
024: * <p>
025: * We are not using any synchronized so that this does not become a bottleneck.
026: * The consequence is that on retrieving values, the operations that are
027: * currently being done won't be counted.
028: */
029: public class StatisticListenerImpl implements
030: CacheMapAccessEventListener, CacheEntryEventListener,
031: ScopeEventListener {
032:
033: /**
034: * Hit counter.
035: */
036: private static int hitCount = 0;
037:
038: /**
039: * Miss counter.
040: */
041: private static int missCount = 0;
042:
043: /**
044: * Stale hit counter.
045: */
046: private static int staleHitCount = 0;
047:
048: /**
049: * Hit counter sum.
050: */
051: private static int hitCountSum = 0;
052:
053: /**
054: * Miss counter sum.
055: */
056: private static int missCountSum = 0;
057:
058: /**
059: * Stale hit counter.
060: */
061: private static int staleHitCountSum = 0;
062:
063: /**
064: * Flush hit counter.
065: */
066: private static int flushCount = 0;
067:
068: /**
069: * Miss counter sum.
070: */
071: private static int entriesAdded = 0;
072:
073: /**
074: * Stale hit counter.
075: */
076: private static int entriesRemoved = 0;
077:
078: /**
079: * Flush hit counter.
080: */
081: private static int entriesUpdated = 0;
082:
083: /**
084: * Constructor, empty for us.
085: */
086: public StatisticListenerImpl() {
087:
088: }
089:
090: /**
091: * This method handles an event each time the cache is accessed.
092: *
093: * @param event
094: * The event triggered when the cache was accessed
095: * @see com.opensymphony.oscache.base.events.CacheMapAccessEventListener#accessed(CacheMapAccessEvent)
096: */
097: public void accessed(CacheMapAccessEvent event) {
098: // Retrieve the event type and update the counters
099: CacheMapAccessEventType type = event.getEventType();
100:
101: // Handles a hit event
102: if (type == CacheMapAccessEventType.HIT) {
103: hitCount++;
104: } else if (type == CacheMapAccessEventType.STALE_HIT) { // Handles a
105: // stale hit
106: // event
107: staleHitCount++;
108: } else if (type == CacheMapAccessEventType.MISS) { // Handles a miss
109: // event
110: missCount++;
111: }
112: }
113:
114: /**
115: * Logs the flush of the cache.
116: *
117: * @param info the string to be logged.
118: */
119: private void flushed(String info) {
120: flushCount++;
121:
122: hitCountSum += hitCount;
123: staleHitCountSum += staleHitCount;
124: missCountSum += missCount;
125:
126: hitCount = 0;
127: staleHitCount = 0;
128: missCount = 0;
129: }
130:
131: /**
132: * Event fired when a specific or all scopes are flushed.
133: *
134: * @param event ScopeEvent
135: * @see com.opensymphony.oscache.base.events.ScopeEventListener#scopeFlushed(ScopeEvent)
136: */
137: public void scopeFlushed(ScopeEvent event) {
138: flushed("scope "
139: + ScopeEventListenerImpl.SCOPE_NAMES[event.getScope()]);
140: }
141:
142: /**
143: * Event fired when an entry is added to the cache.
144: *
145: * @param event CacheEntryEvent
146: * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cacheEntryAdded(CacheEntryEvent)
147: */
148: public void cacheEntryAdded(CacheEntryEvent event) {
149: entriesAdded++;
150: }
151:
152: /**
153: * Event fired when an entry is flushed from the cache.
154: *
155: * @param event CacheEntryEvent
156: * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cacheEntryFlushed(CacheEntryEvent)
157: */
158: public void cacheEntryFlushed(CacheEntryEvent event) {
159: // do nothing, because a group or other flush is coming
160: if (!Cache.NESTED_EVENT.equals(event.getOrigin())) {
161: flushed("entry " + event.getKey() + " / "
162: + event.getOrigin());
163: }
164: }
165:
166: /**
167: * Event fired when an entry is removed from the cache.
168: *
169: * @param event CacheEntryEvent
170: * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cacheEntryRemoved(CacheEntryEvent)
171: */
172: public void cacheEntryRemoved(CacheEntryEvent event) {
173: entriesRemoved++;
174: }
175:
176: /**
177: * Event fired when an entry is updated in the cache.
178: *
179: * @param event CacheEntryEvent
180: * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cacheEntryUpdated(CacheEntryEvent)
181: */
182: public void cacheEntryUpdated(CacheEntryEvent event) {
183: entriesUpdated++;
184: }
185:
186: /**
187: * Event fired when a group is flushed from the cache.
188: *
189: * @param event CacheGroupEvent
190: * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cacheGroupFlushed(CacheGroupEvent)
191: */
192: public void cacheGroupFlushed(CacheGroupEvent event) {
193: flushed("group " + event.getGroup());
194: }
195:
196: /**
197: * Event fired when a key pattern is flushed from the cache.
198: *
199: * @param event CachePatternEvent
200: * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cachePatternFlushed(CachePatternEvent)
201: */
202: public void cachePatternFlushed(CachePatternEvent event) {
203: flushed("pattern " + event.getPattern());
204: }
205:
206: /**
207: * An event that is fired when an entire cache gets flushed.
208: *
209: * @param event CachewideEvent
210: * @see com.opensymphony.oscache.base.events.CacheEntryEventListener#cacheFlushed(CachewideEvent)
211: */
212: public void cacheFlushed(CachewideEvent event) {
213: flushed("wide " + event.getDate());
214: }
215:
216: /**
217: * Return the counters in a string form.
218: *
219: * @return String
220: */
221: public String toString() {
222: return "StatisticListenerImpl: Hit = " + hitCount + " / "
223: + hitCountSum + ", stale hit = " + staleHitCount
224: + " / " + staleHitCountSum + ", miss = " + missCount
225: + " / " + missCountSum + ", flush = " + flushCount
226: + ", entries (added, removed, updates) = "
227: + entriesAdded + ", " + entriesRemoved + ", "
228: + entriesUpdated;
229: }
230:
231: /**
232: * @return Returns the entriesAdded.
233: */
234: public int getEntriesAdded() {
235: return entriesAdded;
236: }
237:
238: /**
239: * @return Returns the entriesRemoved.
240: */
241: public int getEntriesRemoved() {
242: return entriesRemoved;
243: }
244:
245: /**
246: * @return Returns the entriesUpdated.
247: */
248: public int getEntriesUpdated() {
249: return entriesUpdated;
250: }
251:
252: /**
253: * @return Returns the flushCount.
254: */
255: public int getFlushCount() {
256: return flushCount;
257: }
258:
259: /**
260: * @return Returns the hitCount.
261: */
262: public int getHitCount() {
263: return hitCount;
264: }
265:
266: /**
267: * @return Returns the hitCountSum.
268: */
269: public int getHitCountSum() {
270: return hitCountSum;
271: }
272:
273: /**
274: * @return Returns the missCount.
275: */
276: public int getMissCount() {
277: return missCount;
278: }
279:
280: /**
281: * @return Returns the missCountSum.
282: */
283: public int getMissCountSum() {
284: return missCountSum;
285: }
286:
287: /**
288: * @return Returns the staleHitCount.
289: */
290: public int getStaleHitCount() {
291: return staleHitCount;
292: }
293:
294: /**
295: * @return Returns the staleHitCountSum.
296: */
297: public int getStaleHitCountSum() {
298: return staleHitCountSum;
299: }
300: }
|