algorithm - 通过有效地找到最后使用的元素来保持缓存( map )小

标签 algorithm caching data-structures

我有一个 Java 应用程序,可以为大平铺图像的重新采样区域提供服务。

因为连续的区域查询通常彼此靠近,所以将图像切片缓存在 HashMap 中是有意义的。现在我想防止这个缓存无限增长。

为了不损失性能,我需要一个 O(1)/O(logN) 方法来查找最长时间未被访问的 map 元素。有没有办法做到这一点,它与仅从缓存中删除随机元素相比如何?

堆或 bst 将允许我保持排序的最后访问列表,但更新其中一个中的最后访问将花费线性时间。

这是我目前使用的代码的摘录:

Map<Point, BufferedImage> loadedImages = new ConcurrentHashMap<>();
Deque<Point> lastUsed = new ConcurrentLinkedDeque<>();

int getRGB(double tileX, double tileY) {
    Point point = new Point((int) tileX, (int) tileY);
    if (!loadedImages.containsKey(point)) {
        loadedImages.put(point, ImageIO.read(new File("R:\\tiles\\22\\" + point.y + "_" + point.x + ".jpg")));
        lastUsed.addLast(point);
    }
    BufferedImage img = loadedImages.get(point);
    if (loadedImages.size() > 1000) {
        loadedImages.remove(lastUsed.pollFirst());
    }
    //do stuff with img
}

这不是最优的,因为加载时间最长的图像可能在一秒钟前才被访问。

最佳答案

LinkedHashMap 与 Collections.synchronizedMap(linkedHashMap) 一起完成了这个技巧。 LinkedHashMap 的 removeEldestEntry 方法允许定义何时删除最后访问的条目的条件。

final int MAX_BUF_SIZE = 1000;

Map<Point, BufferedImage> loadedImages = new LinkedHashMap(MAX_BUF_SIZE + 1, .75F, true) {

    @Override
    protected boolean removeEldestEntry(Map.Entry eldest) {
        return size() > MAX_BUF_SIZE;
    }
};

int getRGB(double tileX, double tileY) {
    Point point = new Point((int) tileX, (int) tileY);
    if (!loadedImages.containsKey(point)) {
        loadedImages.put(point, ImageIO.read(new File("R:\\tiles\\22\\" + point.y + "_" + point.x + ".jpg")));
    }

    BufferedImage img = loadedImages.get(point);
    //do stuff with img..
}

关于algorithm - 通过有效地找到最后使用的元素来保持缓存( map )小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36254586/

相关文章:

caching - ColdFusion 客户端变量间歇性地显示过时的值

html - 设置缓存过期?

python - Trie 实现的内存高效数据结构

c - 如何计算一个值是否更快?

c++ - 计算这个字符串匹配函数的大 O 复杂度?

linux - Amazon Linux AMI 上的 Symfony2 中的缓存/日志权限

data-structures - 用于绘制数组/链表图像的绘图工具

c# - 素数字典

algorithm - 比较排序算法的复杂度

验证稳定匹配的算法?