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

Add a way to configure DeserializerCache Jackson uses #4101

Merged
merged 65 commits into from
Sep 5, 2023
Merged
Show file tree
Hide file tree
Changes from 54 commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
b1a1519
First draft
JooHyukKim Aug 28, 2023
3b0818a
Change name
JooHyukKim Aug 28, 2023
6bf55c2
Apply review
JooHyukKim Aug 29, 2023
d49dbb3
Clean up changes
JooHyukKim Aug 29, 2023
c71779f
Fix DeserializationConfig constructor accessor
JooHyukKim Aug 29, 2023
ea77d79
Clean up commented out code
JooHyukKim Aug 29, 2023
f2b43c4
Create interface for CacheProvider
JooHyukKim Aug 29, 2023
7cefce2
Merge branch '2.16' into 2502-poc
cowtowncoder Aug 30, 2023
3028b0c
Change DefaultCacheProvider to CacheProvider as param type
JooHyukKim Aug 30, 2023
8a5cbf2
Merge branch '2502-poc' of https://github.com/JooHyukKim/jackson-data…
JooHyukKim Aug 30, 2023
3b53c76
Remove cache mutation in deserialization config
JooHyukKim Aug 30, 2023
64ae831
Update CacheProviderTest.java
JooHyukKim Aug 30, 2023
30adc84
Apply review
JooHyukKim Aug 30, 2023
a36b1d5
not specify _cacheProvider as null
JooHyukKim Aug 30, 2023
272ef1d
Minimize changes
JooHyukKim Aug 30, 2023
a37f740
Remove supplier
JooHyukKim Aug 30, 2023
4359ea3
Merge branch '2.16' into 2502-poc
JooHyukKim Aug 31, 2023
ee5e2e2
Adapt to DeserCache changes
JooHyukKim Aug 31, 2023
7d58ac7
Merge branch '2.16' into 2502-poc
cowtowncoder Aug 31, 2023
a71143c
Merge branch '2.16' into 2502-poc
cowtowncoder Aug 31, 2023
73414ca
WIP apply review
JooHyukKim Aug 31, 2023
11bd54a
Add CacheProvider configuration in BaseSettings
JooHyukKim Aug 31, 2023
c9e7cd1
Update ObjectMapper.java
JooHyukKim Aug 31, 2023
465cc51
Add CacheProvider configuration in BaseSettings
JooHyukKim Aug 31, 2023
05c1d79
Add `BaseSettings`
JooHyukKim Aug 31, 2023
890f416
Add BaseSettings `ObjectMapper.setCacheProvider(CacheProvider cachePr…
JooHyukKim Aug 31, 2023
bc62b04
Merge branch '4101-Add-Cache-Provider-in-BaseSettings' into 2502-poc
JooHyukKim Aug 31, 2023
6f0cd81
Remove supplier
JooHyukKim Aug 31, 2023
447df54
Implement CacheProvider, its default, and related DeserializerCache
JooHyukKim Aug 31, 2023
3e371c9
Implement CacheProvider, its default, and related DeserializerCache
JooHyukKim Aug 31, 2023
49ffff0
Update DefaultDeserializationContext.java
JooHyukKim Aug 31, 2023
054d46f
Fix docs and naming
JooHyukKim Aug 31, 2023
8e229ec
Remove binding of CacheProv in DatabindContext
JooHyukKim Sep 2, 2023
6345e36
Sync changes with sub-PRs
JooHyukKim Sep 2, 2023
578eda9
Minimize changes
JooHyukKim Sep 2, 2023
f3600db
Minor code reuse and access control in DefaultCache.
JooHyukKim Sep 2, 2023
317f8cb
Merge branch '4101-implement-CacheProvider' into 2502-poc
JooHyukKim Sep 2, 2023
e1132d6
Improve JavaDoc
JooHyukKim Sep 2, 2023
e369d0c
Improve Doc and method order
JooHyukKim Sep 2, 2023
2538f6e
Merge branch '2.16' into 2502-poc
JooHyukKim Sep 2, 2023
95b6a2f
Apply review
JooHyukKim Sep 2, 2023
6350496
Update SerializationConfig.java
JooHyukKim Sep 2, 2023
6a7ec46
Remove accessor conflict
JooHyukKim Sep 2, 2023
701d1a5
Update DefaultCacheProvider.java
JooHyukKim Sep 2, 2023
6629f8c
Merge branch '4101-implement-CacheProvider' into 2502-poc
JooHyukKim Sep 2, 2023
aff462e
Minimize more changes.
JooHyukKim Sep 2, 2023
9187533
Solution 2 : Configure CacheProvider when setting CacheProvider
JooHyukKim Sep 2, 2023
68716c8
Improve test and doc around DefaultCacheProvider.Builder
JooHyukKim Sep 2, 2023
b44a8bc
Clean up JavaDoc and add a test
JooHyukKim Sep 2, 2023
70b4558
Apply review on DefaultCacheProvider and CacheProvider
JooHyukKim Sep 3, 2023
7f47132
Implement withCaches
JooHyukKim Sep 3, 2023
3749efd
Revert DeserializerCache changes, except DEFAULT_MAX_CACHE_SIZE constant
JooHyukKim Sep 3, 2023
6c07b0e
Remove now invalid JavaDoc WARNING
JooHyukKim Sep 3, 2023
a8458ef
Clean up changes and fix namings
JooHyukKim Sep 3, 2023
0627eee
Add more doc
JooHyukKim Sep 3, 2023
fc1af99
Merge branch '2.16' into 2502-poc
cowtowncoder Sep 4, 2023
75d6288
Merge branch '2.16' into 2502-poc
cowtowncoder Sep 4, 2023
1b5d819
Minor streamlining
cowtowncoder Sep 4, 2023
32c0abe
Apply review. Fail fast in CacheProviderTest.java
JooHyukKim Sep 4, 2023
97e9041
Update CacheProviderTest.java
JooHyukKim Sep 4, 2023
0abfb1a
Apply review : make CustomCacheProvider in test stateful
JooHyukKim Sep 5, 2023
caabffa
Make variables more meaningful
JooHyukKim Sep 5, 2023
6231c7f
Minor tweaking to try to unify construction of DeserializerCache for …
cowtowncoder Sep 5, 2023
232f7aa
Final touches to try to ensure ObjectMapper.copy() works with caches too
cowtowncoder Sep 5, 2023
bd52023
Merge branch '2.16' into 2502-poc
cowtowncoder Sep 5, 2023
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 @@ -199,6 +199,24 @@ protected DeserializationContext(DeserializationContext src,
_attributes = src._attributes;
}

/**
* @since 2.16
*/
protected DeserializationContext(DeserializationContext src,
cowtowncoder marked this conversation as resolved.
Show resolved Hide resolved
DeserializerCache cache)
{
_cache = cache;
_factory = src._factory;

_config = src._config;
_featureFlags = src._featureFlags;
_readCapabilities = src._readCapabilities;
_view = src._view;
_parser = src._parser;
_injectableValues = src._injectableValues;
_attributes = src._attributes;
}

/**
* Constructor used for creating actual per-call instances.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2272,11 +2272,14 @@ public ObjectMapper setConstructorDetector(ConstructorDetector cd) {
/**
* Method for specifying {@link CacheProvider} instance, to provide Cache instances to be used in components downstream.
*
* @throws IllegalArgumentException if given provider is null
* @since 2.16
*/
public ObjectMapper setCacheProvider(CacheProvider cacheProvider) {
_assertNotNull("cacheProvider", cacheProvider);
_deserializationConfig = _deserializationConfig.with(cacheProvider);
_serializationConfig = _serializationConfig.with(cacheProvider);
_deserializationContext = _deserializationContext.withCaches(cacheProvider);
return this;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
package com.fasterxml.jackson.databind.cfg;

import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.deser.DeserializerCache;
import com.fasterxml.jackson.databind.util.LookupCache;

/**
* Interface that defines API Jackson uses for constructing various internal
* caches. This allows configuring custom caches and cache configurations.
Expand All @@ -11,5 +17,11 @@
public interface CacheProvider
extends java.io.Serializable
{
// !!! TODO: add methods
/**
* Method to provide a {@link LookupCache} instance for constructing {@link DeserializerCache}.
*
* @return {@link LookupCache} instance for constructing {@link DeserializerCache}.
*/
LookupCache<JavaType, JsonDeserializer<Object>> forDeserializerCache(DeserializationConfig config);

}
Original file line number Diff line number Diff line change
@@ -1,19 +1,121 @@
package com.fasterxml.jackson.databind.cfg;

import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.deser.DeserializerCache;
import com.fasterxml.jackson.databind.util.LRUMap;
import com.fasterxml.jackson.databind.util.LookupCache;

/**
* Default implementation of {@link CacheProvider}.
*
* The default implementation of {@link CacheProvider}.
* Configuration is builder-based via {@link DefaultCacheProvider.Builder}.
* <p>
* Users can either use this class or create their own {@link CacheProvider} implementation.
*
* @since 2.16
*/
public class DefaultCacheProvider
implements CacheProvider
{
private static final long serialVersionUID = 1L;

public static DefaultCacheProvider defaultInstance() {
return new DefaultCacheProvider();
/**
* Maximum size of the {@link LookupCache} instance constructed by {@link #forDeserializerCache(DeserializationConfig)}.
*
* @see Builder#maxDeserializerCacheSize(int)
*/
protected final int _maxDeserializerCacheSize;

/*
/**********************************************************************
/* Life cycle
/**********************************************************************
*/

protected DefaultCacheProvider(int deserializerCache)
{
_maxDeserializerCacheSize = deserializerCache;
}

/*
/**********************************************************************
/* Defaults
/**********************************************************************
*/

/**
* @return Default {@link DefaultCacheProvider} instance using default configuration values.
*/
public static CacheProvider defaultInstance() {
return new DefaultCacheProvider(DeserializerCache.DEFAULT_MAX_CACHE_SIZE);
}

// To implement!
/*
/**********************************************************
/* Overriden methods
/**********************************************************
*/

@Override
public LookupCache<JavaType, JsonDeserializer<Object>> forDeserializerCache(DeserializationConfig config) {
return new LRUMap<>(Math.min(64, _maxDeserializerCacheSize >> 2), _maxDeserializerCacheSize);
}

/*
/**********************************************************
/* Builder Config
/**********************************************************
*/

/**
* @return {@link Builder} instance for configuration.
*/
public static DefaultCacheProvider.Builder builder() {
return new Builder();
}

/**
* Builder offering fluent factory methods to configure {@link DefaultCacheProvider}, keeping it immutable.
*/
public static class Builder {

/**
* Maximum Size of the {@link LookupCache} instance created by {@link #forDeserializerCache(DeserializationConfig)}.
* Corresponds to {@link DefaultCacheProvider#_maxDeserializerCacheSize}.
*/
private int _maxDeserializerCacheSize;

private Builder() { }

/**
* Define the maximum size of the {@link LookupCache} instance constructed by {@link #forDeserializerCache(DeserializationConfig)}.
* The cache is instantiated as:
* <pre>
* return new LRUMap<>(Math.min(64, maxSize >> 2), maxSize);
* </pre>
*
* @param maxDeserializerCacheSize Size for the {@link LookupCache} to use within {@link DeserializerCache}
* @return this builder
* @throws IllegalArgumentException if {@code maxDeserializerCacheSize} is negative
* @since 2.16
*/
public Builder maxDeserializerCacheSize(int maxDeserializerCacheSize) {
if (maxDeserializerCacheSize < 0) {
throw new IllegalArgumentException("Cannot set maxDeserializerCacheSize to a negative value");
}
_maxDeserializerCacheSize = maxDeserializerCacheSize;
return this;
}

/**
* Constructs a {@link DefaultCacheProvider} with the provided configuration values, using defaults where not specified.
*
* @return A {@link DefaultCacheProvider} instance with the specified configuration
*/
public DefaultCacheProvider build() {
return new DefaultCacheProvider(_maxDeserializerCacheSize);
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.cfg.CacheProvider;
import com.fasterxml.jackson.databind.cfg.HandlerInstantiator;
import com.fasterxml.jackson.databind.deser.impl.ReadableObjectId;
import com.fasterxml.jackson.databind.deser.impl.ReadableObjectId.Referring;
Expand Down Expand Up @@ -61,6 +62,14 @@ protected DefaultDeserializationContext(DefaultDeserializationContext src,
super(src, factory);
}

/**
* @since 2.16
*/
protected DefaultDeserializationContext(DefaultDeserializationContext src,
DeserializerCache cache) {
super(src, cache);
}

/**
* @since 2.4.4
*/
Expand Down Expand Up @@ -296,6 +305,13 @@ public final KeyDeserializer keyDeserializerInstance(Annotated ann, Object deser
*/
public abstract DefaultDeserializationContext with(DeserializerFactory factory);

/**
* Fluent factory method used for constructing a new instance with cache instances provided by {@link CacheProvider}.
*
* @since 2.16
*/
public abstract DefaultDeserializationContext withCaches(CacheProvider cacheProvider);

/**
* Method called to create actual usable per-deserialization
* context instance.
Expand Down Expand Up @@ -402,6 +418,13 @@ private Impl(Impl src, DeserializationConfig config) {
super(src, config);
}

/**
* @since 2.16
*/
private Impl(Impl src, DeserializerCache deserializerCache) {
super(src, deserializerCache);
}

@Override
public DefaultDeserializationContext copy() {
ClassUtil.verifyMustOverride(Impl.class, this, "copy");
Expand All @@ -424,5 +447,12 @@ public DefaultDeserializationContext createDummyInstance(DeserializationConfig c
public DefaultDeserializationContext with(DeserializerFactory factory) {
return new Impl(this, factory);
}

@Override // Since 2.16
public DefaultDeserializationContext withCaches(CacheProvider cacheProvider) {
DeserializerCache deserializerCache = new DeserializerCache(cacheProvider.forDeserializerCache(_config));

return new Impl(this, deserializerCache);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ public final class DeserializerCache
{
private static final long serialVersionUID = 1L;

/**
* Previously was passed to {@link DeserializerCache} constructors "inline".
* Declared as field since 2.16.
*
* @since 2.16
*/
public final static int DEFAULT_MAX_CACHE_SIZE = 2000;
cowtowncoder marked this conversation as resolved.
Show resolved Hide resolved

/*
/**********************************************************
/* Caching
Expand Down Expand Up @@ -52,7 +60,7 @@ public final class DeserializerCache
*/

public DeserializerCache() {
this(2000); // see [databind#1995]
this(DEFAULT_MAX_CACHE_SIZE); // see [databind#1995]
}

public DeserializerCache(int maxSize) {
Expand Down
Loading