From e3ae85f8c1d98e3ac90599e5ceac94eb66c234e1 Mon Sep 17 00:00:00 2001 From: Sanne Grinovero Date: Fri, 12 Oct 2018 22:06:12 +0100 Subject: [PATCH] HHH-13028 Make ASTPrinter caches use less memory --- .../hql/internal/ast/util/ASTPrinter.java | 11 +++++----- .../hql/internal/ast/util/ASTUtil.java | 21 +++++++++++++------ 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/util/ASTPrinter.java b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/util/ASTPrinter.java index fb32e58f4a..a9ed6538ca 100644 --- a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/util/ASTPrinter.java +++ b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/util/ASTPrinter.java @@ -25,9 +25,11 @@ import antlr.collections.AST; * @author Joshua Davis * @author Steve Ebersole */ -public class ASTPrinter { +public final class ASTPrinter { - private final Map 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; } diff --git a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/util/ASTUtil.java b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/util/ASTUtil.java index 15e5af195a..3da4f0af12 100644 --- a/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/util/ASTUtil.java +++ b/hibernate-core/src/main/java/org/hibernate/hql/internal/ast/util/ASTUtil.java @@ -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 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; } /**