private ToDoubleFunction<CaffeineMetrics> func(@Nullable Type type,
                                                       ToDoubleFunction<CacheReference> valueFunction) {
            return value -> {
                double sum = 0;
                lock.lock();
                try {
                    for (final Iterator<CacheReference> i = cacheRefs.iterator(); i.hasNext();) {
                        final CacheReference ref = i.next();
                        final boolean garbageCollected = ref.updateCacheStats();
                        if (!garbageCollected) {
                            sum += valueFunction.applyAsDouble(ref);
                        } else {
                            // Remove the garbage-collected reference from the list to prevent it from
                            // growing infinitely.
                            i.remove();

                            // Accumulate the stats of the removed reference so the counters do not decrease.
                            // NB: We do not accumulate 'estimatedSize' because it's not a counter but a gauge.
                            final CacheStats stats = ref.cacheStats;
                            statsForGarbageCollected[HIT_COUNT.ordinal()] += stats.hitCount();
                            statsForGarbageCollected[MISS_COUNT.ordinal()] += stats.missCount();
                            statsForGarbageCollected[EVICTION_COUNT.ordinal()] += stats.evictionCount();
                            statsForGarbageCollected[EVICTION_WEIGHT.ordinal()] += stats.evictionWeight();
                            statsForGarbageCollected[LOAD_SUCCESS_COUNT.ordinal()] += stats.loadSuccessCount();
                            statsForGarbageCollected[LOAD_FAILURE_COUNT.ordinal()] += stats.loadFailureCount();
                            statsForGarbageCollected[TOTAL_LOAD_TIME.ordinal()] += stats.totalLoadTime();
                        }
                    }

                    if (type != null) {
                        // Add the value of the garbage-collected caches.
                        sum += statsForGarbageCollected[type.ordinal()];
                    }
                } finally {
                    lock.unlock();
                }

                return sum;
            };
        }
An array whose each element is the sum of the garbage-collected {@link Cache} stats.
{@link Type#ordinal()} signifies the index of this array.
core/src/main/java/com/linecorp/armeria/internal/common/metric/CaffeineMetricSupport.java