8132995: Matcher$ImmutableMatchResult should be optimized to reduce space usage

Reviewed-by: redestad, smarks
This commit is contained in:
Raffaello Giulietti 2023-05-19 08:04:32 +00:00
parent 6765761075
commit 25868b95ee
2 changed files with 194 additions and 26 deletions

View file

@ -274,30 +274,26 @@ public final class Matcher implements MatchResult {
* @since 1.5
*/
public MatchResult toMatchResult() {
return toMatchResult(text.toString());
}
private MatchResult toMatchResult(String text) {
return new ImmutableMatchResult(this.first,
this.last,
groupCount(),
this.groups.clone(),
text,
namedGroups());
String capturedText = hasMatch()
? text.subSequence(first, last).toString()
: null;
return new ImmutableMatchResult(first, last, groupCount(),
groups.clone(), capturedText,
namedGroups()
);
}
private static class ImmutableMatchResult implements MatchResult {
private final int first;
private final int last;
private final int[] groups;
private final int groupCount;
private final int[] groups;
private final String text;
private final Map<String, Integer> namedGroups;
ImmutableMatchResult(int first, int last, int groupCount,
int[] groups, String text,
Map<String, Integer> namedGroups)
{
Map<String, Integer> namedGroups) {
this.first = first;
this.last = last;
this.groupCount = groupCount;
@ -349,7 +345,7 @@ public final class Matcher implements MatchResult {
checkGroup(group);
if ((groups[group * 2] == -1) || (groups[group * 2 + 1] == -1))
return null;
return text.subSequence(groups[group * 2], groups[group * 2 + 1]).toString();
return text.substring(groups[group * 2] - first, groups[group * 2 + 1] - first);
}
@Override
@ -370,7 +366,6 @@ public final class Matcher implements MatchResult {
private void checkMatch() {
if (!hasMatch())
throw new IllegalStateException("No match found");
}
}
@ -1318,9 +1313,6 @@ public final class Matcher implements MatchResult {
// State for concurrent modification checking
// -1 for uninitialized
int expectedCount = -1;
// The input sequence as a string, set once only after first find
// Avoids repeated conversion from CharSequence for each match
String textAsString;
@Override
public MatchResult next() {
@ -1331,7 +1323,7 @@ public final class Matcher implements MatchResult {
throw new NoSuchElementException();
state = -1;
return toMatchResult(textAsString);
return toMatchResult();
}
@Override
@ -1346,9 +1338,6 @@ public final class Matcher implements MatchResult {
return true;
boolean found = find();
// Capture the input sequence as a string on first find
if (found && state < 0)
textAsString = text.toString();
state = found ? 1 : 0;
expectedCount = modCount;
return found;
@ -1371,12 +1360,9 @@ public final class Matcher implements MatchResult {
if (s < 0 && !find())
return;
// Capture the input sequence as a string on first find
textAsString = text.toString();
do {
int ec = modCount;
action.accept(toMatchResult(textAsString));
action.accept(toMatchResult());
if (ec != modCount)
throw new ConcurrentModificationException();
} while (find());