From 350b1cad88ff4c16b8c2c8521e827f9724788c60 Mon Sep 17 00:00:00 2001 From: lzxgyh Date: Thu, 14 Jul 2022 23:25:44 +0800 Subject: [PATCH 1/2] fix performance issue: normalizePath super slow? #2221 and issue: Optimize updates #1856 --- .../changelog/DatabaseChangeLog.java | 48 +++++++++++++------ 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/liquibase-core/src/main/java/liquibase/changelog/DatabaseChangeLog.java b/liquibase-core/src/main/java/liquibase/changelog/DatabaseChangeLog.java index d51e3512483..71b4198cebf 100644 --- a/liquibase-core/src/main/java/liquibase/changelog/DatabaseChangeLog.java +++ b/liquibase-core/src/main/java/liquibase/changelog/DatabaseChangeLog.java @@ -25,6 +25,8 @@ import java.io.IOException; import java.io.InputStream; import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Encapsulates the information stored in the change log XML file. @@ -34,6 +36,27 @@ public class DatabaseChangeLog implements Comparable, Conditi private static final ThreadLocal PARENT_CHANGE_LOG = new ThreadLocal<>(); private static final Logger LOG = Scope.getCurrentScope().getLog(DatabaseChangeLog.class); + public static final Pattern CLASSPATH_PATTERN = Pattern.compile("classpath:"); + public static final Matcher CLASSPATH_MATCHER = CLASSPATH_PATTERN.matcher(""); + public static final Pattern SLASH_PATTERN = Pattern.compile("^/"); + public static final Matcher SLASH_MATCHER = SLASH_PATTERN.matcher(""); + + + + public static final Pattern NON_CLASSPATH_PATTERN = Pattern.compile("^classpath:"); + public static final Pattern DOUBLE_BACK_SLASH_PATTERN = Pattern.compile("\\\\"); + public static final Pattern DOUBLE_SLASH_PATTERN = Pattern.compile("//+"); + public static final Pattern SLASH_DOT_SLASH_PATTERN = Pattern.compile("/\\./"); + public static final Pattern NO_LETTER_PATTERN = Pattern.compile("^[a-zA-Z]:"); + public static final Pattern DOT_SLASH_PATTERN = Pattern.compile("^\\.?/"); + + public static final Matcher NO_CLASSPATH_MATCHER = NON_CLASSPATH_PATTERN.matcher(""); + public static final Matcher DOUBLE_BACK_SLASH_MATCHER = DOUBLE_BACK_SLASH_PATTERN.matcher(""); + public static final Matcher DOUBLE_SLASH_MATCHER = DOUBLE_SLASH_PATTERN.matcher(""); + public static final Matcher SLASH_DOT_SLASH_MATCHER = SLASH_DOT_SLASH_PATTERN.matcher(""); + public static final Matcher NO_LETTER_MATCHER = NO_LETTER_PATTERN.matcher(""); + public static final Matcher DOT_SLASH_MATCHER = DOT_SLASH_PATTERN.matcher(""); + private PreconditionContainer preconditionContainer = new GlobalPreconditionContainer(); private String physicalFilePath; private String logicalFilePath; @@ -130,10 +153,8 @@ public String getLogicalFilePath() { if (returnPath == null) { return null; } - - return returnPath - .replaceAll("\\\\", "/") - .replaceFirst("^/", ""); + String path = DOUBLE_BACK_SLASH_MATCHER.reset(returnPath).replaceAll("/"); + return SLASH_MATCHER.reset(path).replaceFirst(""); } public void setLogicalFilePath(String logicalFilePath) { @@ -647,11 +668,10 @@ public boolean include(String fileName, String relativeBaseFileName = this.getPhysicalFilePath(); if (isRelativePath) { - relativeBaseFileName = relativeBaseFileName.replaceFirst("classpath:", ""); + relativeBaseFileName = CLASSPATH_MATCHER.reset(relativeBaseFileName).replaceFirst(""); fileName = FilenameUtil.concat(FilenameUtil.getDirectory(relativeBaseFileName), fileName); } - - fileName = fileName.replaceFirst("classpath:", ""); + fileName = CLASSPATH_MATCHER.reset(fileName).replaceFirst(""); DatabaseChangeLog changeLog; try { DatabaseChangeLog rootChangeLog = ROOT_CHANGE_LOG.get(); @@ -725,14 +745,12 @@ public static String normalizePath(String filePath) { if (filePath == null) { return null; } - return filePath.replaceFirst("^classpath:", "") - .replaceAll("\\\\", "/") - .replaceAll("//+", "/") - .replaceAll("/\\./", "/") - .replaceFirst("^[a-zA-Z]:", "") - .replaceFirst("^\\.?/", "") - ; - + String noClassPathReplaced = NO_CLASSPATH_MATCHER.reset(filePath).replaceFirst(""); + String doubleBackSlashReplaced = DOUBLE_BACK_SLASH_MATCHER.reset(noClassPathReplaced).replaceAll("/"); + String doubleSlashReplaced = DOUBLE_SLASH_MATCHER.reset(doubleBackSlashReplaced).replaceAll("/"); + String slashDotSlashReplaced =SLASH_DOT_SLASH_MATCHER.reset(doubleSlashReplaced).replaceAll("/"); + String noLetterReplaced = NO_LETTER_MATCHER.reset(slashDotSlashReplaced).replaceFirst(""); + return DOT_SLASH_MATCHER.reset(noLetterReplaced).replaceFirst(""); } public void clearCheckSums() { From 1eaaac95c0b57f0f336bfe9c723da440fb0ca7ff Mon Sep 17 00:00:00 2001 From: lzxgyh Date: Sat, 16 Jul 2022 14:02:37 +0800 Subject: [PATCH 2/2] remove matcher static variables --- .../changelog/DatabaseChangeLog.java | 32 ++++++------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/liquibase-core/src/main/java/liquibase/changelog/DatabaseChangeLog.java b/liquibase-core/src/main/java/liquibase/changelog/DatabaseChangeLog.java index 71b4198cebf..5f90fe810fe 100644 --- a/liquibase-core/src/main/java/liquibase/changelog/DatabaseChangeLog.java +++ b/liquibase-core/src/main/java/liquibase/changelog/DatabaseChangeLog.java @@ -37,12 +37,7 @@ public class DatabaseChangeLog implements Comparable, Conditi private static final Logger LOG = Scope.getCurrentScope().getLog(DatabaseChangeLog.class); public static final Pattern CLASSPATH_PATTERN = Pattern.compile("classpath:"); - public static final Matcher CLASSPATH_MATCHER = CLASSPATH_PATTERN.matcher(""); public static final Pattern SLASH_PATTERN = Pattern.compile("^/"); - public static final Matcher SLASH_MATCHER = SLASH_PATTERN.matcher(""); - - - public static final Pattern NON_CLASSPATH_PATTERN = Pattern.compile("^classpath:"); public static final Pattern DOUBLE_BACK_SLASH_PATTERN = Pattern.compile("\\\\"); public static final Pattern DOUBLE_SLASH_PATTERN = Pattern.compile("//+"); @@ -50,13 +45,6 @@ public class DatabaseChangeLog implements Comparable, Conditi public static final Pattern NO_LETTER_PATTERN = Pattern.compile("^[a-zA-Z]:"); public static final Pattern DOT_SLASH_PATTERN = Pattern.compile("^\\.?/"); - public static final Matcher NO_CLASSPATH_MATCHER = NON_CLASSPATH_PATTERN.matcher(""); - public static final Matcher DOUBLE_BACK_SLASH_MATCHER = DOUBLE_BACK_SLASH_PATTERN.matcher(""); - public static final Matcher DOUBLE_SLASH_MATCHER = DOUBLE_SLASH_PATTERN.matcher(""); - public static final Matcher SLASH_DOT_SLASH_MATCHER = SLASH_DOT_SLASH_PATTERN.matcher(""); - public static final Matcher NO_LETTER_MATCHER = NO_LETTER_PATTERN.matcher(""); - public static final Matcher DOT_SLASH_MATCHER = DOT_SLASH_PATTERN.matcher(""); - private PreconditionContainer preconditionContainer = new GlobalPreconditionContainer(); private String physicalFilePath; private String logicalFilePath; @@ -153,8 +141,8 @@ public String getLogicalFilePath() { if (returnPath == null) { return null; } - String path = DOUBLE_BACK_SLASH_MATCHER.reset(returnPath).replaceAll("/"); - return SLASH_MATCHER.reset(path).replaceFirst(""); + String path = DOUBLE_BACK_SLASH_PATTERN.matcher(returnPath).replaceAll("/"); + return SLASH_PATTERN.matcher(path).replaceFirst(""); } public void setLogicalFilePath(String logicalFilePath) { @@ -668,10 +656,10 @@ public boolean include(String fileName, String relativeBaseFileName = this.getPhysicalFilePath(); if (isRelativePath) { - relativeBaseFileName = CLASSPATH_MATCHER.reset(relativeBaseFileName).replaceFirst(""); + relativeBaseFileName = CLASSPATH_PATTERN.matcher(relativeBaseFileName).replaceFirst(""); fileName = FilenameUtil.concat(FilenameUtil.getDirectory(relativeBaseFileName), fileName); } - fileName = CLASSPATH_MATCHER.reset(fileName).replaceFirst(""); + fileName = CLASSPATH_PATTERN.matcher(fileName).replaceFirst(""); DatabaseChangeLog changeLog; try { DatabaseChangeLog rootChangeLog = ROOT_CHANGE_LOG.get(); @@ -745,12 +733,12 @@ public static String normalizePath(String filePath) { if (filePath == null) { return null; } - String noClassPathReplaced = NO_CLASSPATH_MATCHER.reset(filePath).replaceFirst(""); - String doubleBackSlashReplaced = DOUBLE_BACK_SLASH_MATCHER.reset(noClassPathReplaced).replaceAll("/"); - String doubleSlashReplaced = DOUBLE_SLASH_MATCHER.reset(doubleBackSlashReplaced).replaceAll("/"); - String slashDotSlashReplaced =SLASH_DOT_SLASH_MATCHER.reset(doubleSlashReplaced).replaceAll("/"); - String noLetterReplaced = NO_LETTER_MATCHER.reset(slashDotSlashReplaced).replaceFirst(""); - return DOT_SLASH_MATCHER.reset(noLetterReplaced).replaceFirst(""); + String noClassPathReplaced = NON_CLASSPATH_PATTERN.matcher(filePath).replaceFirst(""); + String doubleBackSlashReplaced = DOUBLE_BACK_SLASH_PATTERN.matcher(noClassPathReplaced).replaceAll("/"); + String doubleSlashReplaced = DOUBLE_SLASH_PATTERN.matcher(doubleBackSlashReplaced).replaceAll("/"); + String slashDotSlashReplaced =SLASH_DOT_SLASH_PATTERN.matcher(doubleSlashReplaced).replaceAll("/"); + String noLetterReplaced = NO_LETTER_PATTERN.matcher(slashDotSlashReplaced).replaceFirst(""); + return DOT_SLASH_PATTERN.matcher(noLetterReplaced).replaceFirst(""); } public void clearCheckSums() {