青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

red22

通過STL實(shí)現(xiàn)帶LRU的Cache

        開發(fā)互聯(lián)網(wǎng)的server系統(tǒng),難免會(huì)用一些cache機(jī)制,通常在Linux下多使用共享內(nèi)存機(jī)制,把分配的內(nèi)存組織成一個(gè)特定的數(shù)據(jù)結(jié)構(gòu),用來緩存后端DB的數(shù)據(jù),加速讀寫。但是對(duì)一些新手而言,共享內(nèi)存的使用還是有一些門檻,與此同時(shí)STL的使用卻是相對(duì)容易上手,所以可以通過STL的容器組合出一個(gè)cache來。

        上網(wǎng)搜了一下,看到已經(jīng)有人做了一些類似的事情,具體可以參看http://bytes.com/forum/thread640146.html,作者采用STL::map(當(dāng)然也可以是hash_map做數(shù)據(jù)緩存cache),采用一個(gè)list做lru鏈,每當(dāng)讀寫cache中的數(shù)據(jù)時(shí),都要在lru鏈中刪除該key值對(duì)應(yīng)的項(xiàng),并把該數(shù)據(jù)的key值重新放到頭部,這里面有個(gè)相對(duì)較慢的地方就是從lru鏈中刪除key值對(duì)應(yīng)的項(xiàng)的操作,因?yàn)閯h除操作表面看也僅是erase,但是其中也是順序查找出來再刪,相對(duì)耗時(shí)。可以針對(duì)此對(duì)之進(jìn)行改進(jìn)。

         采用STL::map做lru鏈,map::first是一個(gè)“虛時(shí)間”,表示訪問某一個(gè)key的虛時(shí)間,map::second就是key值,同樣另外一個(gè)map做cache緩存數(shù)據(jù),first為key,second為(value,virtual_time)對(duì),這樣當(dāng)讀寫一個(gè)key的數(shù)據(jù)時(shí),可以快速定位到該數(shù)據(jù),并且可以查找到它的上次訪問時(shí)間,從而在lru鏈里面快速定位(樹上的查找終究要快)并刪除,再更新key的訪問時(shí)間并插入到lru鏈中就可以了。

         當(dāng)cache過大了,比如緩存最多100,那么就可以從lru鏈的頭部開始淘汰了,(因?yàn)閘ru鏈first值越小,表示訪問越久了)。代碼貼在下面,歡迎批評(píng)指證。與上面文章里的相比,代碼簡(jiǎn)化了給多,這樣比較方便閱讀,另外考慮到數(shù)據(jù)多是blob,所以cache中的value就采用stl::string了。

         STL做cache的幾個(gè)缺點(diǎn):

        1 由于cache的數(shù)據(jù)在堆棧中,所以server一旦core掉就丟了;

        2 鑒于上述原因,所以這種cache適合“讀多寫少”的業(yè)務(wù),一旦有“寫入”操作,就和數(shù)據(jù)庫同步更新,這樣的話淘汰的時(shí)候也比較簡(jiǎn)單,直接丟掉就好了,不存在“臟數(shù)據(jù)”的概念。

        當(dāng)然,對(duì)于海量用戶訪問的業(yè)務(wù),還是建議用共享內(nèi)存做cache機(jī)制,這樣讀寫的效率都會(huì)提高,并且程序出問題數(shù)據(jù)仍然在,但是壞處就是會(huì)帶來復(fù)雜性和好多其它的問題,就不在這里說了。

#ifndef _MAP_LRU_CACHE_H_
#define _MAP_LRU_CACHE_H_

#include <string.h>

#include <iostream>
#include <list>
#include <map>

using namespace std;

namespace lru_cache {

        static const int DEF_CAPACITY = 100000;

        typedef unsigned long long virtual_time;

        typedef struct _HashKey
        {// key的類型自定義,重要的是要overload <和==

        }HashKey;

        typedef struct _HashValue
        {
                string value_;
                virtual_time access_;
        }HashValue;


        class CLRUCache
        {
                public:

                        CLRUCache() : _lru_list(), _hash_table(), _now(0){}
                        virtual ~CLRUCache(){}

                        int set( const HashKey& key, const string &value );
                        HashValue* get( const HashKey& key );


                        unsigned get_lru_list_size(){ return (unsigned)_lru_list.size(); }
                        unsigned get_hash_table_size() { return (unsigned)_hash_table.size(); }
                        virtual_time get_now() { return _now; }

                 private:

                        virtual_time get_virtual_time()
                        {
                                return ++_now;
                        }

