HHH-13028 Make ASTPrinter caches use less memory

This commit is contained in:
Sanne Grinovero 2018-10-12 22:06:12 +01:00
parent 109085cab8
commit e3ae85f8c1
2 changed files with 21 additions and 11 deletions

View File

@ -25,9 +25,11 @@ import antlr.collections.AST;
* @author Joshua Davis * @author Joshua Davis
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class ASTPrinter { public final class ASTPrinter {
private final Map<Integer,String> tokenTypeNameCache; // This is a map: array index is the ANTLR Token ID, array value is the name of that token.
// There might be gaps in the array (null values) but it's generally quite compact.
private final String[] tokenTypeNameCache;
/** /**
* Constructs a printer. Package protected: use the constants from {TokenPrinters} * Constructs a printer. Package protected: use the constants from {TokenPrinters}
@ -88,10 +90,9 @@ public class ASTPrinter {
* or just the integer as a string if none exists. * or just the integer as a string if none exists.
*/ */
public String getTokenTypeName(int type) { public String getTokenTypeName(int type) {
final Integer typeInteger = type; String value = tokenTypeNameCache[type];
String value = tokenTypeNameCache.get( typeInteger );
if ( value == null ) { if ( value == null ) {
value = typeInteger.toString(); value = Integer.toString( type );
} }
return value; return value;
} }

View File

@ -13,6 +13,8 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.hibernate.HibernateError;
import antlr.ASTFactory; import antlr.ASTFactory;
import antlr.collections.AST; import antlr.collections.AST;
import antlr.collections.impl.ASTArray; import antlr.collections.impl.ASTArray;
@ -387,21 +389,28 @@ public final class ASTUtil {
* *
* @param tokenTypeInterface The *TokenTypes interface (or implementor of said interface). * @param tokenTypeInterface The *TokenTypes interface (or implementor of said interface).
* *
* @return The generated map. * @return A compact map int -> tokenName in array format
*/ */
public static Map<Integer,String> generateTokenNameCache(Class tokenTypeInterface) { public static String[] generateTokenNameCache(Class tokenTypeInterface) {
final Field[] fields = tokenTypeInterface.getFields(); final Field[] fields = tokenTypeInterface.getFields();
Map cache = new HashMap( (int) ( fields.length * .75 ) + 1 ); //We try to guess the right size from what we know ANTLR will do;
//"guessing" is safe as the three interfaces this is used on are static,
//and this is all run at boot so at worst would fail fast.
final String[] names = new String[ fields.length + 2 ];
for ( final Field field : fields ) { for ( final Field field : fields ) {
if ( Modifier.isStatic( field.getModifiers() ) ) { if ( Modifier.isStatic( field.getModifiers() ) ) {
int idx = 0;
try { try {
cache.put( Integer.valueOf( field.getInt( null ) ), field.getName() ); idx = field.getInt( null );
} }
catch (Throwable ignore) { catch (IllegalAccessException e) {
throw new HibernateError( "Initialization error", e );
}
String fieldName = field.getName();
names[idx] = fieldName;
} }
} }
} return names;
return cache;
} }
/** /**