Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AVRO-4069: Remove Reader String Cache from Generic Datum Reader #3194

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ protected Object newMap(Object old, int size) {
* representation. By default, this calls {@link #readString(Object,Decoder)}.
*/
protected Object readString(Object old, Schema expected, Decoder in) throws IOException {
Class stringClass = this.getReaderCache().getStringClass(expected);
Class stringClass = this.findStringClass(expected);
if (stringClass == String.class) {
return in.readString();
}
Expand Down Expand Up @@ -490,12 +490,10 @@ protected Class findStringClass(Schema schema) {
if (name == null)
return CharSequence.class;

switch (GenericData.StringType.valueOf(name)) {
case String:
if (GenericData.StringType.String.name().equals(name)) {
return String.class;
default:
return CharSequence.class;
}
return CharSequence.class;
}

/**
Expand Down Expand Up @@ -529,14 +527,10 @@ public boolean equals(Object obj) {

// VisibleForTesting
static class ReaderCache {
private final Map<IdentitySchemaKey, Class> stringClassCache = new ConcurrentHashMap<>();

private final Map<Class, Function<String, Object>> stringCtorCache = new ConcurrentHashMap<>();
private final Map<Class, Function<String, Object>> stringCtorCache;

private final Function<Schema, Class> findStringClass;

public ReaderCache(Function<Schema, Class> findStringClass) {
this.findStringClass = findStringClass;
public ReaderCache() {
this.stringCtorCache = new ConcurrentHashMap<>();
}

public Object newInstanceFromString(Class c, String s) {
Expand All @@ -561,14 +555,9 @@ private Function<String, Object> buildFunction(Class c) {
}
};
}

public Class getStringClass(final Schema s) {
final IdentitySchemaKey key = new IdentitySchemaKey(s);
return this.stringClassCache.computeIfAbsent(key, (IdentitySchemaKey k) -> this.findStringClass.apply(k.schema));
}
}

private final ReaderCache readerCache = new ReaderCache(this::findStringClass);
private final ReaderCache readerCache = new ReaderCache();

// VisibleForTesting
ReaderCache getReaderCache() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import org.apache.avro.Schema;
import org.junit.jupiter.api.Test;
Expand All @@ -33,27 +31,9 @@ public class TestGenericDatumReader {

private static final Random r = new Random(System.currentTimeMillis());

@Test
void readerCache() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you delete the test ?
Looking at it I think it should still work. You just need to remove the ctor parameter.

final GenericDatumReader.ReaderCache cache = new GenericDatumReader.ReaderCache(this::findStringClass);
List<Thread> threads = IntStream.rangeClosed(1, 200).mapToObj((int index) -> {
final Schema schema = TestGenericDatumReader.this.build(index);
final WithSchema s = new WithSchema(schema, cache);
return (Runnable) () -> s.test();
}).map(Thread::new).collect(Collectors.toList());
threads.forEach(Thread::start);
threads.forEach((Thread t) -> {
try {
t.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
}

@Test
void newInstanceFromString() {
final GenericDatumReader.ReaderCache cache = new GenericDatumReader.ReaderCache(this::findStringClass);
final GenericDatumReader.ReaderCache cache = new GenericDatumReader.ReaderCache();

Object object = cache.newInstanceFromString(StringBuilder.class, "Hello");
assertEquals(StringBuilder.class, object.getClass());
Expand All @@ -62,21 +42,6 @@ void newInstanceFromString() {

}

static class WithSchema {
private final Schema schema;

private final GenericDatumReader.ReaderCache cache;

public WithSchema(Schema schema, GenericDatumReader.ReaderCache cache) {
this.schema = schema;
this.cache = cache;
}

public void test() {
this.cache.getStringClass(schema);
}
}

private List<Schema> list = new ArrayList<>();

private Schema build(int index) {
Expand Down
Loading