【问题标题】:Generalized plugable caching pattern?通用的可插入缓存模式?
【发布时间】:2023-03-03 01:57:01
【问题描述】:

鉴于它是the hard things in computer science 之一,有人知道设置可插入缓存策略的方法吗?

我所想的将允许我编写一个程序,而无需考虑需要缓存的内容(即使用某种样板、低成本/无成本的模式,在我可能想要的任何地方编译成任何东西缓存),然后当事情进展得更远并且我知道我需要缓存的位置时,我可以在不进行侵入性代码更改的情况下添加它。

作为我正在寻找的解决方案的一个想法;我正在使用D programing language(但半理智的 C++ 就可以了),我喜欢模板。

【问题讨论】:

  • 缓存什么样的东西?在哪里?就目前而言,这个问题毫无意义。
  • 这个问题对我来说很有意义,尼尔。也许这应该被标记为“通用编程”?
  • @Neil。 缓存函数的返回值。 除此之外,不要做任何假设:它可能是一个纯函数,也可能不是。它可能是从数据库或网页加载数据,或者只是从本地磁盘加载数据,或者只是动态计算。它甚至可能是无法缓存的东西(判断该值是否过时的唯一方法是再次获取该值)。解决方案必须能够以任意组合方式处理上述所有问题。
  • @BCS 该评论不应该成为问题的一部分吗?
  • 我所说的简而言之就是“假设我没有说什么”。我真的需要添加吗?

标签: c++ design-patterns caching d


【解决方案1】:

我想到的最接近的事情是纯函数的记忆。 这本书Pattern Oriented Software Architecture Patterns Management 可能对您来说也很有趣,其中包含缓存模式。

【讨论】:

    【解决方案2】:

    有一个通用自动记忆的 c++0x 解决方案(请参阅此处的答案:What are reasonable ways to improve solving recursive problems?)

    【讨论】:

      【解决方案3】:

      您可能对Drizzle 如何使用不同的存储和缓存后端进行此类操作感兴趣。简而言之,它提供了一个接口,父应用可以使用该接口与 MySQL、memcached 等进行交互。

      【讨论】:

      • 这可能很有趣,但我想更多的是在应用程序内部。
      【解决方案4】:

      我不确定解决方案必须“通用”和“可插入”到何种程度,但如果您能够负担得起对缓存使用的重构(用直接使用某些变量来替换函数调用),那么请考虑以下:

      //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()中创建缓存。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-11-18
        • 1970-01-01
        • 2017-08-20
        • 2016-04-20
        • 2014-06-21
        • 2016-09-21
        • 2014-05-01
        相关资源
        最近更新 更多