Advertisement
bogolyubskiyalexey

interview cache (mail.ru)

Jun 13th, 2021
1,808
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.33 KB | None | 0 0
  1. #ifndef LIBUTIL_LRU_CACHE_HPP__
  2. #define LIBUTIL_LRU_CACHE_HPP__
  3.  
  4. #include <unordered_map>
  5.  
  6. namespace libutil
  7. {
  8.  
  9.     template< class Tkey, class TItem >
  10.     class LastUsedCache
  11.     {
  12.         struct record_t
  13.         {
  14.             TItem data;
  15.             uint64_t gen;
  16.         };
  17.  
  18.  
  19.  
  20.         typedef std::unordered_map< Tkey, record_t > cache_t;
  21.         std::map<uint64_t, const Tkey* const> gen_to_key_;
  22.         cache_t cache_;
  23.         size_t max_size_;
  24.         uint64_t generation_;
  25.  
  26.     public:
  27.         LastUsedCache( size_t nelems )
  28.         :   max_size_(nelems),
  29.             generation_( 0 )
  30.         {}
  31.  
  32.        
  33.         bool find( Tkey key, TItem *item = NULL ) const
  34.         {
  35.             typename cache_t::const_iterator it = cache_.find( key );
  36.  
  37.             if (it == cache_.end())
  38.                 return false;
  39.             else
  40.             {
  41.                 if (item)
  42.                     *item = it->second.data;
  43.                 return true;
  44.             }
  45.         }
  46.  
  47.        
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.         void insert( Tkey key, const TItem &data )
  58.         {
  59.             if (max_size_ != 0U)
  60.             {
  61.                 record_t rec{ data, ++ generation_ };
  62.  
  63.                 std::pair< typename cache_t::iterator, bool > result =
  64.                     cache_.insert( typename cache_t::value_type( key, rec ) );
  65.  
  66.                 if (result.second)
  67.                 {
  68.                     if (cache_.size() > max_size_)
  69.                     {
  70.                         auto it = gen_to_key_.begin();
  71.                         cache_.erase(*it->second);
  72.                         gen_to_key_.erase(it);
  73.                     }
  74.                 }
  75.                 else
  76.                 {
  77.                     gen_to_key.erase(result.first->second.gen);
  78.                     result.first->second = rec;
  79.                     gen_to_key.emplace(result.first->second.gen, &result.first->first);
  80.                 }
  81.             }
  82.         }
  83.  
  84.         size_t size() const
  85.         {
  86.             return cache_.size();
  87.         }
  88.  
  89.         bool empty() const
  90.         {
  91.             return (size() == 0);
  92.         }
  93.  
  94.         void clear()  
  95.         {
  96.             cache_.clear();
  97.             gen_to_key_.clear();
  98.             generation_ = 0;
  99.         }
  100.     };
  101.  
  102. } // namespace libutil
  103.  
  104. #endif LIBUTIL_LRU_CACHE_HPP__
  105.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement