2008-09-23 2 views
12

Кто-нибудь знает какую-либо реализацию шаблонного кеша объектов?Общий кеш объектов

  • Вы используете ключ, чтобы найти объект (такой же, как и в станд :: Карта <>)
  • Можно указать максимальное количество объектов, которые могут находиться в кэше в то же время
  • Есть средства для создания объекта не найден в кэше
  • Есть средства, чтобы знать, когда объект отбрасывается из кэша

Например:

typedef cache<int, MyObj*> MyCache; 
MyCache oCache; 
oCache.SetSize(1); 
oCache.Insert(make_pair(1, new MyObj()); 
oCache.Touch(1); 
MyObj* oldObj = oCache.Delete(1); 

... 

Это может быть так же просто, как кеш LRU или MRU.

Любые предложения приветствуются!

Nic

ответ

-6

В приложении я с трудом могу себе представить, что скорость будет/повысить до производительности для хранения объектов, которые, по-видимому может быть вновь созданные (бедра: так как они могут быть автоматически отбрасывается, когда вершина кэша). Для кэша sw требуется набор из памяти через код ассоциативности, что, конечно, медленнее, чем распределение памяти и запуск конструктора (в основном, инициализация памяти).

За исключением ручной настройки пользователя, чтобы избежать механизма подкачки (именно для повышения производительности, кстати), большинство ОС «кэширует» память для вас на диске ... это «пейджинг», форма «дорогостоящая» кеширование ", потому что ничего не выбрасывается, и это делается конкретным HW, подразделением обработки под названием Memory Management Unit ...

Кэширующий код на большой картинке будет замедлять процессы, будучи избыточными.

+0

Что делать, если (повторное) создание объекта происходит намного медленнее, чем поиск ключа-> значения? Не каждый конструктор является «главным образом инициализацией памяти». – moswald 2008-09-23 22:10:29

+0

Я понимаю, почему downvote: я не отвечаю. Итак, я пытаюсь его получить: Теперь MMU будет отмечать память, содержащую неработающие кешированные объекты, как низкоуровневые, поэтому кандидат должен быть отправлен в файл-страницу на жестком диске ... при условии, что есть HDD. Таким образом, повторное извлечение отсутствующего кэшированного объекта с жесткого диска, iso running code для воссоздания объекта, будет только в очень громоздком множестве обстоятельств «правильным». @Nicolas: Каковы ваши конкретные обстоятельства? – jpinto3912 2010-06-22 19:55:59

1

Ive сколотить относительно простой кэш LRU, построенный из карты и связанного списка:

template<typename K, typename V, typename Map = std::unordered_map<K, typename std::list<K>::iterator>> 
class LRUCache 
{ 
    size_t maxSize; 
    Map data; 
    std::list<K> usageOrder; 
    std::function<void(std::pair<K, V>)> onEject = [](std::pair<K, V> x){}; 

    void moveToFront(typename std::list<K>::iterator itr) 
    { 
     if(itr != usageOrder.begin()) 
      usageOrder.splice(usageOrder.begin(), usageOrder, itr); 
    } 


    void trimToSize() 
    { 
     while(data.size() > maxSize) 
     { 
      auto itr = data.find(usageOrder.back()); 

      onEject(std::pair<K, V>(itr->first, *(itr->second))); 
      data.erase(usageOrder.back()); 
      usageOrder.erase(--usageOrder.end()); 
     } 
    } 

public: 
    typedef std::pair<const K, V> value_type; 
    typedef K key_type; 
    typedef V mapped_type; 


    LRUCache(size_t maxEntries) : maxSize(maxEntries) 
    { 
     data.reserve(maxEntries); 
    } 

    size_t size() const 
    { 
     return data.size(); 
    } 

    void insert(const value_type& v) 
    { 
     usageOrder.push_front(v.first); 
     data.insert(typename Map::value_type(v.first, usageOrder.begin())); 

     trimToSize(); 
    } 

    bool contains(const K& k) const 
    { 
     return data.count(k) != 0; 
    } 

    V& at(const K& k) 
    { 
     auto itr = data.at(k); 
     moveToFront(itr); 
     return *itr; 
    } 


    void setMaxEntries(size_t maxEntries) 
    { 
     maxSize = maxEntries; 
     trimToSize(); 
    } 

    void touch(const K& k) 
    { 
     at(k); 
    } 

    template<typename Compute> 
    V& getOrCompute(const K& k) 
    { 
     if(!data.contains(k)) insert(value_type(k, Compute())); 
     return(at(k)); 
    } 

    void setOnEject(decltype(onEject) f) 
    { 
     onEject = f; 
    } 
}; 

Что я считаю, соответствует вашим критериям. Что-нибудь нужно добавить или изменить?

Смежные вопросы