1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with this 4 * work for additional information regarding copyright ownership. The ASF 5 * licenses this file to you under the Apache License, Version 2.0 (the 6 * "License"); you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14 * License for the specific language governing permissions and limitations under 15 * the License. 16 */ 17 package org.apache.hadoop.hbase.io.hfile; 18 19 /** 20 * A nano-second timer. 21 * <p> 22 * Copied from 23 * <a href="https://issues.apache.org/jira/browse/HADOOP-3315">hadoop-3315 tfile</a>. 24 * Remove after tfile is committed and use the tfile version of this class 25 * instead.</p> 26 */ 27 public class NanoTimer { 28 private long last = -1; 29 private boolean started = false; 30 private long cumulate = 0; 31 32 /** 33 * Constructor 34 * 35 * @param start 36 * Start the timer upon construction. 37 */ 38 public NanoTimer(boolean start) { 39 if (start) this.start(); 40 } 41 42 /** 43 * Start the timer. 44 * 45 * Note: No effect if timer is already started. 46 */ 47 public void start() { 48 if (!this.started) { 49 this.last = System.nanoTime(); 50 this.started = true; 51 } 52 } 53 54 /** 55 * Stop the timer. 56 * 57 * Note: No effect if timer is already stopped. 58 */ 59 public void stop() { 60 if (this.started) { 61 this.started = false; 62 this.cumulate += System.nanoTime() - this.last; 63 } 64 } 65 66 /** 67 * Read the timer. 68 * 69 * @return the elapsed time in nano-seconds. Note: If the timer is never 70 * started before, -1 is returned. 71 */ 72 public long read() { 73 if (!readable()) return -1; 74 75 return this.cumulate; 76 } 77 78 /** 79 * Reset the timer. 80 */ 81 public void reset() { 82 this.last = -1; 83 this.started = false; 84 this.cumulate = 0; 85 } 86 87 /** 88 * Checking whether the timer is started 89 * 90 * @return true if timer is started. 91 */ 92 public boolean isStarted() { 93 return this.started; 94 } 95 96 /** 97 * Format the elapsed time to a human understandable string. 98 * 99 * Note: If timer is never started, "ERR" will be returned. 100 */ 101 public String toString() { 102 if (!readable()) { 103 return "ERR"; 104 } 105 106 return NanoTimer.nanoTimeToString(this.cumulate); 107 } 108 109 /** 110 * A utility method to format a time duration in nano seconds into a human 111 * understandable stirng. 112 * 113 * @param t 114 * Time duration in nano seconds. 115 * @return String representation. 116 */ 117 public static String nanoTimeToString(long t) { 118 if (t < 0) return "ERR"; 119 120 if (t == 0) return "0"; 121 122 if (t < 1000) { 123 return t + "ns"; 124 } 125 126 double us = (double) t / 1000; 127 if (us < 1000) { 128 return String.format("%.2fus", us); 129 } 130 131 double ms = us / 1000; 132 if (ms < 1000) { 133 return String.format("%.2fms", ms); 134 } 135 136 double ss = ms / 1000; 137 if (ss < 1000) { 138 return String.format("%.2fs", ss); 139 } 140 141 long mm = (long) ss / 60; 142 ss -= mm * 60; 143 long hh = mm / 60; 144 mm -= hh * 60; 145 long dd = hh / 24; 146 hh -= dd * 24; 147 148 if (dd > 0) { 149 return String.format("%dd%dh", dd, hh); 150 } 151 152 if (hh > 0) { 153 return String.format("%dh%dm", hh, mm); 154 } 155 156 if (mm > 0) { 157 return String.format("%dm%.1fs", mm, ss); 158 } 159 160 return String.format("%.2fs", ss); 161 162 /** 163 * StringBuilder sb = new StringBuilder(); String sep = ""; 164 * 165 * if (dd > 0) { String unit = (dd > 1) ? "days" : "day"; 166 * sb.append(String.format("%s%d%s", sep, dd, unit)); sep = " "; } 167 * 168 * if (hh > 0) { String unit = (hh > 1) ? "hrs" : "hr"; 169 * sb.append(String.format("%s%d%s", sep, hh, unit)); sep = " "; } 170 * 171 * if (mm > 0) { String unit = (mm > 1) ? "mins" : "min"; 172 * sb.append(String.format("%s%d%s", sep, mm, unit)); sep = " "; } 173 * 174 * if (ss > 0) { String unit = (ss > 1) ? "secs" : "sec"; 175 * sb.append(String.format("%s%.3f%s", sep, ss, unit)); sep = " "; } 176 * 177 * return sb.toString(); 178 */ 179 } 180 181 private boolean readable() { 182 return this.last != -1; 183 } 184 185 /** 186 * Simple tester. 187 * 188 * @param args 189 */ 190 public static void main(String[] args) { 191 long i = 7; 192 193 for (int x = 0; x < 20; ++x, i *= 7) { 194 System.out.println(NanoTimer.nanoTimeToString(i)); 195 } 196 } 197 } 198