package org.gridkit.jvmtool.stacktrace.analytics; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.gridkit.jvmtool.stacktrace.StackFrame; /** * This filter factory is introducing hit cache on frame * matcher level. It also reusing matcher instance. * <br/> * These optimizations are not thread safe. * * @author Alexey Ragozin (alexey.ragozin@gmail.com) */ public class CachingFilterFactory extends BasicFilterFactory { @Override public StackFrameMatcher patternFrameMatcher(Collection<String> patterns) { if (patterns.isEmpty()) { throw new IllegalArgumentException("Pattern list is empty"); } return new CachingPatternFrameMatcher(patterns); } protected static class CachingPatternFrameMatcher implements StackFrameMatcher { private final Matcher regEx; private final Map<StackFrame, Boolean> hitCahce = new HashMap<StackFrame, Boolean>(); CachingPatternFrameMatcher(Collection<String> patterns) { StringBuilder sb = new StringBuilder(); sb.append('('); for(String pattern: patterns) { sb.append(wildCardTranslate(pattern)); sb.append('|'); } sb.setCharAt(sb.length() - 1, ')'); regEx = Pattern.compile(sb.toString()).matcher(""); } @Override public boolean evaluate(StackFrame frame) { Boolean hit = hitCahce.get(frame); if (hit != null) { return hit; } else { regEx.reset(frame); hit = regEx.lookingAt(); hitCahce.put(frame, hit); } return hit; } } }