1 19 package org.netbeans.modules.turbo; 20 21 import java.io.*; 22 import java.util.Date ; 23 import java.util.Set ; 24 import java.util.HashSet ; 25 import java.util.Iterator ; 26 27 35 class Statistics { 36 37 private static final Statistics NOP_INSTANCE = new NOP(); 38 private static final int REMOVED_BATCH_INTERVAL = 1000 *10; 40 private long requests = 0; 41 private long memoryHits = 0; 42 private long diskHits = 0; 43 44 private long threads = 0; 46 private long duplicates = 0; 47 private long maxQueueSize = 0; 48 49 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 56 private Set recentKeys; 57 58 private static volatile int idPool = 1; 60 private final int id; 61 private final Exception origin; 62 63 private PrintWriter out; 64 65 74 public static Statistics createInstance() { 75 if ("none".equalsIgnoreCase(System.getProperty("netbeans.experimental.vcsTurboStatistics", "none"))) { return NOP_INSTANCE; 77 } else { 78 return new Statistics(); 79 } 80 } 81 82 private Statistics() { 83 origin = new RuntimeException (); 84 id = idPool++; 85 } 86 87 90 private static boolean logPerformance() { 91 return System.getProperty("netbeans.experimental.vcsTurboStatistics", "mini").equalsIgnoreCase("performance"); } 93 94 95 public void keyAdded(Object key) { 96 if (key != null) println("EK+ " + key); 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 108 public void keyRemoved(Object key) { 109 if (key != null) println("EK- " + key); gcCounter++; 111 if (recentKeys != null) { 112 recentKeys.remove(key.toString()); 113 } 114 } 115 116 121 public void computeRemoved(Set keys) { 122 if (logPerformance() == false) return; 123 124 if (System.currentTimeMillis() - removedInvocationTime > REMOVED_BATCH_INTERVAL) return; 125 126 removedInvocaionCounter++; 127 Iterator it = keys.iterator(); 128 Set currentKeys = new HashSet (keys.size()); 129 while (it.hasNext()) { 130 String 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 ().toString() + "] reclaimed keys:" ); Iterator itr = recentKeys.iterator(); 142 while (itr.hasNext()) { 143 String next = itr.next().toString(); 144 println("EK- " + next); } 146 println("MSG EOL reclaimed keys" ); } 148 } 149 150 removedInvocationTime = System.currentTimeMillis(); 151 recentKeys = currentKeys; 152 } 153 154 155 public void attributeRequest() { 156 requests++; 157 if (requests % 1000 == 0) { 158 printCacheStatistics(); 159 } 160 } 161 162 163 public void memoryHit() { 164 memoryHits++; 165 } 166 167 168 public void backgroundThread() { 169 threads++; 170 } 171 172 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 184 public void providerHit() { 185 diskHits++; 186 } 187 188 public void shutdown() { 189 printCacheStatistics(); 190 out.flush(); 191 out.close(); 192 } 194 195 private String logPath() { 196 return System.getProperty("java.io.tmpdir") + File.separator + "netbeans-versioning-turbo-" + id + ".log"; } 198 199 private void printCacheStatistics() { 200 println("CS turbo.requests=" + requests); println("CS memory.hits=" + memoryHits + " " + (((float)memoryHits/(float)requests) * 100) + "%"); println("CS provider.hits=" + diskHits + " " + (((float)diskHits/(float)requests) * 100) + "%"); if (removedInvocaionCounter >= 2) { 204 println("CS memory.max=" + maxMemoryEntries); println("CS memory.entries=" + (newCounter - gcCounter)); println("CS memory.entiresReclaimingRatio=" + (((float)gcCounter/(float)newCounter) * 100) + "%"); } 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); println("MSG --"); println("MSG turbo.log.Statistics on " + new Date ().toString()); } 214 215 private synchronized void println(String s) { 216 if (out == null) { 217 String 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"); out.println("MSG CS describes summary statistics of memory and disk caches"); out.println("MSG the MSG prefix denotes free form messages"); out.println("MSG turbo.Statistics instance serving:\n"); StackTraceElement elements[] = origin.getStackTrace(); 228 for (int i = 0; i < elements.length; i++) { 229 StackTraceElement element = elements[i]; 230 out.println("MSG " + element.toString() ); } 232 out.println(); 233 } 234 out.println(s); 235 } 236 237 238 private static final class NOP extends Statistics { 239 public void keyAdded(Object key) { 240 } 241 242 public void computeRemoved(Set 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 |