LRU缓存在C中

时间:2010-06-12 04:25:55

标签: c caching

对于C应用程序(在* nix环境中),我需要在内存中缓存大量(但可变)的小(1千字节到10兆字节)文件。因为我不想吃掉所有内存,所以我想设置硬内存限制(例如,64兆字节)并将文件推送到以文件名为键的哈希表中,并以最少的使用率处理条目。我认为我需要的是一个LRU缓存。

真的,我宁愿不自己滚动,所以如果有人知道我在哪里可以找到一个可行的图书馆,请指明方向?如果不这样,有人可以在C中提供LRU缓存的简单示例吗?相关帖子表明一个哈希表有一个双向链表,但我甚至不清楚双链表如何保持LRU。

旁注:我意识到这几乎就是memcache的功能,但它不适合我。我也看了一下希望在LRU缓存上启发自己的消息来源,但没有成功。

5 个答案:

答案 0 :(得分:5)

  

相关帖子表明哈希表有一个双向链表,但我甚至不清楚双链表如何保持LRU。

我只是在这里猜测,但你可以做这样的事情(在这里使用伪C因为我很懒)。以下是基本数据结构:

struct File
{
    // hash key
    string Name;

    // doubly-linked list
    File* Previous;
    File* Next;

    // other file data...
}

struct Cache
{
    HashTable<string, File*> Table // some existing hashtable implementation
    File* First; // most recent
    File* Last;  // least recent
}

以下是打开和关闭文件的方式:

File* Open(Cache* cache, string name)
{
    if (look up name in cache->Table succeeds)
    {
        File* found = find it from the hash table lookup
        move it to the front of the list
    }
    else
    {
        File* newFile = open the file and create a new node for it

        insert it at the beginning of the list

        if (the cache is full now)
        {
            remove the last file from the list
            close it
            remove it from the hashtable too
        }
    }
}

哈希表允许您快速按名称查找节点,链表允许您按使用顺序维护它们。由于它们指向相同的节点,因此您可以在它们之间切换。这使您可以按名称查找文件,但之后在列表中移动它。

但我对所有这些都完全错了。

答案 1 :(得分:2)

如果您正在使用Linux,我认为操作系统将满足您的所有需求,特别是如果您利用fadvise系统调用让系统知道您计划下一步使用哪些文件。

答案 2 :(得分:1)

koders.com找到了一些;最容易适应和重用的那个(如果你的许可条件没问题的话)似乎是FreeType项目中的this one(需要考虑一下,嗯,有趣的预处理器工作)。在最坏的情况下,它应该向您展示一种方法,您可以在C中实现LRU缓存。

当然,大多数可重复使用的LRU缓存实现(网上有很多可用的)使用更强大的数据结构(通常是内存)的更易用的语言(Java,C ++,C#,Python ......)管理。

答案 3 :(得分:1)

您似乎可以构建LRU Cache in C with uthash

我最喜欢uthash的是它是一个简单的头文件,有很多宏,所以你的额外依赖关系保持在最低限度。

答案 4 :(得分:0)

我不知道C中的任何通用unix环境库,但它应该不难实现。

对于代码示例,我建议在那里查看任何gazillion(oi)哈希表实现。无论表使用链表还是树结构进行实际处理,使用某种形式的缓存(例如MRU)并不罕见,因此它可以让您了解实现的外观。一些简单的垃圾收集器和需要页面替换算法的各种软件也值得一看。

基本上,您在访问它们时标记内容并使引用变老。如果你增加访问时间而不是访问项目的每个对等体的年龄,你显然会在访问时保存一个循环并将权重推到到期操作上。你需要做一些简单的分析,以便找到一个关于最近是否足够的一般概念!最近你的任务。当你到达那一点时,你只需相应地更新缓存。