|
21 | 21 | import org.bson.codecs.configuration.CodecConfigurationException;
|
22 | 22 | import org.bson.codecs.configuration.CodecProvider;
|
23 | 23 | import org.bson.codecs.configuration.CodecRegistry;
|
24 |
| -import org.bson.internal.CodecCache.CodecCacheKey; |
25 | 24 |
|
26 | 25 | import java.lang.reflect.Type;
|
27 | 26 | import java.util.ArrayList;
|
28 | 27 | import java.util.List;
|
| 28 | +import java.util.Objects; |
| 29 | +import java.util.concurrent.ConcurrentHashMap; |
| 30 | +import java.util.concurrent.ConcurrentMap; |
29 | 31 |
|
30 | 32 | import static java.lang.String.format;
|
31 | 33 | import static org.bson.assertions.Assertions.isTrueArgument;
|
32 | 34 | import static org.bson.assertions.Assertions.notNull;
|
33 | 35 |
|
34 | 36 | public final class ProvidersCodecRegistry implements CycleDetectingCodecRegistry {
|
35 | 37 | private final List<CodecProvider> codecProviders;
|
36 |
| - private final CodecCache codecCache = new CodecCache(); |
| 38 | + private final ConcurrentMap<CodecCacheKey, Codec<?>> codecCache = new ConcurrentHashMap<>(); |
37 | 39 |
|
38 | 40 | public ProvidersCodecRegistry(final List<? extends CodecProvider> codecProviders) {
|
39 | 41 | isTrueArgument("codecProviders must not be null or empty", codecProviders != null && codecProviders.size() > 0);
|
@@ -68,17 +70,17 @@ public <T> Codec<T> get(final Class<T> clazz, final CodecRegistry registry) {
|
68 | 70 | @SuppressWarnings({"unchecked"})
|
69 | 71 | public <T> Codec<T> get(final ChildCodecRegistry<T> context) {
|
70 | 72 | CodecCacheKey codecCacheKey = new CodecCacheKey(context.getCodecClass(), context.getTypes().orElse(null));
|
71 |
| - return codecCache.<T>get(codecCacheKey).orElseGet(() -> { |
| 73 | + return (Codec<T>) codecCache.computeIfAbsent(codecCacheKey, k -> { |
72 | 74 | for (CodecProvider provider : codecProviders) {
|
73 |
| - Codec<T> codec = provider.get(context.getCodecClass(), context); |
| 75 | + Codec<?> codec = provider.get(context.getCodecClass(), context); |
74 | 76 | if (codec != null) {
|
75 | 77 | if (codec instanceof Parameterizable && context.getTypes().isPresent()) {
|
76 |
| - codec = (Codec<T>) ((Parameterizable) codec).parameterize(context, context.getTypes().get()); |
| 78 | + codec = ((Parameterizable) codec).parameterize(context, context.getTypes().get()); |
77 | 79 | }
|
78 |
| - return codecCache.putIfAbsent(codecCacheKey, codec); |
| 80 | + return codec; |
79 | 81 | }
|
80 | 82 | }
|
81 |
| - throw new CodecConfigurationException(format("Can't find a codec for %s.", codecCacheKey)); |
| 83 | + throw new CodecConfigurationException(format("Can't find a codec for %s.", k)); |
82 | 84 | });
|
83 | 85 | }
|
84 | 86 |
|
@@ -114,4 +116,39 @@ public String toString() {
|
114 | 116 | + "codecProviders=" + codecProviders
|
115 | 117 | + '}';
|
116 | 118 | }
|
| 119 | + |
| 120 | + private static final class CodecCacheKey { |
| 121 | + private final Class<?> clazz; |
| 122 | + private final List<Type> types; |
| 123 | + |
| 124 | + CodecCacheKey(final Class<?> clazz, final List<Type> types) { |
| 125 | + this.clazz = clazz; |
| 126 | + this.types = types; |
| 127 | + } |
| 128 | + |
| 129 | + @Override |
| 130 | + public boolean equals(final Object o) { |
| 131 | + if (this == o) { |
| 132 | + return true; |
| 133 | + } |
| 134 | + if (o == null || getClass() != o.getClass()) { |
| 135 | + return false; |
| 136 | + } |
| 137 | + CodecCacheKey that = (CodecCacheKey) o; |
| 138 | + return clazz.equals(that.clazz) && Objects.equals(types, that.types); |
| 139 | + } |
| 140 | + |
| 141 | + @Override |
| 142 | + public int hashCode() { |
| 143 | + return Objects.hash(clazz, types); |
| 144 | + } |
| 145 | + |
| 146 | + @Override |
| 147 | + public String toString() { |
| 148 | + return "CodecCacheKey{" |
| 149 | + + "clazz=" + clazz |
| 150 | + + ", types=" + types |
| 151 | + + '}'; |
| 152 | + } |
| 153 | + } |
117 | 154 | }
|
0 commit comments