blob: 26d0c0fab32dc03e8d6154a93d76dd3486c5ee11 [file] [log] [blame]
Alexander Afanasyeva4e74282013-07-11 15:23:20 -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 * GNU v3.0 license, See the LICENSE file for more information
7 *
8 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
9 */
10
11#ifndef NDN_NDNCXX_DETAIL_TIMEOUTS_POLICY_H_
12#define NDN_NDNCXX_DETAIL_TIMEOUTS_POLICY_H_
13
14#include <boost/intrusive/options.hpp>
15#include <boost/intrusive/list.hpp>
16
17#include <ns3/nstime.h>
18#include <ns3/simulator.h>
19
20namespace ns3 {
21namespace ndn {
22namespace detail {
23
24/**
25 * @brief Traits for timeouts policy
26 */
27struct timeouts_policy_traits
28{
29 /// @brief Name that can be used to identify the policy (for NS-3 object model and logging)
30 static std::string GetName () { return "Timeouts"; }
31
32 struct policy_hook_type : public boost::intrusive::set_member_hook<> { Time timeWhenShouldExpire; };
33
34 template<class Container>
35 struct container_hook
36 {
37 typedef boost::intrusive::member_hook< Container,
38 policy_hook_type,
39 &Container::policy_hook_ > type;
40 };
41
42 template<class Base,
43 class Container,
44 class Hook>
45 struct policy
46 {
47 static Time& get_timeout (typename Container::iterator item)
48 {
49 return static_cast<typename policy_container::value_traits::hook_type*>
50 (policy_container::value_traits::to_node_ptr(*item))->timeWhenShouldExpire;
51 }
52
53 static const Time& get_timeout (typename Container::const_iterator item)
54 {
55 return static_cast<const typename policy_container::value_traits::hook_type*>
56 (policy_container::value_traits::to_node_ptr(*item))->timeWhenShouldExpire;
57 }
58
59 template<class Key>
60 struct MemberHookLess
61 {
62 bool operator () (const Key &a, const Key &b) const
63 {
64 return get_timeout (&a) < get_timeout (&b);
65 }
66 };
67
68 typedef boost::intrusive::multiset< Container,
69 boost::intrusive::compare< MemberHookLess< Container > >,
70 Hook > policy_container;
71
72
73 class type : public policy_container
74 {
75 public:
76 typedef policy policy_base; // to get access to get_timeout methods from outside
77 typedef Container parent_trie;
78
79 type (Base &base)
80 : m_base (base)
81 {
82 }
83
84 inline void
85 update (typename parent_trie::iterator item)
86 {
87 // do nothing
88 }
89
90 inline bool
91 insert (typename parent_trie::iterator item)
92 {
93 Time timeout = item->payload ()->GetInterest ()->GetInterestLifetime ();
94 if (timeout.IsZero ()) timeout = Seconds (4.0);
95
96 get_timeout (item) = Simulator::Now () + timeout;
97 policy_container::insert (*item);
98
99 if (policy_container::s_iterator_to (*item) == policy_container::begin ())
100 {
101 if (m_timeoutEvent.IsRunning ())
102 {
103 Simulator::Remove (m_timeoutEvent); // just canceling would not clean up list of events
104 }
105
106 m_timeoutEvent = Simulator::Schedule (timeout, &type::ProcessTimeoutEntry, this, item);
107 }
108
109 return true;
110 }
111
112 inline void
113 lookup (typename parent_trie::iterator item)
114 {
115 // do nothing. it's random policy
116 }
117
118 inline void
119 erase (typename parent_trie::iterator item)
120 {
121 if (policy_container::s_iterator_to (*item) == policy_container::begin ())
122 {
123 if (m_timeoutEvent.IsRunning ())
124 {
125 Simulator::Remove (m_timeoutEvent); // just canceling would not clean up list of events
126 }
127 }
128
129 // erase only if freshness is non zero (otherwise an item is not in the policy
130 policy_container::erase (policy_container::s_iterator_to (*item));
131
132 if (!policy_container::empty ())
133 {
134 Time timeout = get_timeout (&*policy_container::begin ()) - Simulator::Now ();
135 m_timeoutEvent = Simulator::Schedule (timeout, &type::ProcessTimeoutEntry, this, &*policy_container::begin ());
136 }
137 }
138
139 inline void
140 clear ()
141 {
142 policy_container::clear ();
143 }
144
145 inline void
146 ProcessTimeoutEntry (typename parent_trie::iterator item)
147 {
Alexander Afanasyeve4795ae2013-07-11 20:01:31 -0700148 if (!item->payload ()->m_timeoutCallback.IsNull ())
149 item->payload ()->m_timeoutCallback (item->payload ()->GetInterest ());
Alexander Afanasyeva4e74282013-07-11 15:23:20 -0700150
151 m_base.erase (item);
152 }
153
154 private:
155 type () : m_base (*((Base*)0)) { };
156
157 private:
158 Base &m_base;
159 EventId m_timeoutEvent;
160 };
161 };
162};
163
164} // detail
165} // ndn
166} // ns3
167
168#endif // NDN_NDNCXX_DETAIL_TIMEOUTS_STATS_POLICY_H