Refactor DataBufferUtils Matcher implementation
The existing implementation was exposed to very poor performance when matching with multiple delimiters against a large buffer with many delimiters. In that case all matchers are invoked many times (as many as the number of delimiters) even though some of them found no match at all on the first pass. The revised implementation uses a single index and advances all matchers together, checking one byte a time, and not letting any one of them search to the end of the entire buffer on a single pass. Closes gh-25915
This commit is contained in:
@@ -886,18 +886,38 @@ class DataBufferUtilsTests extends AbstractDataBufferAllocatingTests {
|
||||
void matcher2(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer foo = stringBuffer("fooobar");
|
||||
DataBuffer foo = stringBuffer("foooobar");
|
||||
|
||||
byte[] delims = "oo".getBytes(StandardCharsets.UTF_8);
|
||||
DataBufferUtils.Matcher matcher = DataBufferUtils.matcher(delims);
|
||||
int result = matcher.match(foo);
|
||||
assertThat(result).isEqualTo(2);
|
||||
foo.readPosition(2);
|
||||
result = matcher.match(foo);
|
||||
assertThat(result).isEqualTo(3);
|
||||
foo.readPosition(3);
|
||||
result = matcher.match(foo);
|
||||
assertThat(result).isEqualTo(-1);
|
||||
int endIndex = matcher.match(foo);
|
||||
assertThat(endIndex).isEqualTo(2);
|
||||
foo.readPosition(endIndex + 1);
|
||||
endIndex = matcher.match(foo);
|
||||
assertThat(endIndex).isEqualTo(4);
|
||||
foo.readPosition(endIndex + 1);
|
||||
endIndex = matcher.match(foo);
|
||||
assertThat(endIndex).isEqualTo(-1);
|
||||
|
||||
release(foo);
|
||||
}
|
||||
|
||||
@ParameterizedDataBufferAllocatingTest
|
||||
void matcher3(String displayName, DataBufferFactory bufferFactory) {
|
||||
super.bufferFactory = bufferFactory;
|
||||
|
||||
DataBuffer foo = stringBuffer("foooobar");
|
||||
|
||||
byte[] delims = "oo".getBytes(StandardCharsets.UTF_8);
|
||||
DataBufferUtils.Matcher matcher = DataBufferUtils.matcher(delims);
|
||||
int endIndex = matcher.match(foo);
|
||||
assertThat(endIndex).isEqualTo(2);
|
||||
foo.readPosition(endIndex + 1);
|
||||
endIndex = matcher.match(foo);
|
||||
assertThat(endIndex).isEqualTo(4);
|
||||
foo.readPosition(endIndex + 1);
|
||||
endIndex = matcher.match(foo);
|
||||
assertThat(endIndex).isEqualTo(-1);
|
||||
|
||||
release(foo);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user