LRUCache - C++

作者: ccsexyz | 来源:发表于2016-03-16 15:05 被阅读338次

LRUCache是一种常用的缓存替换算法,其原理是根据使用率淘汰数据,一般会实现为一个队列,如果一个cache命中,则将这个数据移动到队列的头部,这样,不经常使用的cache就会逐渐移向队列尾部,当cache容量满时,就从队列尾部取出一个数据丢掉。总的来说,涉及到了数据在头部插入、尾部移除、随机取出数据这样几个主要的操作,所以双向链表是一个不错的选择。但是我们再考虑到这样一个问题:如果直接使用LinkedList,从Cache中取数据时每次都要遍历队列,无谓的消耗了大量时间,所以我们自然而然的加上了HashMap,HashMap中存储了指向LinkedList的指针,这样就可以保证在O(1)的访问复杂度。一个具体的实现如下(C++):


template<typename Key, typename Value>
class LRUCache {
public:
    // err为当cache查找失败时返回的值
    LRUCache(int capacity, Value err) {
        err_ = err;
        capacity_ = capacity;
        head_.next = &tail_;
        tail_.prev = &head_;
    }

    Value get(Key key) {
        auto it = vmap_.find(key);
        if(it == vmap_.end()) {
            return err_;
        } else {
            Cache *c = it->second;
            move_cache_to_head(c);
            return c->value;
        }
    }

    void set(Key key, Value value) {
        auto it = vmap_.find(key);
        if(it != vmap_.end()) {
            Cache *c = it->second;
            c->value = value;
            move_cache_to_head(c);
        } else {
            if(capacity_ == vmap_.size()) {
                Cache *c = remove_last_cache();
                vmap_.erase(c->key);
                c->key = key;
                c->value = value;
                cache_push(c);
                vmap_[key] = c;
            } else {
                Cache *c = new Cache(key, value);
                cache_push(c);
                vmap_[key] = c;
            }
        }
    }

private:
    struct Cache {
        Cache() = default;
        Cache(Key key, Value value) : key(key), value(value) {}
        Key key;
        Value value;
        Cache *prev;
        Cache *next;
    };

    void cache_push(Cache *c) {
        c->next = head_.next;
        head_.next = c;
        c->next->prev = c;
        c->prev = &head_;
    }

    void cache_push(Key key, Value value) {
        Cache *c = new Cache(key, value);
        cache_push(c);
    }

    void move_cache_to_head(Cache *c) {
        c->prev->next = c->next;
        c->next->prev = c->prev;
        cache_push(c);
    }

    Cache *remove_last_cache() {
        Cache *c = tail_.prev;
        tail_.prev = c->prev;
        c->prev->next = &tail_;
        return c;
    }

private:
    Cache head_;
    Cache tail_;
    Value err_;
    int capacity_;
    unordered_map<Key, Cache *> vmap_;
};

其中capacity为Cache容量,err为查找失败时默认的返回值,比如cache的数据类型为int,容量为10,查找失败时返回-1,则LRUCache的定义如下:


LRUCache<int, int> lru(10, -1);

相关文章

  • LRUCache - C++

    LRUCache是一种常用的缓存替换算法,其原理是根据使用率淘汰数据,一般会实现为一个队列,如果一个cache命中...

  • LruCache

    LruCache的使用 LruCache部分源码解析 LruCache 利用 LinkedHashMap 的一个特...

  • Android-Glide源码解析

    一、LruCache 要分析Glide的源码,首先就需要分析LruCache。LruCache是基于LinkedH...

  • Java基础_LruCache工作原理

    本文主要从如下节点讲解 LRU算法简介 LruCache的简介 LruCache的代码实操 LruCache的原理...

  • Glide解析(一) - LruCache

    本文介绍的内容有 LruCache算法思想介绍 v4包中LruCache中源码解析 LruCache算法思想介绍 ...

  • (1)LruCache原理分析

    浅析LruCache原理 Android用LruCache(Least recently use Cache 意...

  • Android LruCache解析

    title: LruCache解析date: 2016-03-29tags: LruChche LruCache ...

  • Android缓存(一)内存缓存LruCache

    LruCache LruCache是Android3.1提供的缓存类,并且在v4包提供了该类。LruCache是一...

  • Android缓存原理

    本文主要内容 LruCache使用 LruCache原理 DiskLruCache使用 DiskLruCache原...

  • 面试题

    LruCache原理 LruCache 即最近最少使用内存(Least recently usage cache)...

网友评论

    本文标题:LRUCache - C++

    本文链接:https://www.haomeiwen.com/subject/isiqlttx.html