KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > turbo > Statistics


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.modules.turbo;
20
21 import java.io.*;
22 import java.util.Date JavaDoc;
23 import java.util.Set JavaDoc;
24 import java.util.HashSet JavaDoc;
25 import java.util.Iterator JavaDoc;
26
27 /**
28  * Statistics support for {@link Turbo}.
29  *
30  * <p>Results analysis allows to determine if cache
31  * have any effect.
32  *
33  * @author Petr Kuzel
34  */

35 class Statistics {
36
37     private static final Statistics NOP_INSTANCE = new NOP();
38     private static final int REMOVED_BATCH_INTERVAL = 1000 *10; // 10s
39

40     private long requests = 0;
41     private long memoryHits = 0;
42     private long diskHits = 0;
43
44     // background loading
45
private long threads = 0;
46     private long duplicates = 0;
47     private long maxQueueSize = 0;
48
49     // Memory.liveentitiesMap utilization
50
private long maxMemoryEntries = 0;
51     private long gcCounter = 0;
52     private long newCounter = 0;
53     private int removedInvocaionCounter = 0;
54     private long removedInvocationTime = System.currentTimeMillis() - REMOVED_BATCH_INTERVAL;
55     /** Holds keys string reprentation to avoid memory leaks. */
56     private Set JavaDoc recentKeys;
57
58     // cache instance identification fields
59
private static volatile int idPool = 1;
60     private final int id;
61     private final Exception JavaDoc origin;
62
63     private PrintWriter out;
64
65     /** Creates new statistics instance according to
66      * <tt>netbeans.experimental.vcsTurboStatistics</tt> system
67      * property:
68      * <ul>
69      * <li><tt>none</tt> (default) no-op implementaion
70      * <li><tt>mini</tt> logs fast events
71      * <li><tt>performance</tt> logs also heavy events slowing down Turbo and increasing it's memory requirements.
72      * </ul>
73      */

74     public static Statistics createInstance() {
75         if ("none".equalsIgnoreCase(System.getProperty("netbeans.experimental.vcsTurboStatistics", "none"))) { // NOI18N
76
return NOP_INSTANCE;
77         } else {
78             return new Statistics();
79         }
80     }
81
82     private Statistics() {
83         origin = new RuntimeException JavaDoc();
84         id = idPool++;
85     }
86
87     /**
88      * Checks if additional logging required for detailed performance evaluation is required.
89      */

90     private static boolean logPerformance() {
91         return System.getProperty("netbeans.experimental.vcsTurboStatistics", "mini").equalsIgnoreCase("performance"); // NOI18N
92
}
93
94     /** Key created adding permision to store it in memory layer. */
95     public void keyAdded(Object JavaDoc key) {
96         if (key != null) println("EK+ " + key); // NOi18N
97
newCounter++;
98         long allocated = newCounter - gcCounter;
99         if (allocated > maxMemoryEntries) {
100             maxMemoryEntries = allocated;
101         }
102         if (recentKeys != null) {
103             assert recentKeys.add(key.toString()) : "Key added for the second time: " + key;
104         }
105     }
106
107     /** Key was removed from memory. */
108     public void keyRemoved(Object JavaDoc key) {
109         if (key != null) println("EK- " + key); // NOi18N
110
gcCounter++;
111         if (recentKeys != null) {
112             recentKeys.remove(key.toString());
113         }
114     }
115
116     /**
117      * Detect reclaimed keys. It lods first results on the second call.
118      *
119      * <p>It's heavy event.
120      */

121     public void computeRemoved(Set JavaDoc keys) {
122         if (logPerformance() == false) return;
123
124         if (System.currentTimeMillis() - removedInvocationTime > REMOVED_BATCH_INTERVAL) return;
125
126         removedInvocaionCounter++;
127         Iterator JavaDoc it = keys.iterator();
128         Set JavaDoc currentKeys = new HashSet JavaDoc(keys.size());
129         while (it.hasNext()) {
130             String JavaDoc stringKey = it.next().toString();
131             currentKeys.add(stringKey);
132         }
133
134         if (recentKeys != null) {
135             recentKeys.removeAll(currentKeys);
136             int reclaimed = recentKeys.size();
137             gcCounter += reclaimed;
138
139             if (reclaimed > 0) {
140                 println("MSG [" + new Date JavaDoc().toString() + "] reclaimed keys:" ); // NOI18N
141
Iterator JavaDoc itr = recentKeys.iterator();
142                 while (itr.hasNext()) {
143                     String JavaDoc next = itr.next().toString();
144                     println("EK- " + next); // NOI18N
145
}
146                 println("MSG EOL reclaimed keys" ); // NOI18N
147
}
148         }
149
150         removedInvocationTime = System.currentTimeMillis();
151         recentKeys = currentKeys;
152     }
153
154     /** Turbo request arrived */
155     public void attributeRequest() {
156         requests++;
157         if (requests % 1000 == 0) {
158             printCacheStatistics();
159         }
160     }
161
162     /** The client request was resolved by memory layer */
163     public void memoryHit() {
164         memoryHits++;
165     }
166
167     /** new background thread spawned */
168     public void backgroundThread() {
169         threads++;
170     }
171
172     /** Duplicate request eliminated from queue. */
173     public void duplicate() {
174         duplicates++;
175     }
176
177     public void queueSize(int size) {
178         if (size > maxQueueSize) {
179             maxQueueSize = size;
180         }
181     }
182
183     /** The client request was resolved at providers layer */
184     public void providerHit() {
185         diskHits++;
186     }
187
188     public void shutdown() {
189         printCacheStatistics();
190         out.flush();
191         out.close();
192 // System.out.println(" Statistics goes to " + Statistics.logPath()); // NOI18N
193
}
194
195     private String JavaDoc logPath() {
196         return System.getProperty("java.io.tmpdir") + File.separator + "netbeans-versioning-turbo-" + id + ".log"; // NOI18N
197
}
198     
199     private void printCacheStatistics() {
200         println("CS turbo.requests=" + requests); // NOI18N
201
println("CS memory.hits=" + memoryHits + " " + (((float)memoryHits/(float)requests) * 100) + "%"); // NOI18N
202
println("CS provider.hits=" + diskHits + " " + (((float)diskHits/(float)requests) * 100) + "%"); // NOI18N
203
if (removedInvocaionCounter >= 2) {
204             println("CS memory.max=" + maxMemoryEntries); // NOI18N
205
println("CS memory.entries=" + (newCounter - gcCounter)); // NOI18N
206
println("CS memory.entiresReclaimingRatio=" + (((float)gcCounter/(float)newCounter) * 100) + "%"); // NOI18N
207
} else {
208             println("MSG No memory utilization data known, use -J-Dnetbeans.experimental.vcsTurboStatistics=performance.");
209         }
210         println("CS queue.threads=" + threads + " queue.duplicates=" + duplicates + " queue.maxSize=" + maxQueueSize); // NOI18N
211
println("MSG --"); // NOI18N
212
println("MSG turbo.log.Statistics on " + new Date JavaDoc().toString()); // NOI18N
213
}
214
215     private synchronized void println(String JavaDoc s) {
216         if (out == null) {
217             String JavaDoc filePath = logPath();
218             try {
219                 out = new PrintWriter(new BufferedWriter(new FileWriter(filePath), 512));
220             } catch (IOException e) {
221                 out = new PrintWriter(new OutputStreamWriter(System.out), true);
222             }
223             out.println("MSG EK followed by +/- denotes new memory cache entry/releasing it"); // NOI18N
224
out.println("MSG CS describes summary statistics of memory and disk caches"); // NOI18N
225
out.println("MSG the MSG prefix denotes free form messages"); // NOI18N
226
out.println("MSG turbo.Statistics instance serving:\n"); // NOI18N
227
StackTraceElement JavaDoc elements[] = origin.getStackTrace();
228             for (int i = 0; i < elements.length; i++) {
229                 StackTraceElement JavaDoc element = elements[i];
230                 out.println("MSG " + element.toString() ); // NOI18N
231
}
232             out.println();
233         }
234         out.println(s);
235     }
236
237     /** Logs nothing. */
238     private static final class NOP extends Statistics {
239         public void keyAdded(Object JavaDoc key) {
240         }
241
242         public void computeRemoved(Set JavaDoc keys) {
243         }
244
245         public void attributeRequest() {
246         }
247
248         public void memoryHit() {
249         }
250
251         public void backgroundThread() {
252         }
253
254         public void duplicate() {
255         }
256
257         public void queueSize(int size) {
258         }
259
260         public void providerHit() {
261         }
262
263         public void shutdown() {
264         }
265
266     }
267 }
268
Popular Tags