From a19df45802206163c26ed32b85709d699356b995 Mon Sep 17 00:00:00 2001 From: lzxgyh Date: Thu, 28 Jul 2022 13:08:57 +0800 Subject: [PATCH] Improved "include" fix performance: optimized normalizePath method (#3063) fix performance issue: normalizePath super slow? #2221 and issue: Optimize updates #1856 --- .../changelog/DatabaseChangeLog.java | 36 +++++++++++-------- 1 file changed, 21 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 47be80514d8..f1a54bb5d12 100644 --- a/liquibase-core/src/main/java/liquibase/changelog/DatabaseChangeLog.java +++ b/liquibase-core/src/main/java/liquibase/changelog/DatabaseChangeLog.java @@ -26,6 +26,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. @@ -35,6 +37,15 @@ 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 Pattern SLASH_PATTERN = Pattern.compile("^/"); + 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("^\\.?/"); + private PreconditionContainer preconditionContainer = new GlobalPreconditionContainer(); private String physicalFilePath; private String logicalFilePath; @@ -131,10 +142,8 @@ public String getLogicalFilePath() { if (returnPath == null) { return null; } - - return returnPath - .replaceAll("\\\\", "/") - .replaceFirst("^/", ""); + String path = DOUBLE_BACK_SLASH_PATTERN.matcher(returnPath).replaceAll("/"); + return SLASH_PATTERN.matcher(path).replaceFirst(""); } public void setLogicalFilePath(String logicalFilePath) { @@ -645,11 +654,10 @@ public boolean include(String fileName, String relativeBaseFileName = this.getPhysicalFilePath(); if (isRelativePath) { - relativeBaseFileName = relativeBaseFileName.replaceFirst("classpath:", ""); + relativeBaseFileName = CLASSPATH_PATTERN.matcher(relativeBaseFileName).replaceFirst(""); fileName = FilenameUtil.concat(FilenameUtil.getDirectory(relativeBaseFileName), fileName); } - - fileName = fileName.replaceFirst("classpath:", ""); + fileName = CLASSPATH_PATTERN.matcher(fileName).replaceFirst(""); DatabaseChangeLog changeLog; try { DatabaseChangeLog rootChangeLog = ROOT_CHANGE_LOG.get(); @@ -723,14 +731,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 = 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() {