@@ -337,43 +337,16 @@ public static String getFullName(Schema schema) {
337337 if (namespace .charAt (len -1 ) == '$' ) {
338338 return namespace + name ;
339339 }
340- return _findFullName (namespace , name );
340+ // 19-Sep-2020, tatu: Due to very expensive contortions of lookups introduced
341+ // in [dataformats-binary#195], attempts to resolve [dataformats-binary#219]
342+ // isolated into separate class
343+ return FullNameResolver .instance .resolve (namespace , name );
341344
342345 default :
343346 return type .getName ();
344347 }
345348 }
346349
347- private static String _findFullName (final String namespace , final String name ) {
348- final String cacheKey = namespace + "." + name ;
349- String schemaName = SCHEMA_NAME_CACHE .get (cacheKey );
350-
351- if (schemaName == null ) {
352- schemaName = _resolveFullName (namespace , name );
353- SCHEMA_NAME_CACHE .put (cacheKey , schemaName );
354- }
355- return schemaName ;
356- }
357-
358- private static String _resolveFullName (final String namespace , final String name ) {
359- StringBuilder sb = new StringBuilder (1 + namespace .length () + name .length ());
360-
361- // 28-Feb-2020: [dataformats-binary#195] somewhat complicated logic of trying
362- // to support differences between avro-lib 1.8 and 1.9...
363- // Check if this is a nested class
364- final String nestedClassName = sb .append (namespace ).append ('$' ).append (name ).toString ();
365- try {
366- Class .forName (nestedClassName );
367-
368- return nestedClassName ;
369- } catch (ClassNotFoundException e ) {
370- // Could not find a nested class, must be a regular class
371- sb .setLength (0 );
372-
373- return sb .append (namespace ).append ('.' ).append (name ).toString ();
374- }
375- }
376-
377350 public static JsonNode nullNode () {
378351 return DEFAULT_VALUE_MAPPER .nullNode ();
379352 }
@@ -416,6 +389,64 @@ public static JsonNode parseDefaultValue(String defaultValue) throws JsonMapping
416389 }
417390 }
418391
419- // @since 2.11.3
420- private static final SimpleLookupCache <String , String > SCHEMA_NAME_CACHE = new SimpleLookupCache <>(80 , 800 );
392+ private final static class FullNameResolver {
393+ private final SimpleLookupCache <FullNameKey , String > SCHEMA_NAME_CACHE = new SimpleLookupCache <>(80 , 800 );
394+
395+ public final static FullNameResolver instance = new FullNameResolver ();
396+
397+ public String resolve (final String namespace , final String name ) {
398+ final FullNameKey cacheKey = new FullNameKey (namespace , name );
399+ String schemaName = SCHEMA_NAME_CACHE .get (cacheKey );
400+
401+ if (schemaName == null ) {
402+ schemaName = _resolve (cacheKey );
403+ SCHEMA_NAME_CACHE .put (cacheKey , schemaName );
404+ }
405+ return schemaName ;
406+ }
407+
408+ private static String _resolve (FullNameKey key ) {
409+ // 28-Feb-2020: [dataformats-binary#195] somewhat complicated logic of trying
410+ // to support differences between avro-lib 1.8 and 1.9...
411+ // Check if this is a nested class
412+ // 19-Sep-2020, tatu: This is a horrible, horribly inefficient and all-around
413+ // wrong mechanism. To be abolished if possible.
414+ final String nestedClassName = key .nameWithSeparator ('$' );
415+ try {
416+ Class .forName (nestedClassName );
417+ return nestedClassName ;
418+ } catch (ClassNotFoundException e ) {
419+ // Could not find a nested class, must be a regular class
420+ return key .nameWithSeparator ('.' );
421+ }
422+ }
423+ }
424+
425+ private final static class FullNameKey {
426+ private final String _namespace , _name ;
427+ private final int _hashCode ;
428+
429+ public FullNameKey (String namespace , String name ) {
430+ _namespace = namespace ;
431+ _name = name ;
432+ _hashCode = namespace .hashCode () + name .hashCode ();
433+ }
434+
435+ public String nameWithSeparator (char sep ) {
436+ final StringBuilder sb = new StringBuilder (1 + _namespace .length () + _name .length ());
437+ return sb .append (_namespace ).append (sep ).append (_name ).toString ();
438+ }
439+
440+ @ Override
441+ public int hashCode () { return _hashCode ; }
442+
443+ @ Override
444+ public boolean equals (Object o ) {
445+ if (o == this ) return true ;
446+ if (o == null ) return false ;
447+ // Only used internally don't bother with type checks
448+ final FullNameKey other = (FullNameKey ) o ;
449+ return other ._name .equals (_name ) && other ._namespace .equals (_namespace );
450+ }
451+ }
421452}
0 commit comments