Package com.redhat.ceylon.compiler.java.util

Source Code of com.redhat.ceylon.compiler.java.util.Timer$IgnoredCategory

/*
* Copyright Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the authors tag. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License version 2.
*
* This particular file is subject to the "Classpath" exception as provided in the
* LICENSE file that accompanied this code.
*
* This program is distributed in the hope that it will be useful, but WITHOUT A
* 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 this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA  02110-1301, USA.
*/
package com.redhat.ceylon.compiler.java.util;

import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

import com.sun.tools.javac.main.OptionName;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Log;
import com.sun.tools.javac.util.Options;

public class Timer {
    private long programStart;
    private String currentTask;
    private long currentTaskStart;
    private boolean verbose;
    private final Map<String,IgnoredCategory> ignoredCategories;
    private PrintWriter out;

    private static final Context.Key<Timer> timerKey = new Context.Key<Timer>();
   
    private Timer(long programStart, boolean verbose, Map<String,IgnoredCategory> ignoredCategories) {
        this.programStart = programStart;
        this.verbose = verbose;
        this.ignoredCategories = ignoredCategories;
    }
   
    public static Timer instance(Context context) {
        Timer instance = (Timer)context.get(timerKey);
        if (instance == null){
            instance = new Timer(context);
            context.put(timerKey, instance);
        }
        return instance;
    }
   
    public Timer(boolean verbose) {
        ignoredCategories = new HashMap<String,IgnoredCategory>();
        setup(verbose);
    }
   
    private Timer(Context context) {
        ignoredCategories = new HashMap<String,IgnoredCategory>();
        Options options = Options.instance(context);
        verbose = options.get(OptionName.VERBOSE) != null
                || options.get(OptionName.VERBOSE + ":benchmark" ) != null;
        out = context.get(Log.outKey);
    }
   
    private void setup(boolean verbose) {
        // we delay printing the program start because we don't know if the verbose option is set yet at
        // that time, so we fake it later on with the correct time
    }

    /**
     * Initializes this timer and {@linkplain #log(String) logs} a
     * "program start" message.
     */
    public void init(){
        programStart = System.nanoTime();
        if(verbose)
            log("Program start", programStart);
    }

    public void end() {
        if(!verbose)
            return;
        log("Program end");
    }

    /**
     * {@linkplain #endTask() Ends} the current task (if any) and starts a
     * timed task with the given name,
     * {@linkplain #log(String) logging} the task name.
     *
     * @param name The name of the task to start.
     *
     * @see #nestedTimer()
     */
    public void startTask(String name){
        if(!verbose)
            return;
        if(currentTask != null)
            endTask();
        currentTask = name;
        currentTaskStart = System.nanoTime();
        log("Task "+currentTask+" start");
    }
   
    /**
     * Logs a message, including the elapsed time since this Timer was
     * {@linkplain #init() initialized}.
     * @param string The message
     */
    public void log(String string) {
        if(!verbose)
            return;
        log(string, System.nanoTime());
    }

    private void log(String string, long now) {
        long delta = (now - programStart)/1_000_000;
        String msg = "["+delta+"ms] "+string;
        if(out != null)
            out.println(msg);
        else
            System.err.println(msg);
    }

    /**
     * Ends the current task, {@linkplain #log(String) logging} the name of
     * the task and its elapsed time
     * @see #startTask(String)
     */
    public void endTask() {
        if(!verbose)
            return;
        long time = System.nanoTime();
        long delta = (time - currentTaskStart)/1_000_000L;
        log("Task "+currentTask+" end: "+delta+"ms");
        printIgnoredCategories();
        currentTask = null;
    }

    public void startIgnore(String category) {
        if(!verbose)
            return;
        IgnoredCategory ignoredCategory = ignoredCategories.get(category);
        if(ignoredCategory == null){
            ignoredCategory = new IgnoredCategory(category);
            ignoredCategories.put(category, ignoredCategory);
        }
        ignoredCategory.start();
    }

    public void stopIgnore(String category) {
        if(!verbose)
            return;
        IgnoredCategory ignoredCategory = ignoredCategories.get(category);
        if (ignoredCategory != null) {
            ignoredCategory.stop();
        }
    }
   
    private void printIgnoredCategories(){
        for(IgnoredCategory category : ignoredCategories.values()){
            if(category.total != 0){
                System.err.println(" Including "+category.name+" for "+category.total+"ms");
            }
            category.reset();
        }
    }

    private final class IgnoredCategory {
        String name;
        long start;
        long total;
        int count;
        public IgnoredCategory(String category) {
            this.name = category;
        }
        public void start() {
            if(count++ == 0){
                start = System.nanoTime();
            }
        }
        public void stop() {
            if(--count == 0){
                long end = System.nanoTime();
                long delta = (end - start)/1_000_000;
                total += delta;
            }
        }
        public void reset() {
            if(count != 0)
                System.err.println("Ignored category "+name+" count is "+count+" during reset: timings will be wrong");
            // try to fix it for next time?
            count = 0;
            total = 0;
        }
    }
   
    /**
     * Creates and returns a new timer suitable for timing sub-tasks
     * without stopping the 'outer' timer. Necessary because
     * {@link #startTask(String)} stops the current timer.
     * @return The new timer
     */
    public Timer nestedTimer() {
        return new Timer(programStart, verbose, ignoredCategories);
    }
}
TOP

Related Classes of com.redhat.ceylon.compiler.java.util.Timer$IgnoredCategory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.