blob: 663ec5b30f6188f23a5fcb2f279051d88e9a5333 [file] [log] [blame]
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -08001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2012 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 FRESHNESS_POLICY_H_
22#define FRESHNESS_POLICY_H_
23
Spyridon Mastorakis53e922f2014-10-17 17:29:26 -070024#include "ns3/ndnSIM/model/ndn-common.hpp"
25
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -080026#include <boost/intrusive/options.hpp>
27#include <boost/intrusive/list.hpp>
28
29#include <ns3/nstime.h>
30#include <ns3/simulator.h>
31#include <ns3/traced-callback.h>
32
33namespace ns3 {
34namespace ndn {
35namespace ndnSIM {
36
37/**
38 * @brief Traits for freshness policy
39 */
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080040struct freshness_policy_traits {
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -080041 /// @brief Name that can be used to identify the policy (for NS-3 object model and logging)
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080042 static std::string
43 GetName()
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -080044 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080045 return "Freshness";
46 }
47
48 struct policy_hook_type : public boost::intrusive::set_member_hook<> {
49 Time timeWhenShouldExpire;
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -080050 };
51
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080052 template<class Container>
53 struct container_hook {
54 typedef boost::intrusive::member_hook<Container, policy_hook_type, &Container::policy_hook_>
55 type;
56 };
57
58 template<class Base, class Container, class Hook>
59 struct policy {
60 static Time&
61 get_freshness(typename Container::iterator item)
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -080062 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080063 return static_cast<typename policy_container::value_traits::hook_type*>(
64 policy_container::value_traits::to_node_ptr(*item))->timeWhenShouldExpire;
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -080065 }
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080066
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080067 static const Time&
68 get_freshness(typename Container::const_iterator item)
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -080069 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080070 return static_cast<const typename policy_container::value_traits::hook_type*>(
71 policy_container::value_traits::to_node_ptr(*item))->timeWhenShouldExpire;
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -080072 }
73
74 template<class Key>
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080075 struct MemberHookLess {
76 bool
77 operator()(const Key& a, const Key& b) const
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -080078 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080079 return get_freshness(&a) < get_freshness(&b);
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -080080 }
81 };
82
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080083 typedef boost::intrusive::multiset<Container,
84 boost::intrusive::compare<MemberHookLess<Container>>,
85 Hook> policy_container;
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -080086
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080087 class type : public policy_container {
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -080088 public:
Alexander Afanasyev69786112012-12-13 11:53:36 -080089 typedef policy policy_base; // to get access to get_freshness methods from outside
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -080090 typedef Container parent_trie;
91
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080092 type(Base& base)
93 : base_(base)
94 , max_size_(100)
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -080095 {
96 }
97
98 inline void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -080099 update(typename parent_trie::iterator item)
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -0800100 {
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800101 // do nothing
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -0800102 }
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800103
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -0800104 inline bool
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800105 insert(typename parent_trie::iterator item)
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -0800106 {
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -0800107 time::milliseconds freshness = item->payload()->GetData()->getFreshnessPeriod();
108 if (freshness > time::milliseconds::zero()) {
109 get_freshness(item) = Simulator::Now() + MilliSeconds(freshness.count());
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -0800110
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -0800111 // push item only if freshness is non zero. otherwise, this payload is not
112 // controlled by the policy.
113 // Note that .size() on this policy would return only the number of items with
114 // non-infinite freshness policy
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800115 policy_container::insert(*item);
116 }
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -0800117
118 return true;
119 }
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800120
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -0800121 inline void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800122 lookup(typename parent_trie::iterator item)
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -0800123 {
124 // do nothing. it's random policy
125 }
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800126
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -0800127 inline void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800128 erase(typename parent_trie::iterator item)
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -0800129 {
Spyridon Mastorakisde1f7732014-12-05 22:43:34 -0800130 time::milliseconds freshness = item->payload()->GetData()->getFreshnessPeriod();
131 if (freshness > time::milliseconds::zero()) {
132 // erase only if freshness is positive (otherwise an item is not in the policy)
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800133 policy_container::erase(policy_container::s_iterator_to(*item));
134 }
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -0800135 }
136
137 inline void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800138 clear()
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -0800139 {
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800140 policy_container::clear();
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -0800141 }
142
143 inline void
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800144 set_max_size(size_t max_size)
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -0800145 {
146 max_size_ = max_size;
147 }
148
149 inline size_t
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800150 get_max_size() const
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -0800151 {
152 return max_size_;
153 }
154
155 private:
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800156 type()
157 : base_(*((Base*)0)){};
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800158
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -0800159 private:
Alexander Afanasyevbe55cf62014-12-20 17:51:09 -0800160 Base& base_;
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -0800161 size_t max_size_;
162 };
163 };
164};
165
166} // ndnSIM
167} // ndn
168} // ns3
169
170#endif // LIFETIME_STATS_POLICY_H