blob: 802f64b01e434e1c7eae692640aca5f6959bfd0e [file] [log] [blame]
Jeff Thompsonfa306642013-06-17 15:06:57 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2013, Regents of the University of California
4 * Alexander Afanasyev
5 *
6 * BSD license, See the LICENSE file for more information
7 *
8 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
9 */
10
11#ifndef LFU_POLICY_H_
12#define LFU_POLICY_H_
13
14#include <boost/intrusive/options.hpp>
15#include <boost/intrusive/set.hpp>
16
17namespace ndn {
18namespace trie {
19
20/**
21 * @brief Traits for LFU replacement policy
22 */
23struct lfu_policy_traits
24{
25 /// @brief Name that can be used to identify the policy (e.g., for logging)
26 static std::string GetName () { return "Lfu"; }
27
28 struct policy_hook_type : public boost::intrusive::set_member_hook<> { double frequency; };
29
30 template<class Container>
31 struct container_hook
32 {
33 typedef boost::intrusive::member_hook< Container,
34 policy_hook_type,
35 &Container::policy_hook_ > type;
36 };
37
38 template<class Base,
39 class Container,
40 class Hook>
41 struct policy
42 {
43 static double& get_order (typename Container::iterator item)
44 {
45 return static_cast<policy_hook_type*>
46 (policy_container::value_traits::to_node_ptr(*item))->frequency;
47 }
48
49 static const double& get_order (typename Container::const_iterator item)
50 {
51 return static_cast<const policy_hook_type*>
52 (policy_container::value_traits::to_node_ptr(*item))->frequency;
53 }
54
55 template<class Key>
56 struct MemberHookLess
57 {
58 bool operator () (const Key &a, const Key &b) const
59 {
60 return get_order (&a) < get_order (&b);
61 }
62 };
63
64 typedef boost::intrusive::multiset< Container,
65 boost::intrusive::compare< MemberHookLess< Container > >,
66 Hook > policy_container;
67
68 // could be just typedef
69 class type : public policy_container
70 {
71 public:
72 typedef policy policy_base; // to get access to get_order methods from outside
73 typedef Container parent_trie;
74
75 type (Base &base)
76 : base_ (base)
77 , max_size_ (100)
78 {
79 }
80
81 inline void
82 update (typename parent_trie::iterator item)
83 {
84 policy_container::erase (policy_container::s_iterator_to (*item));
85 get_order (item) += 1;
86 policy_container::insert (*item);
87 }
88
89 inline bool
90 insert (typename parent_trie::iterator item)
91 {
92 get_order (item) = 0;
93
94 if (max_size_ != 0 && policy_container::size () >= max_size_)
95 {
96 // this erases the "least frequently used item" from cache
97 base_.erase (&(*policy_container::begin ()));
98 }
99
100 policy_container::insert (*item);
101 return true;
102 }
103
104 inline void
105 lookup (typename parent_trie::iterator item)
106 {
107 policy_container::erase (policy_container::s_iterator_to (*item));
108 get_order (item) += 1;
109 policy_container::insert (*item);
110 }
111
112 inline void
113 erase (typename parent_trie::iterator item)
114 {
115 policy_container::erase (policy_container::s_iterator_to (*item));
116 }
117
118 inline void
119 clear ()
120 {
121 policy_container::clear ();
122 }
123
124 inline void
125 set_max_size (size_t max_size)
126 {
127 max_size_ = max_size;
128 }
129
130 inline size_t
131 get_max_size () const
132 {
133 return max_size_;
134 }
135
136 private:
137 type () : base_(*((Base*)0)) { };
138
139 private:
140 Base &base_;
141 size_t max_size_;
142 };
143 };
144};
145
146} // trie
147} // ndn
148
149#endif // LFU_POLICY_H