Добавлено кэширование для substring и subbytes паттернов
This commit is contained in:
@@ -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)));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|||||||
Reference in New Issue
Block a user