                        map<virtual_time, HashKey>    _lru_list;
                        map<HashKey, HashValue> _hash_table;
                        virtual_time _now;
        };

}
#endif

#include "map_lru_cache.h"

using namespace lru_cache;

int CLRUCache::set( const HashKey& key, const string &value )
{
        HashValue hash_value;
        hash_value.value_ = value;
        hash_value.access_ = get_virtual_time();

        pair< map<HashKey, HashValue>::iterator, bool > ret = _hash_table.insert(make_pair(key, hash_value));

        if ( !ret.second )
        {
                // key already exist
                virtual_time old_access = _hash_table[key].access_;
                map<virtual_time, HashKey>::iterator iter = _lru_list.find(old_access);
                if(iter != _lru_list.end())
                {
                        _lru_list.erase(iter);
                }

                _lru_list.insert(make_pair(hash_value.access_, key));
                _hash_table[key] = hash_value;


        }

        else
        {
                _lru_list.insert(make_pair(hash_value.access_, key));

                if ( _hash_table.size() > DEF_CAPACITY ) //ÌÔÌ­
                {
                        // get the least recently used key
                        map<virtual_time, HashKey>::iterator iter = _lru_list.begin();


                        _hash_table.erase( iter->second );
                        // remove last key from list
                        _lru_list.erase(iter);
                }
        }
        return 0;
}

HashValue* CLRUCache::get( const HashKey& key )
{
        map<HashKey, HashValue>::iterator iter = _hash_table.find(key);
        if ( iter != _hash_table.end() )
        {
                virtual_time old_access = iter->second.access_;
                iter->second.access_ = get_virtual_time();

                map<virtual_time, HashKey>::iterator it = _lru_list.find(old_access);
                if(it != _lru_list.end())
                {
                        _lru_list.erase(it);
                }

                _lru_list.insert(make_pair(iter->second.access_, key));

                return &(iter->second);
        }

        else
                return NULL;
}

posted on 2008-09-22 15:21 red22 閱讀(3646) 評(píng)論(1)  編輯 收藏 引用

Feedback

# re: 通過STL實(shí)現(xiàn)帶LRU的Cache 2015-01-17 15:01 后知后覺

基于C++實(shí)現(xiàn)的LRU的cache  回復(fù)  更多評(píng)論   



只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


My Links

Blog Stats

常用鏈接

留言簿

文章檔案

搜索

