blob: 68137adf93aa29e7f9aef021476888d4204a257c [file] [log] [blame]
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2011-2015 Regents of the University of California.
Alexander Afanasyev41824bd2013-01-23 23:57:59 -08004 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08005 * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
6 * contributors.
Alexander Afanasyev41824bd2013-01-23 23:57:59 -08007 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -08008 * ndnSIM is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080011 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -080012 * ndnSIM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080015 *
Alexander Afanasyev60a7b622014-12-20 17:04:07 -080016 * You should have received a copy of the GNU General Public License along with
17 * ndnSIM, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 **/
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080019
20#ifndef LFU_POLICY_H_
21#define LFU_POLICY_H_
22
23#include <boost/intrusive/options.hpp>
24#include <boost/intrusive/set.hpp>
25
26namespace ns3 {
27namespace ndn {
28namespace ndnSIM {
29
30/**
31 * @brief Traits for LFU replacement policy
32 */
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080033struct lfu_policy_traits {
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080034 /// @brief Name that can be used to identify the policy (for NS-3 object model and logging)
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080035 static std::string
36 GetName()
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080037 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080038 return "Lfu";
39 }
40
41 struct policy_hook_type : public boost::intrusive::set_member_hook<> {
42 double frequency;
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080043 };
44
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080045 template<class Container>
46 struct container_hook {
47 typedef boost::intrusive::member_hook<Container, policy_hook_type, &Container::policy_hook_>
48 type;
49 };
50
51 template<class Base, class Container, class Hook>
52 struct policy {
53 static double&
54 get_order(typename Container::iterator item)
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080055 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080056 return static_cast<policy_hook_type*>(policy_container::value_traits::to_node_ptr(*item))
57 ->frequency;
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080058 }
59
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080060 static const double&
61 get_order(typename Container::const_iterator item)
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080062 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080063 return static_cast<const policy_hook_type*>(
64 policy_container::value_traits::to_node_ptr(*item))->frequency;
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080065 }
66
67 template<class Key>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080068 struct MemberHookLess {
69 bool
70 operator()(const Key& a, const Key& b) const
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080071 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080072 return get_order(&a) < get_order(&b);
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080073 }
74 };
75
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080076 typedef boost::intrusive::multiset<Container,
77 boost::intrusive::compare<MemberHookLess<Container>>,
78 Hook> policy_container;
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080079
80 // could be just typedef
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080081 class type : public policy_container {
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080082 public:
83 typedef policy policy_base; // to get access to get_order methods from outside
84 typedef Container parent_trie;
85
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080086 type(Base& base)
87 : base_(base)
88 , max_size_(100)
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080089 {
90 }
91
92 inline void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080093 update(typename parent_trie::iterator item)
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080094 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080095 policy_container::erase(policy_container::s_iterator_to(*item));
96 get_order(item) += 1;
97 policy_container::insert(*item);
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080098 }
99
100 inline bool
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800101 insert(typename parent_trie::iterator item)
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800102 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800103 get_order(item) = 0;
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800104
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800105 if (max_size_ != 0 && policy_container::size() >= max_size_) {
106 // this erases the "least frequently used item" from cache
107 base_.erase(&(*policy_container::begin()));
108 }
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800109
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800110 policy_container::insert(*item);
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800111 return true;
112 }
113
114 inline void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800115 lookup(typename parent_trie::iterator item)
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800116 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800117 policy_container::erase(policy_container::s_iterator_to(*item));
118 get_order(item) += 1;
119 policy_container::insert(*item);
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800120 }
121
122 inline void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800123 erase(typename parent_trie::iterator item)
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800124 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800125 policy_container::erase(policy_container::s_iterator_to(*item));
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800126 }
127
128 inline void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800129 clear()
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800130 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800131 policy_container::clear();
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800132 }
133
134 inline void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800135 set_max_size(size_t max_size)
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800136 {
137 max_size_ = max_size;
138 }
139
140 inline size_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800141 get_max_size() const
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800142 {
143 return max_size_;
144 }
145
146 private:
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800147 type()
148 : base_(*((Base*)0)){};
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800149
150 private:
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800151 Base& base_;
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800152 size_t max_size_;
153 };
154 };
155};
156
157} // ndnSIM
158} // ndn
159} // ns3
160
161#endif // LFU_POLICY_H