All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.ehcache.pool.impl.BalancedAccessEvictor Maven / Gradle / Ivy

Go to download

Ehcache is an open source, standards-based cache used to boost performance, offload the database and simplify scalability. Ehcache is robust, proven and full-featured and this has made it the most widely-used Java-based cache.

There is a newer version: 2.10.9.2
Show newest version
/**
 *  Copyright Terracotta, Inc.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package net.sf.ehcache.pool.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;

import net.sf.ehcache.pool.PoolAccessor;
import net.sf.ehcache.pool.PoolEvictor;
import net.sf.ehcache.pool.PoolParticipant;

/**
 * Abstract implementation of a global 'cache value' maximizing pool eviction algorithm.
 * 

* * @author Chris Dennis * @author Alex Snaps */ public class BalancedAccessEvictor implements PoolEvictor { private static final int SAMPLE_SIZE = 5; /** * Comparator used to rank the stores in order of eviction 'cost'. */ private final class EvictionCostComparator implements Comparator { private final long unloadedSize; private final Map evictionCostCache; public EvictionCostComparator(long unloadedSize, int collectionSize) { this.unloadedSize = unloadedSize; this.evictionCostCache = new IdentityHashMap(collectionSize); } public int compare(PoolAccessor s1, PoolAccessor s2) { Float f1 = evictionCostCache.get(s1); if (f1 == null) { f1 = evictionCost(s1, unloadedSize); evictionCostCache.put(s1, f1); } Float f2 = evictionCostCache.get(s2); if (f2 == null) { f2 = evictionCost(s2, unloadedSize); evictionCostCache.put(s2, f2); } return Float.compare(f1, f2); } } /** * {@inheritDoc} */ public boolean freeSpace(Collection> from, long bytes) { if (from == null || from.isEmpty()) { return false; } List random = new ArrayList(from); Collections.shuffle(random); for (int i = 0; i < random.size(); i += SAMPLE_SIZE) { List sorted = random.subList(i, Math.min(SAMPLE_SIZE + i, random.size())); Collections.sort(sorted, new EvictionCostComparator(getDesiredUnloadedSize(sorted), sorted.size() + 1)); for (PoolAccessor accessor : sorted) { int count; long byteSize = accessor.getSize(); long countSize = accessor.getParticipant().getApproximateCountSize(); if (countSize == 0 || byteSize == 0) { count = 1; } else { count = (int) Math.max((bytes * countSize) / byteSize, 1L); } if (accessor.getParticipant().evict(count, bytes)) { return true; } } } return false; } private float evictionCost(PoolAccessor accessor, long unloadedSize) { float hitRate = accessor.getParticipant().getApproximateHitRate(); float missRate = accessor.getParticipant().getApproximateMissRate(); float accessRate = hitRate + missRate; if (accessRate == 0.0f) { if (accessor.getSize() > unloadedSize) { return 0; } else { return Float.MIN_NORMAL; } } else { long countSize = accessor.getParticipant().getApproximateCountSize(); float cost = accessRate / countSize; if (Float.isNaN(cost)) { throw new AssertionError(String.format("NaN Eviction Cost [hit:%f miss:%f size:%d]", hitRate, missRate, countSize)); } else { return cost; } } } private long getDesiredUnloadedSize(Collection from) { long unloadedSize = 0L; for (PoolAccessor accessor : from) { unloadedSize += accessor.getSize(); } return unloadedSize / from.size(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy