LRU手法を使用してキャッシュ置換を実装する必要があるC++コードがあります。
これまでのところ、LRUキャッシュ置換を実装する2つの方法を知っています。
では、これらのうちどれが量産コードで使用するのに適していますか?
彼らの他のより良い方法はありますか?
最近、私はハッシュマップに広がるリンクリストを使用してLRUキャッシュを実装しました。
/// Typedef for URL/Entry pair
typedef std::pair< std::string, Entry > EntryPair;
/// Typedef for Cache list
typedef std::list< EntryPair > CacheList;
/// Typedef for URL-indexed map into the CacheList
typedef boost::unordered_map< std::string, CacheList::iterator > CacheMap;
/// Cache LRU list
CacheList mCacheList;
/// Cache map into the list
CacheMap mCacheMap;
すべての重要な操作に対してO(1)であるという利点があります。
挿入アルゴリズム:
// create new entry
Entry iEntry( ... );
// Push it to the front;
mCacheList.Push_front( std::make_pair( aURL, iEntry ) );
// add it to the cache map
mCacheMap[ aURL ] = mCacheList.begin();
// increase count of entries
mEntries++;
// check if it's time to remove the last element
if ( mEntries > mMaxEntries )
{
// erease from the map the last cache list element
mCacheMap.erase( mCacheList.back().first );
// erase it from the list
mCacheList.pop_back();
// decrease count
mEntries--;
}
これは、LRUキャッシュの非常に単純な実装です。
https://github.com/lamerman/cpp-lru-cache 。
それは使いやすく、それがどのように機能するかを理解しています。コードの合計サイズは約50行です。
簡単にするために、BoostのMultiIndexマップの使用を検討する必要があるかもしれません。キーをデータから分離する場合、同じデータで複数のキーのセットをサポートします。
"... 2つのインデックスを使用:1)キーで値を検索するためにハッシュされる2)最後に最近使用されたアイテムを追跡するためにシーケンシャル(get関数は、シーケンス内の最後のアイテムとしてアイテムを置く。キャッシュからいくつかのアイテムを削除する必要がある場合、それらを削除することができますシーケンスの最初から)。」
「プロジェクト」演算子は、「プログラマーが同じmulti_index_containerの異なるインデックス間を効率的に移動できるようにする」ことに注意してください。
この 記事 は、STLコンテナーのペア(Key-Valueマップとキーアクセス履歴のリスト)、または単一のboost::bimap
を使用した実装について説明しています。
本番環境では、 Linuxカーネルリンクリスト に類似したC++ダブルリンクリストを使用します。オブジェクトのリンクリストに好きなだけオブジェクトを追加でき、リストの操作が速くて簡単であるというのが優れています。