001/* 002 * (C) Copyright 2017 Nuxeo (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Nuxeo - initial API and implementation 018 */ 019package org.nuxeo.runtime.util; 020 021import java.text.DecimalFormat; 022import java.util.HashMap; 023import java.util.Map; 024import java.util.concurrent.TimeUnit; 025 026/** 027 * Usage: 028 * 029 * <pre> 030 * <code> 031 * Watch w = new Watch() 032 * w.start(); 033 * ... 034 * w.start("interval-name") 035 * w.stop("interval-name") 036 * .. 037 * w.stop() 038 * </code> 039 * </pre> 040 * 041 * @author bogdan 042 * @since 9.2 043 */ 044public class Watch { 045 046 public final TimeInterval total = new TimeInterval("total"); 047 048 public final Map<String, TimeInterval> intervals = new HashMap<>(); 049 050 public Watch start() { 051 // reset if needed 052 total.t0 = 0; 053 total.t1 = 0; 054 intervals.clear(); 055 056 total.start(); 057 return this; 058 } 059 060 public Watch stop() { 061 total.stop(); 062 return this; 063 } 064 065 public Watch start(String interval) { 066 TimeInterval ti = intervals.get(interval); 067 if (ti == null) { 068 ti = new TimeInterval(interval); 069 intervals.put(interval, ti); 070 } 071 ti.start(); 072 return this; 073 } 074 075 public Watch stop(String interval) { 076 TimeInterval ti = intervals.get(interval); 077 if (ti != null) { 078 ti.stop(); 079 } 080 return this; 081 } 082 083 public long elapsed(TimeUnit unit) { 084 return total.elapsed(unit); 085 } 086 087 public long elapsed(String name, TimeUnit unit) { 088 TimeInterval ti = intervals.get(name); 089 if (ti != null) { 090 return total.elapsed(unit); 091 } 092 return 0; 093 } 094 095 public TimeInterval getTotal() { 096 return total; 097 } 098 099 public TimeInterval[] getIntervals() { 100 return intervals.values().toArray(new TimeInterval[intervals.size()]); 101 } 102 103 public static class TimeInterval implements Comparable<TimeInterval> { 104 105 public String name; 106 107 public long t0; 108 109 public long t1; 110 111 public TimeInterval(String name) { 112 this.name = name; 113 } 114 115 /** 116 * Elapsed time in nano seconds 117 */ 118 public long elapsed() { 119 return t1 - t0; 120 } 121 122 public long elapsed(TimeUnit unit) { 123 return unit.convert(t1 - t0, TimeUnit.NANOSECONDS); 124 } 125 126 protected void start() { 127 this.t0 = System.nanoTime(); 128 } 129 130 protected void stop() { 131 this.t1 = System.nanoTime(); 132 } 133 134 @Override 135 public int compareTo(TimeInterval o) { 136 long dt = (t1 - t0) - (o.t1 - o.t0); // this may be out of range for an int 137 return dt < 0 ? -1 : (dt > 0 ? 1 : 0); 138 } 139 140 public String formatSeconds() { 141 return new DecimalFormat("0.000").format(((double) this.t1 - this.t0) / 1000000000); 142 } 143 144 @Override 145 public String toString() { 146 return name + ": " + this.formatSeconds() + " sec."; 147 } 148 149 } 150 151}