web-dev-qa-db-ja.com

量産コードでのLRUの実装

LRU手法を使用してキャッシュ置換を実装する必要があるC++コードがあります。
これまでのところ、LRUキャッシュ置換を実装する2つの方法を知っています。

  1. キャッシュされたデータがアクセスされるたびにtimeStampを使用し、最後に置換時のtimeStampを比較します。
  2. キャッシュされたアイテムのスタックを使用し、最近アクセスされた場合は一番上に移動するため、最後に一番下にLRU候補が含まれます。

では、これらのうちどれが量産コードで使用するのに適していますか?
彼らの他のより良い方法はありますか?

29
sud03r

最近、私はハッシュマップに広がるリンクリストを使用して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--;
}
39

これは、LRUキャッシュの非常に単純な実装です。

https://github.com/lamerman/cpp-lru-cache

それは使いやすく、それがどのように機能するかを理解しています。コードの合計サイズは約50行です。

10

簡単にするために、BoostのMultiIndexマップの使用を検討する必要があるかもしれません。キーをデータから分離する場合、同じデータで複数のキーのセットをサポートします。

[ http://old.nabble.com/realization-of-Last-Recently-Used-cache-with-boost%3A%3Amulti_index-td22326432.html ]から:

"... 2つのインデックスを使用:1)キーで値を検索するためにハッシュされる2)最後に最近使用されたアイテムを追跡するためにシーケンシャル(get関数は、シーケンス内の最後のアイテムとしてアイテムを置く。キャッシュからいくつかのアイテムを削除する必要がある場合、それらを削除することができますシーケンスの最初から)。」

「プロジェクト」演算子は、「プログラマーが同じmulti_index_containerの異なるインデックス間を効率的に移動できるようにする」ことに注意してください。

6
William Wong

この 記事 は、STLコンテナーのペア(Key-Valueマップとキーアクセス履歴のリスト)、または単一のboost::bimapを使用した実装について説明しています。

4
timday

本番環境では、 Linuxカーネルリンクリスト に類似したC++ダブルリンクリストを使用します。オブジェクトのリンクリストに好きなだけオブジェクトを追加でき、リストの操作が速くて簡単であるというのが優れています。

2
grokus