001: /*
002: * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
003: * (license2)
004: * Initial Developer: H2 Group
005: */
006: package org.h2.test.coverage;
007:
008: import java.io.BufferedWriter;
009: import java.io.FileReader;
010: import java.io.FileWriter;
011: import java.io.IOException;
012: import java.io.LineNumberReader;
013: import java.io.OutputStream;
014: import java.io.Reader;
015: import java.io.Writer;
016:
017: /**
018: * The class used at runtime to measure the code usage and performance.
019: */
020: public class Profile extends Thread {
021: public static final boolean LIST_UNVISITED = false;
022: public static final boolean FAST = false;
023: public static final boolean TRACE = false;
024: public static final Profile MAIN = new Profile();
025: public static int current;
026: private BufferedWriter trace;
027: public int[] count;
028: public int[] time;
029: boolean stop;
030: int maxIndex;
031: int lastIndex;
032: long lastTime;
033: static int top = 15;
034:
035: static {
036: try {
037: String s = System.getProperty("profile.top");
038: if (s != null) {
039: top = Integer.parseInt(s);
040: }
041: } catch (Throwable e) {
042: // ignore SecurityExceptions
043: }
044: }
045:
046: public static void visit(int i) {
047: if (FAST) {
048: current = i;
049: } else {
050: MAIN.addVisit(i);
051: }
052: }
053:
054: public void run() {
055: list();
056: }
057:
058: public static void startCollecting() {
059: MAIN.stop = false;
060: MAIN.lastTime = System.currentTimeMillis();
061: }
062:
063: public static void stopCollecting() {
064: MAIN.stop = true;
065: }
066:
067: public static void list() {
068: if (MAIN.lastIndex == 0) {
069: // don't list anything if no statistics collected
070: return;
071: }
072: try {
073: MAIN.listUnvisited();
074: MAIN.listTop("MOST CALLED", MAIN.count, top);
075: MAIN.listTop("MOST TIME USED", MAIN.time, top);
076: } catch (Exception e) {
077: e.printStackTrace();
078: }
079: }
080:
081: Profile() {
082: FileReader reader = null;
083: try {
084: reader = new FileReader("profile.txt");
085: LineNumberReader r = new LineNumberReader(reader);
086: while (r.readLine() != null) {
087: // nothing - just count lines
088: }
089: maxIndex = r.getLineNumber();
090: count = new int[maxIndex];
091: time = new int[maxIndex];
092: lastTime = System.currentTimeMillis();
093: Runtime.getRuntime().addShutdownHook(this );
094: } catch (Exception e) {
095: e.printStackTrace();
096: System.exit(1);
097: } finally {
098: closeSilently(reader);
099: }
100: }
101:
102: private void closeSilently(Reader reader) {
103: if (reader != null) {
104: try {
105: reader.close();
106: } catch (IOException e) {
107: // ignore
108: }
109: }
110: }
111:
112: private void closeSilently(Writer writer) {
113: if (writer != null) {
114: try {
115: writer.close();
116: } catch (IOException e) {
117: // ignore
118: }
119: }
120: }
121:
122: public static void closeSilently(OutputStream out) {
123: if (out != null) {
124: try {
125: out.close();
126: } catch (IOException e) {
127: // ignore
128: }
129: }
130: }
131:
132: void addVisit(int i) {
133: if (stop) {
134: return;
135: }
136: long now = System.currentTimeMillis();
137: if (TRACE && trace != null) {
138: int duration = (int) (now - lastTime);
139: try {
140: trace.write(i + "\t" + duration + "\r\n");
141: } catch (Exception e) {
142: e.printStackTrace();
143: System.exit(1);
144: }
145: }
146: count[i]++;
147: time[lastIndex] += (int) (now - lastTime);
148: lastTime = now;
149: lastIndex = i;
150: }
151:
152: void listUnvisited() throws Exception {
153: printLine('=');
154: print("NOT COVERED");
155: printLine('-');
156: FileReader reader = null;
157: FileWriter fileWriter = null;
158: try {
159: reader = new FileReader("profile.txt");
160: LineNumberReader r = new LineNumberReader(reader);
161: fileWriter = new FileWriter("notCovered.txt");
162: BufferedWriter writer = new BufferedWriter(fileWriter);
163: int unvisited = 0;
164: int unvisitedThrow = 0;
165: for (int i = 0; i < maxIndex; i++) {
166: String line = r.readLine();
167: if (count[i] == 0) {
168: if (!line.endsWith("throw")) {
169: writer.write(line + "\r\n");
170: if (LIST_UNVISITED) {
171: print(line + "\r\n");
172: }
173: unvisited++;
174: } else {
175: unvisitedThrow++;
176: }
177: }
178: }
179: int percent = (100 * unvisited / maxIndex);
180: print("Not covered: " + percent + " % " + " (" + unvisited
181: + " of " + maxIndex + "; throw=" + unvisitedThrow
182: + ")");
183: } finally {
184: closeSilently(fileWriter);
185: closeSilently(reader);
186: }
187: }
188:
189: void listTop(String title, int[] list, int max) throws Exception {
190: printLine('-');
191: int total = 0;
192: int totalLines = 0;
193: for (int j = 0; j < maxIndex; j++) {
194: int l = list[j];
195: if (l > 0) {
196: total += list[j];
197: totalLines++;
198: }
199: }
200: if (max == 0) {
201: max = totalLines;
202: }
203: print(title);
204: print("Total: " + total);
205: printLine('-');
206: String[] text = new String[max];
207: int[] index = new int[max];
208: for (int i = 0; i < max; i++) {
209: int big = list[0];
210: int bigIndex = 0;
211: for (int j = 1; j < maxIndex; j++) {
212: int l = list[j];
213: if (l > big) {
214: big = l;
215: bigIndex = j;
216: }
217: }
218: list[bigIndex] = -(big + 1);
219: index[i] = bigIndex;
220: }
221: FileReader reader = null;
222: try {
223: reader = new FileReader("profile.txt");
224: LineNumberReader r = new LineNumberReader(reader);
225: for (int i = 0; i < maxIndex; i++) {
226: String line = r.readLine();
227: int k = list[i];
228: if (k < 0) {
229: k = -(k + 1);
230: list[i] = k;
231: for (int j = 0; j < max; j++) {
232: if (index[j] == i) {
233: int percent = (100 * k / total);
234: text[j] = k + " " + percent + "%: " + line;
235: }
236: }
237: }
238: }
239: for (int i = 0; i < max; i++) {
240: print(text[i]);
241: }
242: } finally {
243: closeSilently(reader);
244: }
245: }
246:
247: void print(String s) {
248: System.out.println(s);
249: }
250:
251: void printLine(char c) {
252: for (int i = 0; i < 60; i++) {
253: System.out.print(c);
254: }
255: print("");
256: }
257: }
|