blob: 897dc49849dbd6f3552ce59c07d8c0571215325b [file] [log] [blame]
Alexander Afanasyev41824bd2013-01-23 23:57:59 -08001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2011 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
19 */
20
21#ifndef LFU_POLICY_H_
22#define LFU_POLICY_H_
23
24#include <boost/intrusive/options.hpp>
25#include <boost/intrusive/set.hpp>
26
27namespace ns3 {
28namespace ndn {
29namespace ndnSIM {
30
31/**
32 * @brief Traits for LFU replacement policy
33 */
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080034struct lfu_policy_traits {
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080035 /// @brief Name that can be used to identify the policy (for NS-3 object model and logging)
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080036 static std::string
37 GetName()
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080038 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080039 return "Lfu";
40 }
41
42 struct policy_hook_type : public boost::intrusive::set_member_hook<> {
43 double frequency;
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080044 };
45
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080046 template<class Container>
47 struct container_hook {
48 typedef boost::intrusive::member_hook<Container, policy_hook_type, &Container::policy_hook_>
49 type;
50 };
51
52 template<class Base, class Container, class Hook>
53 struct policy {
54 static double&
55 get_order(typename Container::iterator item)
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080056 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080057 return static_cast<policy_hook_type*>(policy_container::value_traits::to_node_ptr(*item))
58 ->frequency;
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080059 }
60
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080061 static const double&
62 get_order(typename Container::const_iterator item)
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080063 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080064 return static_cast<const policy_hook_type*>(
65 policy_container::value_traits::to_node_ptr(*item))->frequency;
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080066 }
67
68 template<class Key>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080069 struct MemberHookLess {
70 bool
71 operator()(const Key& a, const Key& b) const
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080072 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080073 return get_order(&a) < get_order(&b);
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080074 }
75 };
76
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080077 typedef boost::intrusive::multiset<Container,
78 boost::intrusive::compare<MemberHookLess<Container>>,
79 Hook> policy_container;
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080080
81 // could be just typedef
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080082 class type : public policy_container {
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080083 public:
84 typedef policy policy_base; // to get access to get_order methods from outside
85 typedef Container parent_trie;
86
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080087 type(Base& base)
88 : base_(base)
89 , max_size_(100)
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080090 {
91 }
92
93 inline void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080094 update(typename parent_trie::iterator item)
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080095 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080096 policy_container::erase(policy_container::s_iterator_to(*item));
97 get_order(item) += 1;
98 policy_container::insert(*item);
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080099 }
100
101 inline bool
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800102 insert(typename parent_trie::iterator item)
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800103 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800104 get_order(item) = 0;
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800105
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800106 if (max_size_ != 0 && policy_container::size() >= max_size_) {
107 // this erases the "least frequently used item" from cache
108 base_.erase(&(*policy_container::begin()));
109 }
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800110
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800111 policy_container::insert(*item);
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800112 return true;
113 }
114
115 inline void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800116 lookup(typename parent_trie::iterator item)
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800117 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800118 policy_container::erase(policy_container::s_iterator_to(*item));
119 get_order(item) += 1;
120 policy_container::insert(*item);
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800121 }
122
123 inline void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800124 erase(typename parent_trie::iterator item)
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800125 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800126 policy_container::erase(policy_container::s_iterator_to(*item));
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800127 }
128
129 inline void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800130 clear()
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800131 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800132 policy_container::clear();
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800133 }
134
135 inline void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800136 set_max_size(size_t max_size)
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800137 {
138 max_size_ = max_size;
139 }
140
141 inline size_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800142 get_max_size() const
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800143 {
144 return max_size_;
145 }
146
147 private:
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800148 type()
149 : base_(*((Base*)0)){};
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800150
151 private:
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800152 Base& base_;
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800153 size_t max_size_;
154 };
155 };
156};
157
158} // ndnSIM
159} // ndn
160} // ns3
161
162#endif // LFU_POLICY_H