Учитывая, что это - одна из твердых вещей в информатике, кто-либо знает о способе настроить сменную стратегию кэширования?
То, о чем я думаю, позволило бы мне писать программу с минимальной мыслью относительно того, какие потребности кэшироваться (e.i. используют своего рода шаблон, низко/нет стоят шаблона, который ни во что не компилирует далеко нигде, я мог бы хотеть кэшировать), и затем когда вещи далее приезжают, и я знаю, где мне нужно кэширование, я могу включить его, не внося агрессивные изменения кода.
Как идея виду решения я ищу; я работаю с D программирование языка (но промежуточный нормальный C++ был бы прекрасен), и мне нравится шаблон.
Больше всего мне на ум приходит мемоизация для чистых функций. Возможно, вас также заинтересует эта книга Pattern Ориентированное управление шаблонами архитектуры программного обеспечения , в котором есть шаблон кэширования.
Возможно, вам будет интересно узнать, как Drizzle делает подобные вещи с различными бэкендами хранения и кэширования. В двух словах, он предоставляет интерфейс, который может быть использован родительским приложением для взаимодействия с MySQL, memcached и т.д.
Я не уверен, до какой степени решение должно быть «обобщенным» и «подключаемым», но если вы можете позволить себе рефакторинг использования ваших кешей ( заменяя вызовы функций прямым использованием некоторой переменной), тогда рассмотрите следующее:
//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 ().