concurrent_lru_cache模板类

汇总

最近最少使用缓存的并发操作的模板类

语法

template <typename key_type, typename value_type, typename value_functor_type = value_type (*)(key_type) >
 class concurrent_lru_cache;

头文件

#define TBB_PREVIEW_CONCURRENT_LRU_CACHE 1
 #include "tbb/concurrent_lru_cache.h"

描述

concurrent_lru_cache container maps keys to values with the ability to limit the number of stored unused objects. There is at most one element in the container for each key.

The container permits multiple threads to concurrently retrieve items from it.

The container tracks the lifetime of retrieved items by returning a proxy object instead of a real value.

The container stores all the items that are currently in use and a limited number of unused items. Extra items are removed in a least recently used manner.

When no item is found for a key, the container calls the user provided function object to get a needed value and inserts it. The functor object must be thread safe.

成员函数

namespace tbb {
 template <typename key_type,
 typename value_type,
 typename value_functor_type = value_type (*)(key_type) >
 class concurrent_lru_cache{
 private:
 class handle_object;
 public:
 typedef handle_object handle;
 public:
 concurrent_lru_cache(value_functor_type f,std::size_t number_of_lru_history_items);
 handle_object operator()(key_type k);
 private:
 struct handle_move_t;
 class handle_object {
 public:
 handle_object(handle_move_t m);
 operator handle_move_t();
 value_type& value();
 ~handle_object();
 friend handle_move_t move(handle_object& h);
 private:
 void operator=(handle_object&);
 handle_object(handle_object &);
 };
};
 }
The following table provides additional information on the members of this template class.
Member Description
concurrent_lru_cache(value_function_type f,std::size_tnumber_of_lru_history_items);

Constructs an empty cache with a number_of_lru_history_items maximum number of stored unused objects, and f function object returning new values.

handle_object operator[](key_type k)

Search the container for a pair with given key. If the pair is not found, the user provided function object is called to get the value and insert it into the container.

Returnshandle_object pointing to the matching value.

~ concurrent_lru_cache ()

Destroys all items in the container, and the container itself, so that it can no longer be used.

handle_object class More Info
handle_move_t class

This is an instrumental class to allow certain conversions that allow ownership transfer between instances of handle_object objects. As well it allowshandle_object objects to be passed to and returned from functions. The class has no members other than holding a reference to value object in LRU cache container and a pointer to the container itself.


handle_object class

汇总

提供了读和写访问concurrent_lru_cache值的

语法

template <typename key_type,
 typename value_type,
 typename value_functor_type = value_type (*)(key_type) >
 class concurrent_lru_cache::handle_object {

头文件

#include "tbb/concurrent_lru_cache.h"

描述

handle_object is a (smart handle) proxy object returned by the cache container allowing getting reference to the value.

Live object of this type prevents the container from erasing values while they are being used.

The handle_object does not have copy semantics; instead it only allows transfer of ownership i.e. it semantics is similar to one of std::auto_ptr or move semantics from C++11.

成员函数和独立的功能

namespace tbb {
 template <typename key_type,
 typename value_type,
 typename value_functor_type = value_type (*)(key_type) >
 class concurrent_lru_cache::handle_object {
 public:
 handle_object(handle_move_t m);
 operator handle_move_t();
 value_type& value();
 ~handle_object();
 private:
 void operator=(handle_object&);
 handle_object(handle_object &);
 };
};
 handle_move_t move(handle_object& h);
 }
The following table provides additional information on the members of this template class.
Member Description
handle_object(handle_move_t m)

Constructs an handle_object object from a pointer or from another handle_object (through implicit conversion to handle_move_t object).

Since handle_object objects owns a reference to a value object of LRU cache, when a new handle_object is constructed from anotherhandle_object, the former owner releases the reference ownership (i.e. no longer refers to any value) .

operator handle_move_t()

This method should not be called directly, instead use free standing move function.

Effects: Transfer reference ownership from handle_object objects to temporary handle_move_t object.

Returnshandle_move_t object pointing to the same value object of LRU cache

value_type& value()

Return a reference to value object of LRU cache container.

Returns: Reference to value_type object inside the LRU cache container.

~handle_object()

Release a reference to value object of LRU cache container. It it was the last reference to the value object the container is allowed to evict the value.





// A simple LRU cache written in C++
// Hash map + doubly linked list
#include <iostream>
#include <vector>
#include <ext/hash_map>
using namespace std;
using namespace __gnu_cxx;


template <class K, class T>
struct Node{
    K key;
    T data;
    Node *prev, *next;
};


template <class K, class T>
class LRUCache{
public:
    LRUCache(size_t size){
        entries_ = new Node<K,T>[size];
        for(int i=0; i<size; ++i)// 存储可用结点的地址
            free_entries_.push_back(entries_+i);
        head_ = new Node<K,T>;
        tail_ = new Node<K,T>;
        head_->prev = NULL;
        head_->next = tail_;
        tail_->prev = head_;
        tail_->next = NULL;
    }
    ~LRUCache(){
        delete head_;
        delete tail_;
        delete[] entries_;
    }
    void Put(K key, T data){
        Node<K,T> *node = hashmap_[key];
        if(node){ // node exists
            detach(node);
            node->data = data;
            attach(node);
        }
        else{
            if(free_entries_.empty()){// 可用结点为空,即cache已满
                node = tail_->prev;
                detach(node);
                hashmap_.erase(node->key);
            }
            else{
                node = free_entries_.back();
                free_entries_.pop_back();
            }
            node->key = key;
            node->data = data;
            hashmap_[key] = node;
            attach(node);
        }
    }
    T Get(K key){
        Node<K,T> *node = hashmap_[key];
        if(node){
            detach(node);
            attach(node);
            return node->data;
        }
        else{// 如果cache中没有,返回T的默认值。与hashmap行为一致
            return T();
        }
    }
private:
    // 分离结点
    void detach(Node<K,T>* node){
        node->prev->next = node->next;
        node->next->prev = node->prev;
    }
    // 将结点插入头部
    void attach(Node<K,T>* node){
        node->prev = head_;
        node->next = head_->next;
        head_->next = node;
        node->next->prev = node;
    }
private:
    hash_map<K, Node<K,T>* > hashmap_;
    vector<Node<K,T>* > free_entries_; // 存储可用结点的地址
    Node<K,T> *head_, *tail_;
    Node<K,T> *entries_; // 双向链表中的结点
};


int main(){
    hash_map<int, int> map;
    map[9]= 999;
    cout<<map[9]<<endl;
    cout<<map[10]<<endl;
    LRUCache<int, string> lru_cache(100);
    lru_cache.Put(1, "one");
    cout<<lru_cache.Get(1)<<endl;
    if(lru_cache.Get(2) == "")
        lru_cache.Put(2, "two");
    cout<<lru_cache.Get(2);
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值