1
1
package com .fasterxml .jackson .databind .deser ;
2
2
3
3
import java .util .HashMap ;
4
- import java .util .concurrent .ConcurrentHashMap ;
5
4
6
5
import com .fasterxml .jackson .annotation .JsonFormat ;
7
6
12
11
import com .fasterxml .jackson .databind .type .*;
13
12
import com .fasterxml .jackson .databind .util .ClassUtil ;
14
13
import com .fasterxml .jackson .databind .util .Converter ;
14
+ import com .fasterxml .jackson .databind .util .SimpleLookupCache ;
15
15
16
16
/**
17
- * Class that defines caching layer between callers (like
18
- * {@link ObjectMapper},
17
+ * Class that defines caching layer between callers (like {@link ObjectMapper},
19
18
* {@link com.fasterxml.jackson.databind.DeserializationContext})
20
19
* and classes that construct deserializers
21
20
* ({@link com.fasterxml.jackson.databind.deser.DeserializerFactory}).
@@ -25,6 +24,11 @@ public final class DeserializerCache
25
24
{
26
25
private static final long serialVersionUID = 3L ;
27
26
27
+ /**
28
+ * By default allow caching of up to 4000 deserializers.
29
+ */
30
+ public final static int DEFAULT_MAX_CACHED = 4000 ;
31
+
28
32
/*
29
33
/**********************************************************************
30
34
/* Caching
@@ -34,42 +38,45 @@ public final class DeserializerCache
34
38
/**
35
39
* We will also cache some dynamically constructed deserializers;
36
40
* specifically, ones that are expensive to construct.
37
- * This currently means bean and Enum deserializers; starting with
38
- * 2.5, container deserializers will also be cached.
39
- *<p>
40
- * Given that we don't expect much concurrency for additions
41
- * (should very quickly converge to zero after startup), let's
42
- * define a relatively low concurrency setting.
41
+ * This currently (3.0) means POJO, Enum and Container (collection,
42
+ * map) deserializers.
43
43
*/
44
- private final transient ConcurrentHashMap <JavaType , JsonDeserializer <Object >> _cachedDeserializers
45
- = new ConcurrentHashMap <JavaType , JsonDeserializer <Object >>(64 , 0.75f , 4 );
44
+ private final SimpleLookupCache <JavaType , JsonDeserializer <Object >> _cachedDeserializers ;
46
45
47
46
/**
48
47
* During deserializer construction process we may need to keep track of partially
49
48
* completed deserializers, to resolve cyclic dependencies. This is the
50
49
* map used for storing deserializers before they are fully complete.
51
50
*/
52
51
private final transient HashMap <JavaType , JsonDeserializer <Object >> _incompleteDeserializers
53
- = new HashMap <JavaType , JsonDeserializer < Object > >(8 );
52
+ = new HashMap <>(8 );
54
53
55
54
/*
56
55
/**********************************************************************
57
56
/* Life-cycle
58
57
/**********************************************************************
59
58
*/
60
59
61
- public DeserializerCache () { }
60
+ public DeserializerCache () { this (DEFAULT_MAX_CACHED ); }
61
+
62
+ public DeserializerCache (int maxSize ) {
63
+ int initial = Math .min (64 , maxSize >>2 );
64
+ _cachedDeserializers = new SimpleLookupCache <>(initial , maxSize );
65
+ }
66
+
67
+ private DeserializerCache (DeserializerCache src ) {
68
+ _cachedDeserializers = src ._cachedDeserializers ;
69
+ }
62
70
63
71
/*
64
72
/**********************************************************************
65
73
/* JDK serialization handling
66
74
/**********************************************************************
67
75
*/
68
76
69
- // 11-Apr-2018, tatu: instead of clearing or such on write, keep everything transient,
70
- // recreate as empty. No point trying to revive cached instances
77
+ // Need to re-create just to initialize `transient` fields
71
78
protected Object readResolve () {
72
- return new DeserializerCache ();
79
+ return new DeserializerCache (this );
73
80
}
74
81
75
82
/*
0 commit comments