From 70ffc70993a2581a16640c20037474612eb4348d Mon Sep 17 00:00:00 2001 From: dreis2211 Date: Wed, 29 Apr 2020 21:11:42 +0200 Subject: [PATCH 1/2] Optimize StringSequence.startsWith See gh-21259 --- .../boot/loader/jar/StringSequence.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/StringSequence.java b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/StringSequence.java index a1129e7173..82d5812557 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/StringSequence.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/StringSequence.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -98,15 +98,19 @@ final class StringSequence implements CharSequence { return this.source.indexOf(str, this.start + fromIndex) - this.start; } - boolean startsWith(CharSequence prefix) { + boolean startsWith(String prefix) { return startsWith(prefix, 0); } - boolean startsWith(CharSequence prefix, int offset) { + boolean startsWith(String prefix, int offset) { int prefixLength = prefix.length(); - if (length() - prefixLength - offset < 0) { + int length = length(); + if (length - prefixLength - offset < 0) { return false; } + if (length == this.source.length()) { + return this.source.startsWith(prefix, offset); + } int prefixOffset = 0; int sourceOffset = offset; while (prefixLength-- != 0) { From 4a8492d428be5c659acc007e3b6f1462ff9fe645 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Tue, 5 May 2020 18:32:50 -0700 Subject: [PATCH 2/2] Further optimize StringSequence.startsWith See gh-21259 --- .../boot/loader/jar/StringSequence.java | 12 +----------- .../boot/loader/jar/StringSequenceTests.java | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/StringSequence.java b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/StringSequence.java index 82d5812557..25822d0fcd 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/StringSequence.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/StringSequence.java @@ -108,17 +108,7 @@ final class StringSequence implements CharSequence { if (length - prefixLength - offset < 0) { return false; } - if (length == this.source.length()) { - return this.source.startsWith(prefix, offset); - } - int prefixOffset = 0; - int sourceOffset = offset; - while (prefixLength-- != 0) { - if (charAt(sourceOffset++) != prefix.charAt(prefixOffset++)) { - return false; - } - } - return true; + return this.source.startsWith(prefix, this.start + offset); } @Override diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/StringSequenceTests.java b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/StringSequenceTests.java index fddd5ee72a..a9194bbd34 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/StringSequenceTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/StringSequenceTests.java @@ -203,4 +203,18 @@ class StringSequenceTests { assertThat(new StringSequence("xab").startsWith("c", 1)).isFalse(); } + @Test + void startsWithOnSubstringTailWhenMatch() { + StringSequence subSequence = new StringSequence("xabc").subSequence(1); + assertThat(subSequence.startsWith("abc")).isTrue(); + assertThat(subSequence.startsWith("abcd")).isFalse(); + } + + @Test + void startsWithOnSubstringMiddleWhenMatch() { + StringSequence subSequence = new StringSequence("xabc").subSequence(1, 3); + assertThat(subSequence.startsWith("ab")).isTrue(); + assertThat(subSequence.startsWith("abc")).isFalse(); + } + }