package onlinefrontlines.profiler; /** * A sampler can be used to time a specific bit of code by using: * * <pre> * Sampler sampler = Profiler.getInstance().getSampler("Category", "Sub Category"); * try * { * ... * } * finally * { * sampler.stop(); * } * </pre> * * @author jorrit * * Copyright (C) 2009-2013 Jorrit Rouwe * * This file is part of Online Frontlines. * * Online Frontlines is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Online Frontlines is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Online Frontlines. If not, see <http://www.gnu.org/licenses/>. */ public final class Sampler { /** * Profiler that created us */ private Profiler profiler; /** * Category that we were created with */ private String category; /** * Sub category we were created with */ private String subCategory; /** * Accumulator for category / sub category */ private TimeAccumulatorWithChildren accumulator; /** * Start time in nanoseconds */ private long startTime; /** * Current sampler for this thread */ private static ThreadLocal<Sampler> currentSampler = new ThreadLocal<Sampler>(); /** * Parent sampler */ private Sampler parentSampler; /** * Constructor, used by Profiler * * @param profiler * @param category * @param subCategory */ public Sampler(Profiler profiler, String category, String subCategory) { this.profiler = profiler; this.category = category; this.subCategory = subCategory; accumulator = profiler.getTimeAccumulator(category, subCategory); } /** * Start sampling, used by Profiler */ public void start() { startTime = System.nanoTime(); // Replace current sampler assert(currentSampler.get() != this); this.parentSampler = currentSampler.get(); currentSampler.set(this); } /** * Stop sampling and accumulate the stats */ public void stop() { double time = 1e-6 * (System.nanoTime() - startTime); // Accumulate child time for my parent if (parentSampler != null && parentSampler.accumulator != null) parentSampler.accumulator.accumulateChild(subCategory, time); // Accumulate time if (accumulator != null) accumulator.accumulate(time); // Accumulate time profiler.accumulateTime(category, time); // Restore current sampler assert(currentSampler.get() == this); currentSampler.set(parentSampler); } }