From ff8e8cfe88ddbdc0de3cf839a89e3cc1cb7530bc Mon Sep 17 00:00:00 2001 From: Toshiya Kobayashi Date: Wed, 18 Sep 2024 17:43:06 +0900 Subject: [PATCH] [incubator-kie-drools-6088] Performance issue with many kbase models and many large spreadsheets --- .../kie/builder/impl/AbstractKieProject.java | 7 ++++- .../kie/builder/impl/KieBuilderImpl.java | 26 ++++++++++++++----- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/AbstractKieProject.java b/drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/AbstractKieProject.java index 7775abacc43..6ae861d93b5 100644 --- a/drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/AbstractKieProject.java +++ b/drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/AbstractKieProject.java @@ -32,6 +32,7 @@ import org.drools.compiler.kproject.models.KieBaseModelImpl; import org.drools.compiler.kproject.models.KieModuleModelImpl; import org.drools.compiler.kproject.models.KieSessionModelImpl; +import org.drools.io.InternalResource; import org.drools.util.StringUtils; import org.kie.api.builder.Message; import org.kie.api.builder.model.KieBaseModel; @@ -65,6 +66,8 @@ public abstract class AbstractKieProject implements KieProject { private final Map kSessionModels = new HashMap<>(); + private Map packageNameCache = new HashMap<>(); + private static final Predicate BUILD_ALL = s -> true; public ResultsImpl verify() { @@ -83,6 +86,7 @@ public void verify(BuildContext buildContext) { for ( KieBaseModel model : kBaseModels.values() ) { buildKnowledgePackages((KieBaseModelImpl) model, buildContext); } + packageNameCache.clear(); } private void verify(String[] kBaseNames, BuildContext buildContext) { @@ -93,6 +97,7 @@ private void verify(String[] kBaseNames, BuildContext buildContext) { } buildKnowledgePackages( kieBaseModel, buildContext ); } + packageNameCache.clear(); } public KieBaseModel getDefaultKieBaseModel() { @@ -331,7 +336,7 @@ private void addFiles( Predicate buildFilter, Set assets, KieBase InternalKieModule kieModule, boolean useFolders) { for (String fileName : kieModule.getFileNames()) { if (buildFilter.test( fileName ) && !fileName.startsWith(".") && !fileName.endsWith(".properties") && - filterFileInKBase(kieModule, kieBaseModel, fileName, () -> kieModule.getResource( fileName ), useFolders)) { + filterFileInKBase(kieModule, kieBaseModel, fileName, () -> kieModule.getResource( fileName ), useFolders, packageNameCache)) { assets.add(new Asset( kieModule, fileName )); } } diff --git a/drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/KieBuilderImpl.java b/drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/KieBuilderImpl.java index ec1cb65533d..7245269a74b 100644 --- a/drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/KieBuilderImpl.java +++ b/drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/KieBuilderImpl.java @@ -23,8 +23,10 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.Enumeration; import java.util.List; +import java.util.Map; import java.util.function.BiFunction; import java.util.function.Predicate; import java.util.function.Supplier; @@ -363,7 +365,11 @@ private static ResourceType getResourceType( ResourceConfiguration conf ) { } public static boolean filterFileInKBase( InternalKieModule kieModule, KieBaseModel kieBase, String fileName, Supplier file, boolean useFolders ) { - return isFileInKieBase( kieBase, fileName, file, useFolders ) && + return filterFileInKBase(kieModule, kieBase, fileName, file, useFolders, null); + } + + public static boolean filterFileInKBase( InternalKieModule kieModule, KieBaseModel kieBase, String fileName, Supplier file, boolean useFolders, Map packageNameCache) { + return isFileInKieBase( kieBase, fileName, file, useFolders, packageNameCache ) && ( isKieExtension( fileName ) || getResourceType( kieModule, fileName ) != null ); } @@ -371,7 +377,7 @@ private static boolean isKieExtension(String fileName) { return !isJavaSourceFile( fileName ) && ResourceType.determineResourceType(fileName) != null; } - private static boolean isFileInKieBase( KieBaseModel kieBase, String fileName, Supplier file, boolean useFolders ) { + private static boolean isFileInKieBase( KieBaseModel kieBase, String fileName, Supplier file, boolean useFolders, Map packageNameCache ) { int lastSep = fileName.lastIndexOf( "/" ); if ( lastSep + 1 < fileName.length() && fileName.charAt( lastSep + 1 ) == '.' ) { // skip dot files @@ -381,15 +387,15 @@ private static boolean isFileInKieBase( KieBaseModel kieBase, String fileName, S return true; } else { String folderNameForFile = lastSep > 0 ? fileName.substring( 0, lastSep ) : ""; - String pkgNameForFile = packageNameForFile( fileName, folderNameForFile, !useFolders, file ); + String pkgNameForFile = packageNameForFile( fileName, folderNameForFile, !useFolders, file, packageNameCache ); return isPackageInKieBase( kieBase, pkgNameForFile ); } } - private static String packageNameForFile( String fileName, String folderNameForFile, boolean discoverPackage, Supplier file ) { + private static String packageNameForFile( String fileName, String folderNameForFile, boolean discoverPackage, Supplier file, Map packageNameCache ) { String packageNameFromFolder = getRelativePackageName(folderNameForFile.replace( '/', '.' )); if (discoverPackage) { - String packageNameForFile = packageNameFromAsset(fileName, file.get()); + String packageNameForFile = packageNameFromAsset(fileName, file.get(), packageNameCache); if (packageNameForFile != null) { packageNameForFile = getRelativePackageName( packageNameForFile ); if ( !packageNameForFile.equals( packageNameFromFolder ) ) { @@ -403,10 +409,18 @@ private static String packageNameForFile( String fileName, String folderNameForF return packageNameFromFolder; } - private static String packageNameFromAsset(String fileName, InternalResource file) { + private static String packageNameFromAsset(String fileName, InternalResource file, Map packageNameCache) { if (file == null) { return null; } + if (packageNameCache != null) { + return packageNameCache.computeIfAbsent(file, f -> packageNameFromAsset(fileName, f)); + } else { + return packageNameFromAsset(fileName, file); + } + } + + private static String packageNameFromAsset(String fileName, InternalResource file) { if (fileName.endsWith( ".drl" )) { return packageNameFromDrl( new String(file.getBytes()) ); }