最新評(píng)論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久久一区二区三区| 亚洲精品国产精品国产自| 亚洲黄色视屏| 宅男精品视频| 一本一本久久| 99视频精品全部免费在线| 在线观看91精品国产入口| 国产毛片一区二区| 国产精品久久国产精品99gif| 玖玖玖免费嫩草在线影院一区| 久色成人在线| 91久久久久久久久| 裸体丰满少妇做受久久99精品| 亚洲欧美综合另类中字| 午夜亚洲伦理| 国产亚洲欧洲| 国内久久婷婷综合| 亚洲高清不卡一区| 亚洲国产精品激情在线观看| 亚洲动漫精品| av成人动漫| 亚洲一区三区电影在线观看| 午夜精品美女自拍福到在线| 久久超碰97人人做人人爱| 久久不射2019中文字幕| 久久午夜精品| 黄色av一区| 国语自产精品视频在线看抢先版结局 | 亚洲综合清纯丝袜自拍| 亚洲免费播放| 亚洲视频一区| 久久精品夜色噜噜亚洲a∨ | 日韩视频精品在线| 亚洲小说欧美另类社区| 久久久久久国产精品一区| 欧美精品一区在线| 国产欧美一区二区精品秋霞影院| 1024欧美极品| 欧美一区亚洲| 久久夜色精品国产欧美乱极品| 亚洲欧洲精品一区二区三区不卡| 亚洲一区二区在线视频| 欧美专区在线播放| 亚洲国产成人精品久久| 亚洲欧美一级二级三级| 欧美激情91| 黄色免费成人| 欧美一区二区三区的| 亚洲国产精选| 久久精品国产精品| 欧美日韩精品免费观看视频| 一区二区视频免费在线观看| 亚洲一区影院| 亚洲美女在线观看| 美女诱惑黄网站一区| 亚洲最新视频在线播放| 久久精品官网| 亚洲一区二区精品| 欧美日韩国产在线播放| 亚洲大片精品永久免费| 欧美在线视频a| 亚洲小说区图片区| 欧美日韩精品是欧美日韩精品| **性色生活片久久毛片| 久久九九热免费视频| 亚洲免费视频网站| 欧美日韩一区二区三区高清| 91久久久国产精品| 欧美1区2区视频| 亚洲午夜久久久久久久久电影院 | 国产精品日韩专区| 亚洲高清一二三区| 久久国产精品久久精品国产| 亚洲欧美一区二区在线观看| 国产婷婷一区二区| 久久经典综合| 猫咪成人在线观看| 艳妇臀荡乳欲伦亚洲一区| 一区二区三区视频在线| 国产美女搞久久| 免费在线成人| 欧美激情第4页| 亚洲一区久久| 久久精品国产91精品亚洲| 一区视频在线| av不卡在线| 精久久久久久久久久久| 欧美成人自拍视频| 欧美日韩免费观看一区二区三区| 中文精品视频| 性欧美videos另类喷潮| 国产一区二区黄| 久久久五月婷婷| 久久激情综合| 国内精品视频在线播放| 欧美成人在线免费视频| 欧美日韩午夜精品| 在线视频国内自拍亚洲视频| 午夜精品国产| 美女999久久久精品视频| 国产精品视频一区二区三区| 一区二区免费看| 亚洲国产精彩中文乱码av在线播放| 蜜臀av国产精品久久久久| 亚洲欧美日韩精品久久奇米色影视| 欧美韩国日本一区| 亚洲国产精品久久91精品| 久久亚洲综合色| 欧美中文日韩| 狠狠色噜噜狠狠色综合久| 久久激情视频| 欧美一区=区| 国模套图日韩精品一区二区| 国内精品国语自产拍在线观看| 欧美人与性禽动交情品 | aa亚洲婷婷| 欧美破处大片在线视频| 海角社区69精品视频| 欧美成ee人免费视频| 国产午夜精品理论片a级大结局 | 亚洲视频专区在线| 欧美精品二区| 亚洲精品四区| 亚洲一区免费在线观看| 亚洲美女视频| 99国产精品国产精品久久| 欧美国产高潮xxxx1819| av成人福利| 亚洲特级片在线| 国产日韩一区二区三区在线播放| 久久久久国色av免费观看性色| 久久精品麻豆| 亚洲裸体俱乐部裸体舞表演av| 91久久久一线二线三线品牌| 亚洲毛片av在线| 国产精品欧美久久| 久久三级视频| 欧美日韩国产综合在线| 一本色道久久综合亚洲精品小说 | 欧美日韩一区二区三区在线看 | 国产乱码精品一区二区三区不卡| 久久精品在这里| 免费高清在线一区| 亚洲深夜福利网站| 午夜精品一区二区三区在线视 | 亚洲精品免费看| 欧美日韩在线播放三区四区| 欧美日韩免费在线观看| 久久精品电影| 欧美激情2020午夜免费观看| 欧美专区在线观看一区| 欧美aⅴ一区二区三区视频| 亚洲宅男天堂在线观看无病毒| 久久久久久久网站| 亚洲免费影视| 欧美国产专区| 免费观看久久久4p| 欧美三级韩国三级日本三斤| 久久久噜噜噜久久| 亚洲女与黑人做爰| 狠狠色丁香久久婷婷综合丁香| 久久精品国产亚洲aⅴ| 久久久亚洲欧洲日产国码αv | 一区二区三区|亚洲午夜| 国产真实精品久久二三区| 亚洲免费精品| 韩国精品主播一区二区在线观看| 一区二区欧美国产| 亚洲剧情一区二区| 久久久精品国产免费观看同学| 午夜精品视频一区| 欧美成人三级在线| 久久久久久噜噜噜久久久精品| 欧美成人精品在线视频| 久久精品30| 亚洲精品欧美日韩专区| 欧美一区二区在线观看| 久久久91精品国产一区二区三区 | 99精品国产在热久久下载| 精品不卡一区| 久久精品国产综合精品| 久久电影一区| 国产欧美日韩亚州综合| 亚洲一区二区欧美| 亚洲视频在线视频| 欧美日本亚洲| 午夜欧美大尺度福利影院在线看| 久久久www| 亚洲国产精品成人va在线观看| 午夜精品福利视频| 欧美视频第二页| 中文网丁香综合网| 亚洲综合国产| 国产精品久久久久婷婷| 在线视频日韩| 亚洲夜晚福利在线观看| 欧美日本在线播放| 亚洲精品久久久久中文字幕欢迎你 | 99国产精品视频免费观看| 一本久久综合亚洲鲁鲁|