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

Simplify CodecCache #1018

Merged
merged 5 commits into from
Oct 18, 2022
Merged

Simplify CodecCache #1018

merged 5 commits into from
Oct 18, 2022

Conversation

stIncMale
Copy link
Member

@stIncMale stIncMale self-assigned this Oct 17, 2022
Copy link
Member

@rozza rozza left a comment

Choose a reason for hiding this comment

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

LGTM

Comment on lines -79 to -86
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;
}
Copy link
Member Author

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.

Comment on lines +118 to +130
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.')
}
}
Copy link
Member Author

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.

@jyemin jyemin self-requested a review October 18, 2022 14:38
Copy link
Collaborator

@jyemin jyemin left a comment

Choose a reason for hiding this comment

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

LGTM

Comment on lines +71 to +78
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);
Copy link
Member Author

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.

Copy link
Member Author

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.

Copy link
Member

@rozza rozza left a comment

Choose a reason for hiding this comment

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

Very nice - LGTM

Copy link
Collaborator

@jyemin jyemin left a 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.

@stIncMale
Copy link
Member Author

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.

Yes. While ConcurrentMap.computeIfAbsent does not have this restriction, ConcurrentHashMap.computeIfAbsent documents it.

@stIncMale stIncMale requested a review from jyemin October 18, 2022 15:46
@stIncMale stIncMale merged commit b1f4e3c into mongodb:master Oct 18, 2022
@stIncMale stIncMale deleted the JAVA-4751 branch October 18, 2022 16:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants