-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Simplify CodecCache
#1018
Simplify CodecCache
#1018
Conversation
JAVA-4751
JAVA-4751
JAVA-4751
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
public synchronized <T> Codec<T> putIfMissing(final CodecCacheKey codecCacheKey, final Codec<T> codec) { | ||
Optional<Codec<?>> cachedCodec = codecCache.computeIfAbsent(codecCacheKey, clz -> Optional.of(codec)); | ||
if (cachedCodec.isPresent()) { | ||
return (Codec<T>) cachedCodec.get(); | ||
} | ||
codecCache.put(codecCacheKey, Optional.of(codec)); | ||
return codec; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of improving this method as I originally described here, I did more changes, further simplifying the cache. Before this PR we were caching failures of finding a codec as Optional.empty()
values just for the sake of throwing an exception faster if asked for the same codec again. I see no point in trying to optimize that path.
def codec = Mock(Codec) | ||
def provider = new CodecProvider() { | ||
private int counter = 0 | ||
|
||
@Override | ||
Codec get(final Class clazz, final CodecRegistry registry) { | ||
if (counter == 0) { | ||
counter++ | ||
return codec | ||
} | ||
throw new AssertionError((Object)'Must not be called more than once.') | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some reason, I failed to use Spock stubbing here (the stabbed provider
works as expected if used directly from the test, but does not work when used via registry
. So I had to stub the object manually.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
return codecCache.<T>get(codecCacheKey).orElseGet(() -> { | ||
for (CodecProvider provider : codecProviders) { | ||
Codec<T> codec = provider.get(context.getCodecClass(), context); | ||
if (codec != null) { | ||
if (codec instanceof Parameterizable && context.getTypes().isPresent()) { | ||
codec = (Codec<T>) ((Parameterizable) codec).parameterize(context, context.getTypes().get()); | ||
} | ||
return codecCache.putIfMissing(codecCacheKey, codec); | ||
return codecCache.putIfAbsent(codecCacheKey, codec); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have just realized that this whole thing can and should be done as a single compute
. Will do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Turns out, IllegalStateException: Recursive update
is a thing despite the map being concurrent :( Well, we can't have all the good things.
JAVA-4751
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice - LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you're going to have to revert the last commit as many tests are failing with a "recursive update" exception thrown by ConcurrentHashMap.
This reverts commit 12528a8.
Yes. While |
JAVA-4751