@Test
  public void testLFUFractionOverflow() {
    final int adaptiveRate = 700; // in order to cause an overflow
    mCache =
        createDummyAdaptiveCountingMemoryCache(
            mParamsSupplier,
            mCacheTrimStrategy,
            mValueDescriptor,
            adaptiveRate,
            1,
            2,
            initialLFUCacheFractionPromil);

    // add item1 to LFU
    CloseableReference<Integer> originalRef1 = newReference(10);
    CloseableReference<Integer> valueRef1 = mCache.cache(KEYS[1], originalRef1);
    originalRef1.close();
    valueRef1.close();
    assertLFUExclusivelyOwned(KEYS[1], 10);

    // add item2 to LFU
    CloseableReference<Integer> originalRef2 = newReference(20);
    CloseableReference<Integer> valueRef2 = mCache.cache(KEYS[2], originalRef2);
    originalRef2.close();
    valueRef2.close();
    assertLFUExclusivelyOwned(KEYS[1], 10);
    assertLFUExclusivelyOwned(KEYS[2], 20);

    // add item3 to LFU, item1 will be evicted from LFU and will be inserted to the LFU ghost list
    CloseableReference<Integer> originalRef3 = newReference(30);
    CloseableReference<Integer> valueRef3 = mCache.cache(KEYS[3], originalRef3);
    originalRef3.close();
    valueRef3.close();
    assertLFUExclusivelyOwned(KEYS[2], 20);
    assertLFUExclusivelyOwned(KEYS[3], 30);
    assertNotCached(KEYS[1], 10);

    // item1 in the LFU ghost list
    assertKeyIsInLFUGhostList(KEYS[1], 1);

    // try to access item1, which was already evicted, which will result in updating the LFU
    // fraction
    assertEquals(initialLFUCacheFractionPromil, mCache.mLFUFractionPromil);
    CloseableReference<Integer> valueRef1a = mCache.get(KEYS[1]);
    assertNull(valueRef1a);
    // make sure the LFU cache fraction was not updated, because if we do it will cause in overflow
    assertEquals(initialLFUCacheFractionPromil, mCache.mLFUFractionPromil);

    // make item2 and item3 "frequently used" by accessing them more than mFrequentlyUsedThreshiold
    CloseableReference<Integer> valueRef2a = mCache.get(KEYS[2]);
    CloseableReference<Integer> valueRef3a = mCache.get(KEYS[3]);
    valueRef2a.close();
    valueRef3a.close();
    assertMFUExclusivelyOwned(KEYS[2], 20);
    assertMFUExclusivelyOwned(KEYS[3], 30);

    // insert item4 to MFU, item2 will be evicted from MFU and inserted in the MFU ghost list
    CloseableReference<Integer> originalRef4 = newReference(40);
    CloseableReference<Integer> valueRef4 = mCache.cache(KEYS[4], originalRef4);
    CloseableReference<Integer> valueRef4a = mCache.get(KEYS[4]);
    originalRef4.close();
    valueRef4.close();
    valueRef4a.close();

    assertEquals(initialLFUCacheFractionPromil, mCache.mLFUFractionPromil);
    CloseableReference<Integer> valueRef2b = mCache.get(KEYS[2]);
    assertNull(valueRef2b);
    // make sure the LFU cache fraction was not updated, because if we do it will cause in overflow
    assertEquals(initialLFUCacheFractionPromil, mCache.mLFUFractionPromil);
  }
This test checks edge cases, when trying to increase/decrease the LFU cache fraction to more
than 1/less than 0 (of the cache size). The expected behaviour is not to update the LFU
fraction.
imagepipeline-base/src/test/java/com/facebook/imagepipeline/cache/AbstractAdaptiveCountingMemoryCacheTest.java