LCOV - code coverage report
Current view: top level - utilities/include/mcrl2/utilities - cache_policy.h (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 9 25 36.0 %
Date: 2020-02-21 00:44:40 Functions: 4 8 50.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Author(s): Maurice Laveaux
       2             : // Copyright: see the accompanying file COPYING or copy at
       3             : // https://github.com/mCRL2org/mCRL2/blob/master/COPYING
       4             : //
       5             : // Distributed under the Boost Software License, Version 1.0.
       6             : // (See accompanying file LICENSE_1_0.txt or copy at
       7             : // http://www.boost.org/LICENSE_1_0.txt)
       8             : //
       9             : 
      10             : #ifndef MCRL2_UTILITIES_CACHE_POLICY_H
      11             : #define MCRL2_UTILITIES_CACHE_POLICY_H
      12             : 
      13             : #include <forward_list>
      14             : 
      15             : #include <cassert>
      16             : 
      17             : namespace mcrl2
      18             : {
      19             : namespace utilities
      20             : {
      21             : 
      22             : /// \brief An interface to implement a replacement policy for the fixed_size_cache.
      23             : template<typename Map>
      24           1 : class replacement_policy
      25             : {
      26             : public:
      27             :   using key_type = typename Map::key_type;
      28             :   using map_type = Map;
      29             : 
      30             : protected:
      31             :   /// \brief Called whenever the underlying cache is cleared.
      32             :   virtual void clear() = 0;
      33             : 
      34             :   /// \brief Called whenever a new element has been inserted into the cache.
      35             :   virtual void inserted(const key_type& key) = 0;
      36             : 
      37             :   /// \returns An iterator to the key that should be replaced when the cache is full.
      38             :   virtual typename Map::iterator replacement_candidate(Map& map) = 0;
      39             : 
      40             :   /// \brief Called whenever an element was found in the cache.
      41             :   virtual void touch(const key_type& key) = 0;
      42             : };
      43             : 
      44             : /// \brief A policy that replaces an arbitrary (but not random) element.
      45             : template<typename Map>
      46             : class no_policy final : public replacement_policy<Map>
      47             : {
      48             : public:
      49             :   using key_type = typename Map::key_type;
      50             : 
      51             :   typename Map::iterator replacement_candidate(Map& map) override { return map.begin(); }
      52             : 
      53             :   // Not implemented.
      54             :   void clear() override {}
      55             :   void inserted(const key_type&) override {}
      56             :   void touch(const key_type&) override {}
      57             : };
      58             : 
      59             : template<typename Map>
      60           1 : class fifo_policy final : public replacement_policy<Map>
      61             : {
      62             : public:
      63             :   using key_type = typename Map::key_type;
      64             : 
      65           1 :   fifo_policy()
      66           1 :   {
      67           1 :     m_last_element_it = m_queue.before_begin();
      68           1 :   }
      69             : 
      70             :   fifo_policy(const fifo_policy& other)
      71             :     : m_queue(other.m_queue)
      72             :   {
      73             :     update_last_element_it();
      74             :   }
      75             : 
      76             :   fifo_policy& operator=(const fifo_policy& other)
      77             :   {
      78             :     m_queue = other.m_queue;
      79             :     update_last_element_it();
      80             :     return *this;
      81             :   }
      82             : 
      83             :   // These moves work when moving m_queue guarantees that m_last_element_it remains valid.
      84             :   fifo_policy(fifo_policy&& other) noexcept = default;
      85             :   fifo_policy& operator=(fifo_policy&& other) noexcept = default;
      86             : 
      87           0 :   void clear() override
      88             :   {
      89           0 :     m_queue.clear();
      90           0 :     update_last_element_it();
      91           0 :   }
      92             : 
      93           0 :   typename Map::iterator replacement_candidate(Map& map) override
      94             :   {
      95           0 :     assert(!m_queue.empty());
      96             :     // Remove the first key (the first one to be inserted into the queue).
      97           0 :     auto it = map.find(m_queue.front());
      98           0 :     m_queue.erase_after(m_queue.before_begin());
      99           0 :     assert(it != map.end());
     100           0 :     return it;
     101             :   }
     102             : 
     103         100 :   void inserted(const key_type& key) override
     104             :   {
     105             :     // A new key was inserted, so it must be the last one to be removed.
     106         100 :     m_last_element_it = m_queue.insert_after(m_last_element_it, key);
     107         100 :   }
     108             : 
     109           0 :   void touch(const key_type&) override
     110           0 :   {}
     111             : 
     112             : private:
     113           0 :   void update_last_element_it()
     114             :   {
     115             :     // Update the iterator to the last element of the queue.
     116           0 :     for (auto it = m_queue.before_begin(); it != m_queue.end(); ++it)
     117             :     {
     118           0 :       m_last_element_it = it;
     119             :     }
     120           0 :   }
     121             : 
     122             :   std::forward_list<key_type> m_queue;
     123             :   typename std::forward_list<key_type>::iterator m_last_element_it;
     124             : };
     125             : 
     126             : } // namespace utilities
     127             : } // namespace mcrl2
     128             : 
     129             : #endif // MCRL2_UTILITIES_CACHE_POLICY_H

Generated by: LCOV version 1.13