Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: d9f10b44663b81defeb543673a8d8429bfe3e351 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
/*******************************************************************************
 * Copyright (c) 2013 Red Hat Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Red Hat Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.linuxtools.internal.perf;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.linuxtools.internal.perf.handlers.Messages;
import org.eclipse.linuxtools.internal.perf.model.PMStatEntry;
import org.eclipse.linuxtools.internal.perf.model.PMStatEntry.Type;

/**
 * Class containing all functionality for comparting perf statistics data.
 */
public class StatComparisonData implements IPerfData {
	// Old stats file.
	private File oldFile;

	// New stats file.
	private File newFile;

	// Comparison result string.
	private String result = ""; //$NON-NLS-1$

	// Title for this comparison run.
	private String title;

	public StatComparisonData(String title, File oldFile, File newFile) {
		this.title = title;
		this.oldFile = oldFile;
		this.newFile = newFile;
	}

	@Override
	public String getPerfData() {
		return result;
	}

	@Override
	public String getTitle() {
		return title;
	}

	/**
	 * Compare stat data files and store the result in the result field.
	 */
	public void runComparison() {
		ArrayList<PMStatEntry> statsDiff = getComparisonStats();

		if (!statsDiff.isEmpty()) {
			String[][] statsDiffStr = new String[statsDiff.size()][];
			int currentRow = 0;

			// gather comparison results in a string array
			for (PMStatEntry statEntry : statsDiff) {
				statsDiffStr[currentRow] = statEntry.toStringArray();
				currentRow++;
			}

			// apply format to each entry and set the result
			String format = getFormat(statsDiffStr);
			String curLine;
			for (String[] statEntry : statsDiffStr) {
				curLine = String.format(format, (Object[]) statEntry);
				curLine = curLine.contains(PMStatEntry.TIME) ? "\n" + curLine //$NON-NLS-1$
						: curLine;
				result += curLine;
			}
		} else{

		}
	}

	/**
	 * Return a PMStatEntry array with the result of the comparison between the
	 * old and new stat data files
	 * @return
	 */
	public ArrayList<PMStatEntry> getComparisonStats() {
		ArrayList<PMStatEntry> oldStats = collectStats(oldFile);
		ArrayList<PMStatEntry> newStats = collectStats(newFile);
		ArrayList<PMStatEntry> result = new ArrayList<PMStatEntry>();

		for (PMStatEntry oldEntry : oldStats) {
			for (PMStatEntry newEntry : newStats) {
				if (oldEntry.equalEvents(newEntry)) {
					result.add(oldEntry.compare(newEntry));
					continue;
				}
			}
		}

		return result;
	}

	/**
	 * Collect statistics entries from the specified stat data file.
	 *
	 * @param file file to collect from
	 * @return List containing statistics entries from the given file.
	 */
	public static ArrayList<PMStatEntry> collectStats(File statFile) {
		ArrayList<PMStatEntry> result = new ArrayList<PMStatEntry>();
		BufferedReader statReader = null;
		try {
			statReader = new BufferedReader(new FileReader(statFile));

			// pattern for a valid perf stat entry
			Pattern entryPattern = Pattern.compile(PMStatEntry.getString(Type.ENTRY_PATTERN));

			// pattern for last stat entry (seconds elapsed):
			Pattern totalTimePattern = Pattern.compile(PMStatEntry.getString(Type.TIME_PATTERN));

			String line;
			while((line = statReader.readLine()) != null ){
				line = line.trim();
				Matcher match = entryPattern.matcher(line);
				String samples, event, usage, units, delta, scale;
				PMStatEntry statEntry;

				if(match.find()){

					// extract information from groups
					samples = match.group(1);
					event = match.group(2);
					usage = match.group(6);
					units = match.group(7);
					delta = match.group(9);
					scale = match.group(13);

					// create stat entry
					statEntry = new PMStatEntry(toFloat(samples), event,
							toFloat(usage), units, toFloat(delta),
							toFloat(scale));

					// add stat entry to results list
					result.add(statEntry);

				} else if(line.contains(PMStatEntry.TIME)){

					// match seconds elapsed pattern
					match = totalTimePattern.matcher(line);
					if(match.find()){
						samples = match.group(1);
						event = match.group(2);
						delta = match.group(4);

						// create stat entry
						statEntry = new PMStatEntry(toFloat(samples),
								event, 0, null, toFloat(delta), 0);

						result.add(statEntry);
					}
				}
			}
			return result;
		} catch (FileNotFoundException e) {
			PerfPlugin.getDefault().openError(e, Messages.MsgError);
		} catch (IOException e) {
			PerfPlugin.getDefault().openError(e, Messages.MsgError);
		} finally {
			try {
				if (statReader != null) {
					statReader.close();
				}
			} catch (IOException e) {
				PerfPlugin.getDefault().openError(e, Messages.PerfResourceLeak_title);
			}
		}

		return result;
	}

	/**
	 * Get formatting string from unformatted table.
	 *
	 * @param table array to construct formatting for.
	 * @return Formatting string representing the proper way to format the given
	 *         table.
	 */
	public String getFormat(String[][] table) {
		// all entries have the same number of columns
		int[] maxCharLen = new int[table[0].length];

		// collect max number of characters per column
		for (int i = 0; i < table.length; i++) {
			for (int j = 0; j < table[i].length; j++) {
				maxCharLen[j] = Math.max(maxCharLen[j], table[i][j].length());
			}
		}

		// prepare format arguments
		ArrayList<Integer> arguments = new ArrayList<Integer>();
		for (int length : maxCharLen) {
			arguments.add(length);
		}

		// generate format string
		String entryFormat = String.format(
				PMStatEntry.getString(Type.ENTRY_FORMAT),
				arguments.toArray());

		return entryFormat;
	}

	/**
	 * Get float representation of specified string.
	 *
	 * @param str String convert
	 * @return Float representation of string.
	 */
	public static float toFloat(String str) {
		try {
			// remove commas from number string representation
			return (str == null) ? 0
					: Float.parseFloat(str.replace(",", "")); //$NON-NLS-1$//$NON-NLS-2$
		} catch (NumberFormatException e) {
			return 0;
		}
	}
}

Back to the top