HHH-11495 Reduce criteria overhead by adding an implementors cache

This commit is contained in:
Carlos Aristu 2018-06-29 12:15:47 +02:00 committed by Guillaume Smet
parent 35cd3a1c38
commit 9684afda76
1 changed files with 52 additions and 45 deletions

View File

@ -111,6 +111,8 @@ public class MetamodelImpl implements MetamodelImplementor, Serializable {
private final TypeConfiguration typeConfiguration;
private final Map<String, String[]> implementorsCache = new ConcurrentHashMap<>();
public MetamodelImpl(SessionFactoryImplementor sessionFactory, TypeConfiguration typeConfiguration) {
this.sessionFactory = sessionFactory;
this.typeConfiguration = typeConfiguration;
@ -622,51 +624,7 @@ public class MetamodelImpl implements MetamodelImplementor, Serializable {
* @throws MappingException
*/
public String[] getImplementors(String className) throws MappingException {
final Class clazz;
try {
clazz = getSessionFactory().getServiceRegistry().getService( ClassLoaderService.class ).classForName( className );
}
catch (ClassLoadingException e) {
return new String[] { className }; //for a dynamic-class
}
ArrayList<String> results = new ArrayList<>();
for ( EntityPersister checkPersister : entityPersisters().values() ) {
if ( ! Queryable.class.isInstance( checkPersister ) ) {
continue;
}
final Queryable checkQueryable = Queryable.class.cast( checkPersister );
final String checkQueryableEntityName = checkQueryable.getEntityName();
final boolean isMappedClass = className.equals( checkQueryableEntityName );
if ( checkQueryable.isExplicitPolymorphism() ) {
if ( isMappedClass ) {
return new String[] { className }; //NOTE EARLY EXIT
}
}
else {
if ( isMappedClass ) {
results.add( checkQueryableEntityName );
}
else {
final Class mappedClass = checkQueryable.getMappedClass();
if ( mappedClass != null && clazz.isAssignableFrom( mappedClass ) ) {
final boolean assignableSuperclass;
if ( checkQueryable.isInherited() ) {
Class mappedSuperclass = entityPersister( checkQueryable.getMappedSuperclass() ).getMappedClass();
assignableSuperclass = clazz.isAssignableFrom( mappedSuperclass );
}
else {
assignableSuperclass = false;
}
if ( !assignableSuperclass ) {
results.add( checkQueryableEntityName );
}
}
}
}
}
return results.toArray( new String[results.size()] );
return implementorsCache.computeIfAbsent( className, this::doGetImplementors );
}
@Override
@ -789,4 +747,53 @@ public class MetamodelImpl implements MetamodelImplementor, Serializable {
public void close() {
// anything to do ?
}
private String[] doGetImplementors(String className) throws MappingException {
final Class<?> clazz;
try {
clazz = getSessionFactory().getServiceRegistry().getService( ClassLoaderService.class ).classForName( className );
}
catch (ClassLoadingException e) {
return new String[]{ className }; //for a dynamic-class
}
ArrayList<String> results = new ArrayList<>();
for ( EntityPersister checkPersister : entityPersisters().values() ) {
if ( !Queryable.class.isInstance( checkPersister ) ) {
continue;
}
final Queryable checkQueryable = Queryable.class.cast( checkPersister );
final String checkQueryableEntityName = checkQueryable.getEntityName();
final boolean isMappedClass = className.equals( checkQueryableEntityName );
if ( checkQueryable.isExplicitPolymorphism() ) {
if ( isMappedClass ) {
return new String[]{ className }; // NOTE EARLY EXIT
}
}
else {
if ( isMappedClass ) {
results.add( checkQueryableEntityName );
}
else {
final Class<?> mappedClass = checkQueryable.getMappedClass();
if ( mappedClass != null && clazz.isAssignableFrom( mappedClass ) ) {
final boolean assignableSuperclass;
if ( checkQueryable.isInherited() ) {
Class<?> mappedSuperclass = entityPersister( checkQueryable.getMappedSuperclass() ).getMappedClass();
assignableSuperclass = clazz.isAssignableFrom( mappedSuperclass );
}
else {
assignableSuperclass = false;
}
if ( !assignableSuperclass ) {
results.add( checkQueryableEntityName );
}
}
}
}
}
return results.toArray( new String[results.size()] );
}
}