Skip to content

Commit 51fa201

Browse files
committed
rewrote parts of #219 (use separate cache key; isolate cache further), done now
1 parent abe5d1d commit 51fa201

File tree

1 file changed

+65
-32
lines changed

1 file changed

+65
-32
lines changed

avro/src/main/java/com/fasterxml/jackson/dataformat/avro/schema/AvroSchemaHelper.java

Lines changed: 65 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -348,43 +348,16 @@ public static String getFullName(Schema schema) {
348348
if (namespace.charAt(len-1) == '$') {
349349
return namespace + name;
350350
}
351-
return _findFullName(namespace, name);
351+
// 19-Sep-2020, tatu: Due to very expensive contortions of lookups introduced
352+
// in [dataformats-binary#195], attempts to resolve [dataformats-binary#219]
353+
// isolated into separate class
354+
return FullNameResolver.instance.resolve(namespace, name);
352355

353356
default:
354357
return type.getName();
355358
}
356359
}
357360

358-
private static String _findFullName(final String namespace, final String name) {
359-
final String cacheKey = namespace + "." + name;
360-
String schemaName = SCHEMA_NAME_CACHE.get(cacheKey);
361-
362-
if (schemaName == null) {
363-
schemaName = _resolveFullName(namespace, name);
364-
SCHEMA_NAME_CACHE.put(cacheKey, schemaName);
365-
}
366-
return schemaName;
367-
}
368-
369-
private static String _resolveFullName(final String namespace, final String name) {
370-
StringBuilder sb = new StringBuilder(1 + namespace.length() + name.length());
371-
372-
// 28-Feb-2020: [dataformats-binary#195] somewhat complicated logic of trying
373-
// to support differences between avro-lib 1.8 and 1.9...
374-
// Check if this is a nested class
375-
final String nestedClassName = sb.append(namespace).append('$').append(name).toString();
376-
try {
377-
Class.forName(nestedClassName);
378-
379-
return nestedClassName;
380-
} catch (ClassNotFoundException e) {
381-
// Could not find a nested class, must be a regular class
382-
sb.setLength(0);
383-
384-
return sb.append(namespace).append('.').append(name).toString();
385-
}
386-
}
387-
388361
public static JsonNode nullNode() {
389362
return DEFAULT_VALUE_MAPPER.nullNode();
390363
}
@@ -439,5 +412,65 @@ public static JsonNode parseDefaultValue(String defaultValue) throws JsonMapping
439412
}
440413

441414
// @since 2.11.3
442-
private static final LRUMap<String, String> SCHEMA_NAME_CACHE = new LRUMap<>(80, 800);
415+
private final static class FullNameResolver {
416+
private final LRUMap<FullNameKey, String> SCHEMA_NAME_CACHE = new LRUMap<>(80, 800);
417+
418+
public final static FullNameResolver instance = new FullNameResolver();
419+
420+
public String resolve(final String namespace, final String name) {
421+
final FullNameKey cacheKey = new FullNameKey(namespace, name);
422+
String schemaName = SCHEMA_NAME_CACHE.get(cacheKey);
423+
424+
if (schemaName == null) {
425+
schemaName = _resolve(cacheKey);
426+
SCHEMA_NAME_CACHE.put(cacheKey, schemaName);
427+
}
428+
return schemaName;
429+
}
430+
431+
private static String _resolve(FullNameKey key) {
432+
// 28-Feb-2020: [dataformats-binary#195] somewhat complicated logic of trying
433+
// to support differences between avro-lib 1.8 and 1.9...
434+
// Check if this is a nested class
435+
// 19-Sep-2020, tatu: This is a horrible, horribly inefficient and all-around
436+
// wrong mechanism. To be abolished if possible.
437+
final String nestedClassName = key.nameWithSeparator('$');
438+
try {
439+
Class.forName(nestedClassName);
440+
return nestedClassName;
441+
} catch (ClassNotFoundException e) {
442+
// Could not find a nested class, must be a regular class
443+
return key.nameWithSeparator('.');
444+
}
445+
}
446+
}
447+
448+
// @since 2.11.3
449+
private final static class FullNameKey {
450+
private final String _namespace, _name;
451+
private final int _hashCode;
452+
453+
public FullNameKey(String namespace, String name) {
454+
_namespace = namespace;
455+
_name = name;
456+
_hashCode = namespace.hashCode() + name.hashCode();
457+
}
458+
459+
public String nameWithSeparator(char sep) {
460+
final StringBuilder sb = new StringBuilder(1 + _namespace.length() + _name.length());
461+
return sb.append(_namespace).append(sep).append(_name).toString();
462+
}
463+
464+
@Override
465+
public int hashCode() { return _hashCode; }
466+
467+
@Override
468+
public boolean equals(Object o) {
469+
if (o == this) return true;
470+
if (o == null) return false;
471+
// Only used internally don't bother with type checks
472+
final FullNameKey other = (FullNameKey) o;
473+
return other._name.equals(_name) && other._namespace.equals(_namespace);
474+
}
475+
}
443476
}

0 commit comments

Comments
 (0)