package org.gridkit.jvmtool.stacktrace;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
import com.carrotsearch.junitbenchmarks.BenchmarkRule;
@Ignore("Benchmark")
public class RegExMicrobenchmark {
private static StackFrame[] FRAMES;
private static StackFrame[] INTERNED_FRAMES;
private static StackTraceElement[] TRACE_ELEMENTS;
static {
FRAMES = loadFrames("stack-frame.txt", 1000);
INTERNED_FRAMES = new StackFrame[FRAMES.length];
TRACE_ELEMENTS = new StackTraceElement[FRAMES.length];
for(int i = 0; i != FRAMES.length; ++i) {
INTERNED_FRAMES[i] = FRAMES[i].internSymbols();
TRACE_ELEMENTS[i] = FRAMES[i].toStackTraceElement();
}
}
private static Pattern pattern1 = GlobHelper.translate("org.hibernate.type.AbstractStandardBasicType.getHashCode", ".");
private static Pattern pattern2 = GlobHelper.translate("**.TagMethodExpression.invoke", ".");
private static Pattern pattern3 = GlobHelper.translate("org.jboss.seam.**", ".");
private static StackFrame[] loadFrames(String res, int multiplier) {
try {
List<StackFrame> frames = new ArrayList<StackFrame>();
for(int i = 0; i != multiplier; ++i) {
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(res);
BufferedReader br = new BufferedReader(new InputStreamReader(is));
while(true) {
String line = br.readLine();
if (line == null) {
break;
}
if (line.trim().length() > 0)
frames.add(StackFrame.parseFrame(line.trim()));
}
}
return frames.toArray(new StackFrame[frames.size()]);
} catch (IOException e) {
throw new RuntimeException(e);
}
};
@Rule
public TestName testName = new TestName();
@Rule
public volatile BenchmarkRule benchmark = new BenchmarkRule();
@Test
public void frame_pattern1() {
testFrameMatcher(FRAMES, pattern1);
}
@Test
public void frame_pattern2() {
testFrameMatcher(FRAMES, pattern2);
}
@Test
public void frame_pattern3() {
testFrameMatcher(FRAMES, pattern3);
}
@Test
public void frame_patternAll() {
testFrameMatcher(FRAMES, pattern1, pattern2, pattern3);
}
@Test
public void interned_frame_pattern1() {
testFrameMatcher(INTERNED_FRAMES, pattern1);
}
@Test
public void interned_frame_pattern2() {
testFrameMatcher(INTERNED_FRAMES, pattern2);
}
@Test
public void interned_frame_pattern3() {
testFrameMatcher(INTERNED_FRAMES, pattern3);
}
@Test
public void interned_frame_patternAll() {
testFrameMatcher(INTERNED_FRAMES, pattern1, pattern2, pattern3);
}
@Test
public void trace_element_pattern1() {
testFrameMatcher(TRACE_ELEMENTS, pattern1);
}
@Test
public void trace_element_pattern2() {
testFrameMatcher(TRACE_ELEMENTS, pattern2);
}
@Test
public void trace_element_pattern3() {
testFrameMatcher(TRACE_ELEMENTS, pattern3);
}
@Test
public void trace_element_patternAll() {
testFrameMatcher(TRACE_ELEMENTS, pattern1, pattern2, pattern3);
}
protected void testFrameMatcher(StackFrame[] frames, Pattern... pattern) {
int[] count = new int[pattern.length];
Matcher[] matcher = new Matcher[pattern.length];
for(int i = 0; i != pattern.length; ++i) {
matcher[i] = pattern[i].matcher("");
}
for(StackFrame frame: frames) {
for(int i = 0; i != pattern.length; ++i) {
if (match(frame, matcher[i])) {
++count[i];
}
}
}
if (benchmark == null) {
System.out.println(testName.getMethodName());
for(int i = 0; i != pattern.length; ++i) {
System.out.println(" " + count[i] + " - " + pattern[i].pattern());
}
}
}
protected void testFrameMatcher(StackTraceElement[] frames, Pattern... pattern) {
int[] count = new int[pattern.length];
Matcher[] matcher = new Matcher[pattern.length];
for(int i = 0; i != pattern.length; ++i) {
matcher[i] = pattern[i].matcher("");
}
for(StackTraceElement frame: frames) {
for(int i = 0; i != pattern.length; ++i) {
if (match(frame.toString(), matcher[i])) {
++count[i];
}
}
}
if (benchmark == null) {
System.out.println(testName.getMethodName());
for(int i = 0; i != pattern.length; ++i) {
System.out.println(" " + count[i] + " - " + pattern[i].pattern());
}
}
}
private boolean match(CharSequence frame, Matcher pattern) {
pattern.reset(frame);
return pattern.lookingAt();
}
}