All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.netbeans.modules.turbo.Statistics Maven / Gradle / Ivy

There is a newer version: RELEASE240
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.netbeans.modules.turbo;

import java.io.*;
import java.util.Date;
import java.util.Set;
import java.util.HashSet;
import java.util.Iterator;

/**
 * Statistics support for {@link Turbo}.
 *
 * 

Results analysis allows to determine if cache * have any effect. * * @author Petr Kuzel */ class Statistics { private static final Statistics NOP_INSTANCE = new NOP(); private static final int REMOVED_BATCH_INTERVAL = 1000 *10; // 10s private long requests = 0; private long memoryHits = 0; private long diskHits = 0; // background loading private long threads = 0; private long duplicates = 0; private long maxQueueSize = 0; // Memory.liveentitiesMap utilization private long maxMemoryEntries = 0; private long gcCounter = 0; private long newCounter = 0; private int removedInvocaionCounter = 0; private long removedInvocationTime = System.currentTimeMillis() - REMOVED_BATCH_INTERVAL; /** Holds keys string reprentation to avoid memory leaks. */ private Set recentKeys; // cache instance identification fields private static volatile int idPool = 1; private final int id; private final Exception origin; private PrintWriter out; /** Creates new statistics instance according to * netbeans.experimental.vcsTurboStatistics system * property: *

    *
  • none (default) no-op implementaion *
  • mini logs fast events *
  • performance logs also heavy events slowing down Turbo and increasing it's memory requirements. *
*/ public static Statistics createInstance() { if ("none".equalsIgnoreCase(System.getProperty("netbeans.experimental.vcsTurboStatistics", "none"))) { // NOI18N return NOP_INSTANCE; } else { return new Statistics(); } } private Statistics() { origin = new RuntimeException(); id = idPool++; } /** * Checks if additional logging required for detailed performance evaluation is required. */ private static boolean logPerformance() { return System.getProperty("netbeans.experimental.vcsTurboStatistics", "mini").equalsIgnoreCase("performance"); // NOI18N } /** Key created adding permision to store it in memory layer. */ public void keyAdded(Object key) { if (key != null) println("EK+ " + key); // NOi18N newCounter++; long allocated = newCounter - gcCounter; if (allocated > maxMemoryEntries) { maxMemoryEntries = allocated; } if (recentKeys != null) { assert recentKeys.add(key.toString()) : "Key added for the second time: " + key; } } /** Key was removed from memory. */ public void keyRemoved(Object key) { if (key != null) println("EK- " + key); // NOi18N gcCounter++; if (recentKeys != null) { recentKeys.remove(key.toString()); } } /** * Detect reclaimed keys. It lods first results on the second call. * *

It's heavy event. */ public void computeRemoved(Set keys) { if (logPerformance() == false) return; if (System.currentTimeMillis() - removedInvocationTime > REMOVED_BATCH_INTERVAL) return; removedInvocaionCounter++; Iterator it = keys.iterator(); Set currentKeys = new HashSet(keys.size()); while (it.hasNext()) { String stringKey = it.next().toString(); currentKeys.add(stringKey); } if (recentKeys != null) { recentKeys.removeAll(currentKeys); int reclaimed = recentKeys.size(); gcCounter += reclaimed; if (reclaimed > 0) { println("MSG [" + new Date().toString() + "] reclaimed keys:" ); // NOI18N Iterator itr = recentKeys.iterator(); while (itr.hasNext()) { String next = itr.next().toString(); println("EK- " + next); // NOI18N } println("MSG EOL reclaimed keys" ); // NOI18N } } removedInvocationTime = System.currentTimeMillis(); recentKeys = currentKeys; } /** Turbo request arrived */ public void attributeRequest() { requests++; if (requests % 1000 == 0) { printCacheStatistics(); } } /** The client request was resolved by memory layer */ public void memoryHit() { memoryHits++; } /** new background thread spawned */ public void backgroundThread() { threads++; } /** Duplicate request eliminated from queue. */ public void duplicate() { duplicates++; } public void queueSize(int size) { if (size > maxQueueSize) { maxQueueSize = size; } } /** The client request was resolved at providers layer */ public void providerHit() { diskHits++; } public void shutdown() { printCacheStatistics(); out.flush(); out.close(); // System.out.println(" Statistics goes to " + Statistics.logPath()); // NOI18N } private String logPath() { return System.getProperty("java.io.tmpdir") + File.separator + "netbeans-versioning-turbo-" + id + ".log"; // NOI18N } private void printCacheStatistics() { println("CS turbo.requests=" + requests); // NOI18N println("CS memory.hits=" + memoryHits + " " + (((float)memoryHits/(float)requests) * 100) + "%"); // NOI18N println("CS provider.hits=" + diskHits + " " + (((float)diskHits/(float)requests) * 100) + "%"); // NOI18N if (removedInvocaionCounter >= 2) { println("CS memory.max=" + maxMemoryEntries); // NOI18N println("CS memory.entries=" + (newCounter - gcCounter)); // NOI18N println("CS memory.entiresReclaimingRatio=" + (((float)gcCounter/(float)newCounter) * 100) + "%"); // NOI18N } else { println("MSG No memory utilization data known, use -J-Dnetbeans.experimental.vcsTurboStatistics=performance."); } println("CS queue.threads=" + threads + " queue.duplicates=" + duplicates + " queue.maxSize=" + maxQueueSize); // NOI18N println("MSG --"); // NOI18N println("MSG turbo.log.Statistics on " + new Date().toString()); // NOI18N } private synchronized void println(String s) { if (out == null) { String filePath = logPath(); try { out = new PrintWriter(new BufferedWriter(new FileWriter(filePath), 512)); } catch (IOException e) { out = new PrintWriter(new OutputStreamWriter(System.out), true); } out.println("MSG EK followed by +/- denotes new memory cache entry/releasing it"); // NOI18N out.println("MSG CS describes summary statistics of memory and disk caches"); // NOI18N out.println("MSG the MSG prefix denotes free form messages"); // NOI18N out.println("MSG turbo.Statistics instance serving:\n"); // NOI18N StackTraceElement elements[] = origin.getStackTrace(); for (int i = 0; i < elements.length; i++) { StackTraceElement element = elements[i]; out.println("MSG " + element.toString() ); // NOI18N } out.println(); } out.println(s); } /** Logs nothing. */ private static final class NOP extends Statistics { public void keyAdded(Object key) { } public void computeRemoved(Set keys) { } public void attributeRequest() { } public void memoryHit() { } public void backgroundThread() { } public void duplicate() { } public void queueSize(int size) { } public void providerHit() { } public void shutdown() { } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy