Обобщенный подключаемый шаблон кэширования?

Учитывая, что это один из сложные вещи в информатике, кто-нибудь знает, как настроить подключаемую стратегию кэширования?

То, о чем я думаю, позволило бы мне написать программу с минимальными мыслями о том, что нужно кэшировать (например, использовать какой-то шаблонный шаблон с низкими/бесплатными затратами, который ничего не компилирует везде, где мне может понадобиться кэширование) и затем, когда дела пойдут дальше и я знаю, где мне нужно кэширование, я могу добавить его, не внося инвазивных изменений в код.

В качестве идеи для решения, которое я ищу; Я работаю с языком программирования D (но наполовину разумный C++ был бы в порядке), и мне нравится шаблон .


person BCS    schedule 27.04.2010    source источник
comment
Кэширование чего? Где? В таком виде вопрос не имеет смысла.   -  person    schedule 27.04.2010
comment
Для меня этот вопрос имеет смысл, Нил. Возможно, это следует пометить как универсальное программирование?   -  person Vladimir Panteleev    schedule 27.04.2010
comment
@Нил. Кэширование возвращаемого значения функции. Кроме того, не делайте никаких предположений: это может быть чистая функция, а может и нет. Это может быть загрузка данных из БД или веб-страницы, или просто с локального диска, или просто вычисление их на лету. Это может быть даже что-то, что не может быть кэшировано (единственный способ определить, устарело ли значение, — это снова получить значение) или нет. Решение должно быть в состоянии иметь дело с любым из вышеперечисленных в любой комбинации.   -  person BCS    schedule 27.04.2010
comment
@BCS Разве этот комментарий не должен быть частью вопроса?   -  person    schedule 27.04.2010
comment
То, что я сказал вкратце, предполагает, что я ничего не сказал. Мне действительно нужно добавить это?   -  person BCS    schedule 27.04.2010
comment
@BCS Является ли это кэшированием возвращаемого значения в строгом смысле, то есть как насчет функций с выводами в списке параметров?   -  person academicRobot    schedule 19.05.2010
comment
@academicRobot, да, возвращаемое значение или, в идеале, любое другое выражение   -  person BCS    schedule 19.05.2010


Ответы (4)


Ближайшая вещь, которая приходит мне на ум, это мемоизация для чистых функций. Возможно, вас также заинтересует эта книга Pattern Oriented Software Architecture Patterns Управление, в котором есть шаблон кэширования.

person Gabriel Ščerbák    schedule 27.04.2010

есть решение С++ 0x для общего автоматического запоминания (см. ответ здесь: Каковы разумные способы улучшить решение рекурсивных задач? )

person Dmitry Ledentsov    schedule 28.07.2011

Вам может быть интересно узнать, как Drizzle справляется с подобными задачами с различными системами хранения и кэширования. В двух словах, он предоставляет интерфейс, который может использоваться родительским приложением для взаимодействия с MySQL, memcached и т. д.

person Nick Gerakines    schedule 11.05.2010
comment
Это может быть интересно, но я больше думал о том, что происходит внутри приложения. - person BCS; 12.05.2010

Я не уверен, в какой степени решение должно быть «обобщенным» и «подключаемым», но если вы можете позволить себе рефакторинг использования ваших кешей (замена вызовов функций прямым использованием некоторой переменной), то рассмотрите следующее:

//works for any CopyConstructible type of cache and any function 
//which result should be cached 
//(the arguments of the function have to be properly binded)
/**
* caching + lazy initialization
* we shouldn't allow copying of lazy<T>, because every copy initializes its own cache
* and this is not what intended most of the time
* T must be CopyConstructible
*/
template<class T>
class lazy: private boost::noncopyable
{
public:
    lazy(boost::function0<T> _creator)
        : creator(_creator) {}
    /**
    * aka is_cashed
    */
    bool is_initialized()
    {
        return val;
    }
    operator T&()
    {
        if(!val)
            val = creator();
        return *val;
    }
    T& operator*()
    {
        if(!val)
            val = creator();
        return *val;
    }
    /**
    * resets cache to update it next time it is used
    */
    void reset()
    {
        val.reset();
    }
private:
    boost::function0<T> creator;
    boost::optional<T> val;
};
//usage
    //initialize caching and updating strategy
    lazy<WebPage> cached_page(boost::bind(&Server::getPage, server));
    server->OnPageUpdate = boost::bind(&OnPageUpdate, cached_page);
    .....

    //use cached_page everywhere as if it were regular variable of WebPage type
    showPage(cached_page);
//--------------
void OnPageUpdate(lazy<WebPage>& page)
{
    page.reset();
}

Если вы хотите убрать ленивую инициализацию, то модифицируйте так, чтобы кеш создавался в конструкторе и методе reset().

person Alsk    schedule 13.05.2010