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 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}
@ -88,10 +90,9 @@ public class ASTPrinter {
* or just the integer as a string if none exists.
*/
public String getTokenTypeName(int type) {
final Integer typeInteger = type;
String value = tokenTypeNameCache.get( typeInteger );
String value = tokenTypeNameCache[type];
if ( value == null ) {
value = typeInteger.toString();
value = Integer.toString( type );
}
return value;
}

View File

@ -13,6 +13,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.hibernate.HibernateError;
import antlr.ASTFactory;
import antlr.collections.AST;
import antlr.collections.impl.ASTArray;
@ -387,21 +389,28 @@ public final class ASTUtil {
*
* @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();
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 ) {
if ( Modifier.isStatic( field.getModifiers() ) ) {
int idx = 0;
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 cache;
return names;
}
/**