Skip to content

Commit

Permalink
Cache CClassType.get(Class)
Browse files Browse the repository at this point in the history
Improves runtime performance of type checking functions.
  • Loading branch information
Pieter12345 committed Nov 11, 2023
1 parent 7893dbf commit 64deb06
Showing 1 changed file with 26 additions and 17 deletions.
43 changes: 26 additions & 17 deletions src/main/java/com/laytonsmith/core/constructs/CClassType.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ public final class CClassType extends Construct implements com.laytonsmith.core.

public static final String PATH_SEPARATOR = FullyQualifiedClassName.PATH_SEPARATOR;

private static final Map<FullyQualifiedClassName, CClassType> CACHE = new HashMap<>();
private static final Map<FullyQualifiedClassName, CClassType> FQCN_CCLASSTYPE_CACHE = new HashMap<>();
private static final Map<Class<? extends Mixed>, CClassType> CLASS_CCLASSTYPE_CACHE = new HashMap<>();

// The only types that can be created here are the ones that don't have a real class associated with them, or the
// TYPE value itself
Expand Down Expand Up @@ -68,7 +69,7 @@ public final class CClassType extends Construct implements com.laytonsmith.core.
public static final CClassType[] EMPTY_CLASS_ARRAY = new CClassType[0];

static {
CACHE.put(FullyQualifiedClassName.forNativeClass(CClassType.class), TYPE);
FQCN_CCLASSTYPE_CACHE.put(FullyQualifiedClassName.forNativeClass(CClassType.class), TYPE);
}

private final boolean isTypeUnion;
Expand Down Expand Up @@ -112,13 +113,21 @@ public final class CClassType extends Construct implements com.laytonsmith.core.
* @return
*/
public static CClassType get(Class<? extends Mixed> type) {
try {
CClassType t = get(FullyQualifiedClassName.forNativeClass(type));
t.nativeClass = type;
return t;
} catch (ClassNotFoundException ex) {
throw new Error(ex);

// Get cached result or compute and cache result.
CClassType cclassType = CLASS_CCLASSTYPE_CACHE.get(type);
if(cclassType == null) {
try {
cclassType = get(FullyQualifiedClassName.forNativeClass(type));
cclassType.nativeClass = type;
} catch (ClassNotFoundException ex) {
throw new Error(ex);
}
CLASS_CCLASSTYPE_CACHE.put(type, cclassType);
}

// Return the result.
return cclassType;
}

/**
Expand All @@ -129,13 +138,13 @@ public static CClassType get(Class<? extends Mixed> type) {
*/
public static CClassType get(FullyQualifiedClassName type) throws ClassNotFoundException {
assert type != null;
CClassType ctype = CACHE.get(type);
CClassType ctype = FQCN_CCLASSTYPE_CACHE.get(type);
if(ctype == null) {
synchronized(CACHE) {
ctype = CACHE.get(type);
synchronized(FQCN_CCLASSTYPE_CACHE) {
ctype = FQCN_CCLASSTYPE_CACHE.get(type);
if(ctype == null) {
ctype = new CClassType(type, Target.UNKNOWN, false);
CACHE.put(type, ctype);
FQCN_CCLASSTYPE_CACHE.put(type, ctype);
}
}
}
Expand All @@ -157,13 +166,13 @@ public static CClassType get(FullyQualifiedClassName... types) throws ClassNotFo
SortedSet<FullyQualifiedClassName> t = new TreeSet<>(Arrays.asList(types));
FullyQualifiedClassName type
= FullyQualifiedClassName.forFullyQualifiedClass(StringUtils.Join(t, "|", e -> e.getFQCN()));
CClassType ctype = CACHE.get(type);
CClassType ctype = FQCN_CCLASSTYPE_CACHE.get(type);
if(ctype == null) {
synchronized(CACHE) {
ctype = CACHE.get(type);
synchronized(FQCN_CCLASSTYPE_CACHE) {
ctype = FQCN_CCLASSTYPE_CACHE.get(type);
if(ctype == null) {
ctype = new CClassType(type, Target.UNKNOWN, false);
CACHE.put(type, ctype);
FQCN_CCLASSTYPE_CACHE.put(type, ctype);
}
}
}
Expand Down Expand Up @@ -195,7 +204,7 @@ public static CClassType get(CClassType... types) throws ClassNotFoundException
public static CClassType defineClass(FullyQualifiedClassName fqcn) {
try {
CClassType type = new CClassType(fqcn, Target.UNKNOWN, true);
CACHE.put(fqcn, type);
FQCN_CCLASSTYPE_CACHE.put(fqcn, type);
return type;
} catch (ClassNotFoundException ex) {
throw new Error(ex);
Expand Down

0 comments on commit 64deb06

Please sign in to comment.