Добавлено кэширование для substring и subbytes паттернов

This commit is contained in:
serega6531
2021-01-11 10:27:39 +03:00
parent ba63899af4
commit 8c752f1d44
2 changed files with 28 additions and 14 deletions

View File

@@ -15,7 +15,9 @@ import java.util.regex.Matcher;
public class PatternMatcher { public class PatternMatcher {
private static final Map<String, java.util.regex.Pattern> compiledPatterns = new HashMap<>(); private static final Map<String, java.util.regex.Pattern> compiledRegexes = new HashMap<>();
private static final Map<String, KMPStringSearcher> compiledStringKmps = new HashMap<>();
private static final Map<String, KMPByteSearcher> compiledByteKmps = new HashMap<>();
private final byte[] contentBytes; private final byte[] contentBytes;
private final String content; private final String content;
@@ -43,7 +45,7 @@ public class PatternMatcher {
} }
private void matchRegex(Pattern pattern) { private void matchRegex(Pattern pattern) {
final var regex = compilePattern(pattern); final var regex = compileRegex(pattern);
final Matcher matcher = regex.matcher(content); final Matcher matcher = regex.matcher(content);
int startPos = 0; int startPos = 0;
@@ -59,7 +61,7 @@ public class PatternMatcher {
private void matchSubstring(Pattern pattern) { private void matchSubstring(Pattern pattern) {
final String value = pattern.getValue(); final String value = pattern.getValue();
KMPStringSearcher searcher = new KMPStringSearcher(value.toCharArray()); KMPStringSearcher searcher = compileStringKMP(pattern);
StringReader reader = new StringReader(content); StringReader reader = new StringReader(content);
while (true) { while (true) {
@@ -81,7 +83,7 @@ public class PatternMatcher {
@SneakyThrows @SneakyThrows
private void matchSubbytes(Pattern pattern) { private void matchSubbytes(Pattern pattern) {
final byte[] value = Hex.decode(pattern.getValue()); final byte[] value = Hex.decode(pattern.getValue());
KMPByteSearcher searcher = new KMPByteSearcher(value); KMPByteSearcher searcher = compileByteKMP(pattern);
InputStream is = new ByteArrayInputStream(contentBytes); InputStream is = new ByteArrayInputStream(contentBytes);
while (true) { while (true) {
@@ -112,8 +114,24 @@ public class PatternMatcher {
return a <= x && x <= b; return a <= x && x <= b;
} }
static java.util.regex.Pattern compilePattern(Pattern pattern) { static void compilePattern(Pattern pattern) {
return compiledPatterns.computeIfAbsent(pattern.getValue(), java.util.regex.Pattern::compile); switch (pattern.getSearchType()) {
case REGEX -> compileRegex(pattern);
case SUBSTRING -> compileStringKMP(pattern);
case SUBBYTES -> compileByteKMP(pattern);
}
}
private static java.util.regex.Pattern compileRegex(Pattern pattern) {
return compiledRegexes.computeIfAbsent(pattern.getValue(), java.util.regex.Pattern::compile);
}
private static KMPStringSearcher compileStringKMP(Pattern pattern) {
return compiledStringKmps.computeIfAbsent(pattern.getValue(), val -> new KMPStringSearcher(val.toCharArray()));
}
private static KMPByteSearcher compileByteKMP(Pattern pattern) {
return compiledByteKmps.computeIfAbsent(pattern.getValue(), val -> new KMPByteSearcher(Hex.decode(val)));
} }
} }

View File

@@ -10,7 +10,6 @@ import ru.serega6531.packmate.model.FoundPattern;
import ru.serega6531.packmate.model.Pattern; import ru.serega6531.packmate.model.Pattern;
import ru.serega6531.packmate.model.enums.PatternActionType; import ru.serega6531.packmate.model.enums.PatternActionType;
import ru.serega6531.packmate.model.enums.PatternDirectionType; import ru.serega6531.packmate.model.enums.PatternDirectionType;
import ru.serega6531.packmate.model.enums.PatternSearchType;
import ru.serega6531.packmate.model.enums.SubscriptionMessageType; import ru.serega6531.packmate.model.enums.SubscriptionMessageType;
import ru.serega6531.packmate.model.pojo.PatternDto; import ru.serega6531.packmate.model.pojo.PatternDto;
import ru.serega6531.packmate.model.pojo.SubscriptionMessage; import ru.serega6531.packmate.model.pojo.SubscriptionMessage;
@@ -19,7 +18,6 @@ import ru.serega6531.packmate.repository.PatternRepository;
import java.time.Instant; import java.time.Instant;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.regex.PatternSyntaxException;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Service @Service
@@ -85,12 +83,10 @@ public class PatternService {
} }
public Pattern save(Pattern pattern) { public Pattern save(Pattern pattern) {
if (pattern.getSearchType() == PatternSearchType.REGEX) { try {
try { PatternMatcher.compilePattern(pattern);
PatternMatcher.compilePattern(pattern); } catch (Exception e) {
} catch (PatternSyntaxException e) { throw new IllegalArgumentException(e.getMessage());
throw new IllegalArgumentException(e.getMessage());
}
} }
pattern.setSearchStartTimestamp(System.currentTimeMillis()); pattern.setSearchStartTimestamp(System.currentTimeMillis());