Caching path resolution - #2336
Conversation
Caches both positive and negative resolution of paths, in order to avoid repeated use of exceptions for program control. Negative resolution, i.e. no matching path found is cached separately in an LRU cache to avoid memory exhaustion. Closes #2335
mp911de
left a comment
There was a problem hiding this comment.
The caching isn't effective caused by short-lived QueryMapper objects in JDBC.
R2DBC's binding to DefaultReactiveDataAccessStrategy reduces the query mapper instances to a single instance and for R2DBC, this approach could work.
| * Extension of {@link Field} to be backed with mapping metadata. | ||
| */ | ||
| protected static class MetadataBackedField extends Field { | ||
| protected class MetadataBackedField extends Field { |
There was a problem hiding this comment.
nit: removing static makes the MappingContext<? extends RelationalPersistentEntity<?>, RelationalPersistentProperty> mappingContext field superfluous
|
|
||
| private final JdbcConverter converter; | ||
| private final MappingContext<? extends RelationalPersistentEntity<?>, RelationalPersistentProperty> mappingContext; | ||
| private final PropertyPathResolver propertyPathResolver; |
There was a problem hiding this comment.
QueryMapper is created quite frequently (e.g. AggregateReader.createCondition, StatementFactory via PartTreeJdbcQuery.execute or createDeleteQueries), therefore we create many instances of a cache that do not survive long enough to establish meaningful caching.
| private static final int UNRESOLVABLE_CACHE_SIZE = 4096; | ||
|
|
||
| private final MappingContext<? extends RelationalPersistentEntity<?>, RelationalPersistentProperty> mappingContext; | ||
| private final Map<PathResolutionKey, PersistentPropertyPath<RelationalPersistentProperty>> resolved = new ConcurrentHashMap<>(); |
There was a problem hiding this comment.
Map has an unbounded growth imposing out of memory risk.
There was a problem hiding this comment.
That's why it is used only for the successfully resolved paths, which are limited in number.
The unlimited unresolved paths are only cached in an LRUCache.
There was a problem hiding this comment.
PathResolutionKey input is a String. Given the supported variance in expressions, PersonAddressStreetName can be person.address.streetName, person_address_streetName, personAddress_streetName, etc. While the space is finite, we still can have an exponentially growing number of keys.
Caches both positive and negative resolution of paths, in order to avoid repeated use of exceptions for program control.
Negative resolution, i.e. no matching path found is cached separately in an LRU cache to avoid memory exhaustion.
Closes #2335