oracle / coherence

Oracle Coherence Community Edition
https://coherence.community
Universal Permissive License v1.0
427 stars 70 forks source link

Fix unit factor usage in Caffeine cache #76

Closed ben-manes closed 2 years ago

ben-manes commented 2 years ago

Fix the calculation based on what @aseovic explained to me over slack. I had mistakenly thought this was to change the base unit of the entry's weight, e.g. from bytes to kilobytes, so that larger values could be stored. Instead it is to allow the total capacity to be reported as an int instead of a long, since that fix would be a breaking API change.

A minor cleanup was to allocate a CacheEvent instance only if it the cache will actually fire the event. Since MapListenerSupport#fireEvent is a synchronous call even if no listeners are registered (see collectListeners), the unsynchronized isEmpty() method is called as a guard. It's probably better to prefer avoiding the allocation over the convenience method as not much of a difference in readability.

aseovic commented 2 years ago

Actually, while the existing changes look good, I think some are still missing: getHighUnits and setHighUnits also need to take unit factor into account:

    @Override
    public int getHighUnits()
        {
        return (int) Math.min(f_eviction.getMaximum() / m_nUnitFactor, Integer.MAX_VALUE);
        }

    @Override
    public synchronized void setHighUnits(int units)
        {
        f_eviction.setMaximum(units * m_nUnitFactor);
        }

Without that it would be impossible to set high units to anything larger than 2 GB.

ben-manes commented 2 years ago

CaffeineCacheTest runs against both implementations (unfortunately the current unit factor test passes both with and without this pr). I think adding the high/low tests would help, and we can accumulate more for compatibility checks.

ben-manes commented 2 years ago

Updated the implementation by using the internal / external conversion methods from OldCache and added a unit test. This way the logic stays as similar as possible. It differs slightly because Caffeine avoids long overflow by restricting the maximum size to Long.MAX_VALUE - Integer.MAX_VALUE, rather than checking for that at runtime (whereas OldCache goes negative).

coherence-bot commented 2 years ago

Failed to process pull request Failed to prepare P4 changelist (possibly a merge conflict).

aseovic commented 2 years ago

@rlubke Looks like we'll have to do a manual patch in P4. Automated PR merge still doesn't work... :-(

@thegridman This may be a good PR to use to sort out why the merge doesn't work any more. It's fairly simple, touches only 3 files that should be exactly the same in main and ce branches in P4.

ben-manes commented 2 years ago

Please remember to merge this.

rlubke commented 2 years ago

We haven't forgotten :)

We're working on it, just in the middle of some refactorings and don't want to muddy the waters at the moment. Will follow up as soon as it has been merged.

rlubke commented 2 years ago

PR has been merged