blob: 5fa2a34a7d85248e9a0dd021c1d162f9d4109455 [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
24#include <boost/intrusive/options.hpp>
25#include <boost/intrusive/list.hpp>
26
27#include <ns3/nstime.h>
28#include <ns3/simulator.h>
29#include <ns3/traced-callback.h>
30
31namespace ns3 {
32namespace ndn {
33namespace ndnSIM {
34
35/**
36 * @brief Traits for freshness policy
37 */
38struct freshness_policy_traits
39{
40 /// @brief Name that can be used to identify the policy (for NS-3 object model and logging)
41 static std::string GetName () { return "Freshness"; }
42
43 struct policy_hook_type : public boost::intrusive::set_member_hook<> { Time timeWhenShouldExpire; };
44
45 template<class Container>
46 struct container_hook
47 {
48 typedef boost::intrusive::member_hook< Container,
49 policy_hook_type,
50 &Container::policy_hook_ > type;
51 };
52
53 template<class Base,
54 class Container,
55 class Hook>
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080056 struct policy
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -080057 {
58 static Time& get_freshness (typename Container::iterator item)
59 {
60 return static_cast<typename policy_container::value_traits::hook_type*>
61 (policy_container::value_traits::to_node_ptr(*item))->timeWhenShouldExpire;
62 }
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080063
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -080064 static const Time& get_freshness (typename Container::const_iterator item)
65 {
66 return static_cast<const typename policy_container::value_traits::hook_type*>
67 (policy_container::value_traits::to_node_ptr(*item))->timeWhenShouldExpire;
68 }
69
70 template<class Key>
71 struct MemberHookLess
72 {
73 bool operator () (const Key &a, const Key &b) const
74 {
75 return get_freshness (&a) < get_freshness (&b);
76 }
77 };
78
79 typedef boost::intrusive::multiset< Container,
80 boost::intrusive::compare< MemberHookLess< Container > >,
81 Hook > policy_container;
82
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080083
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -080084 class type : public policy_container
85 {
86 public:
Alexander Afanasyev69786112012-12-13 11:53:36 -080087 typedef policy policy_base; // to get access to get_freshness methods from outside
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -080088 typedef Container parent_trie;
89
90 type (Base &base)
91 : base_ (base)
92 , max_size_ (100)
93 {
94 }
95
96 inline void
97 update (typename parent_trie::iterator item)
98 {
Alexander Afanasyev41824bd2013-01-23 23:57:59 -080099 // do nothing
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -0800100 }
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800101
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -0800102 inline bool
103 insert (typename parent_trie::iterator item)
104 {
105 // get_time (item) = Simulator::Now ();
106 Time freshness = item->payload ()->GetHeader ()->GetFreshness ();
107 if (!freshness.IsZero ())
108 {
109 get_freshness (item) = Simulator::Now () + freshness;
110
111 // push item only if freshness is non zero. otherwise, this payload is not controlled by the policy
112 // note that .size() on this policy would return only number of items with non-infinite freshness policy
Alexander Afanasyev8c476bb2013-07-04 09:34:55 -0700113 policy_container::insert (*item);
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -0800114 }
115
116 return true;
117 }
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800118
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -0800119 inline void
120 lookup (typename parent_trie::iterator item)
121 {
122 // do nothing. it's random policy
123 }
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800124
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -0800125 inline void
126 erase (typename parent_trie::iterator item)
127 {
128 if (!item->payload ()->GetHeader ()->GetFreshness ().IsZero ())
129 {
130 // erase only if freshness is non zero (otherwise an item is not in the policy
131 policy_container::erase (policy_container::s_iterator_to (*item));
132 }
133 }
134
135 inline void
136 clear ()
137 {
138 policy_container::clear ();
139 }
140
141 inline void
142 set_max_size (size_t max_size)
143 {
144 max_size_ = max_size;
145 }
146
147 inline size_t
148 get_max_size () const
149 {
150 return max_size_;
151 }
152
153 private:
154 type () : base_(*((Base*)0)) { };
Alexander Afanasyev41824bd2013-01-23 23:57:59 -0800155
Alexander Afanasyevc3cc0b32012-12-12 18:41:20 -0800156 private:
157 Base &base_;
158 size_t max_size_;
159 };
160 };
161};
162
163} // ndnSIM
164} // ndn
165} // ns3
166
167#endif // LIFETIME_STATS_POLICY_H