Skip to content

Chore: Extracted interface Cache from 'LRUCache' #130964

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

Open
wants to merge 32 commits into
base: main
Choose a base branch
from

Conversation

mjmbischoff
Copy link
Contributor

@mjmbischoff mjmbischoff commented Jul 9, 2025

Chore: Extracting a Cache interface to allow exploring alternative implementations. Alternative implementations are outside the scope of this PR.

I know indirection is bad for performance, but the Cache/LRUCache already lists trade-offs, I expect things to get inlined quickly enough during runtime, so everything considered, I don't think this will 'do us in'.

Along the way found some minor bugs and issues

  • Renamed Cache to LRUCache and extracted an interface and put under the old name to allow other implementations to be tested.
  • Adjusted tests but made explicit the ones who rely on the LRUCache implementation to test if settings are applied correctly. (While CacheBuilder#build() returns a Cache it still always returns the LRUCache implementation)
  • Made Cache.CacheStats / Cache.Stats a record. Getters we're kept for now, should perhaps inline access in the future.
  • Updated the javadoc of the interface to provide enough guarantees for current usage while also lowering it to provide more flexibility for future alternative implementations
  • Notification of removal is documented in the javadoc, also described the situation with regards to registering a RemovalListener and how the interface doesn't mandate how, how many, and what the effects are if registered listener is swapped or if multiple listeners can be registered and what happens when they are added or removed.
  • Added a test to assert if implementations of Cache follow the contract

Context

The Cache/LRUCache is the only implementation of a cache within the ES code base, the implementation dates from 2015 when different priorities were being juggled. Being the only implementation part of the codebase, it's usage has grown over the years, for example: Enrich, Interference, Searchable snapshots. While the choices at the time were sound, as the external factors have changed, it makes sense to revisit these. As a first step PR which looks to extract an Interface and formalize the contract between implementation and consumer.

Somewhat complete list of use cases that use the cache:

  • Geoip ingest processor
  • User agent ingest processor
  • 'Query Caches' (BitsetFilterCache, IndicesRequestCache(shard level), IndicesFieldDataCache) (NOT LRUQueryCache as it is supplied / managed as part of Lucene)
  • Script cache
  • Security(dls, field permissions, Role-privileges, automata, idp / saml, APIkey, LDAP, etc)
  • Enrich cache
  • Interference (Amazon SageMaker)
  • ML (Job auditing)
  • searchable snapshots

NOTES (ramblings of the author, for context, can be ignored):

The wording of javadoc of the old Cache/LRUCache might have sounded 'overly scary/dangerous' leading to some interesting usage/interaction

As already pointed out in comments org.elasticsearch.xpack.core.security.support.CacheIteratorHelper, it's a little wonk. I'm also unsure if the extra protection is needed. Regardless the design of that class to leak the locks and not pull up interaction and fully decorate a cache a la Collections.unmodifiableXXX(XXX) is... 'not (personally) preferred'. But this would be a separate PR.

A computed weight is being tracked as long, which can overflow. Always calculating it on the fly or calculating it on the fly after detecting overflow is an option. Also wondering about thread safety as we're incrementing and something like an AtomicLong is needed. 'Best-effort' :-) Changing the LRUCache impl is out of scope of this PR, so left alone.


For the reviewer:

old Cache was refactored to LRUCache, please diff these, there shouldn't be any changes beyond the name and pulling the shared inner classes out. Github shows a diff between the old Cache and the interface that is now created at the old coordinate. It seems that context was lost which makes it appear like a much bigger PR than it is.

Similar with CacheTests and LRUCacheTests. (CacheTests is completely new)

…nder the old name to allow other implementations to be tested.

- Found and fixed minor bug where we tested max weight against count() instead of weight
- Found and fixed minor issue with possible long overflow.
- Adjusted tests but made explicit the ones who rely on the `LRUCache` implementation to test if settings are applied correctly.
While CacheBuilder#build() returns a `Cache` it still always returns the `LRUCache` implementation
@elasticsearchmachine elasticsearchmachine added v9.2.0 external-contributor Pull request authored by a developer outside the Elasticsearch team labels Jul 10, 2025
@mjmbischoff mjmbischoff marked this pull request as ready for review July 14, 2025 14:24
@elasticsearchmachine elasticsearchmachine added the needs:triage Requires assignment of a team area label label Jul 14, 2025
@mjmbischoff mjmbischoff self-assigned this Jul 15, 2025
@ywangd ywangd removed their request for review July 21, 2025 00:35
@ywangd
Copy link
Member

ywangd commented Jul 21, 2025

Not sure about the context of this change. The code is owned by @elastic/es-core-infra, so I took myself off the reviewers.

@gbanasiak gbanasiak added the :Core/Infra/Core Core issues without another label label Jul 21, 2025
@elasticsearchmachine elasticsearchmachine added Team:Core/Infra Meta label for core/infra team and removed needs:triage Requires assignment of a team area label labels Jul 21, 2025
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra (Team:Core/Infra)

@mjmbischoff mjmbischoff removed the serverless-linked Added by automation, don't add manually label Jul 23, 2025
@nielsbauman nielsbauman removed their request for review July 28, 2025 14:29
@mjmbischoff mjmbischoff requested a review from rjernst July 31, 2025 16:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Core/Infra/Core Core issues without another label external-contributor Pull request authored by a developer outside the Elasticsearch team >refactoring Team:Core/Infra Meta label for core/infra team >tech debt v9.2.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants