blob: 7c8785c91565cea7b3fcb377b99b8208427a4ecb [file] [log] [blame]
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -07001/* -*- 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 _CCNX_PIT_H_
22#define _CCNX_PIT_H_
23
Alexander Afanasyevcf133f02011-09-06 12:13:48 -070024#include "ns3/object.h"
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -070025#include "ns3/nstime.h"
26#include "ns3/event-id.h"
27
28#include "hash-helper.h"
29#include "ccnx-pit-entry.h"
30
31#include <boost/multi_index_container.hpp>
32#include <boost/multi_index/tag.hpp>
33#include <boost/multi_index/ordered_index.hpp>
34#include <boost/multi_index/composite_key.hpp>
35#include <boost/multi_index/hashed_index.hpp>
36#include <boost/multi_index/member.hpp>
37#include <boost/multi_index/mem_fun.hpp>
38#include <boost/multi_index/sequenced_index.hpp>
Ilya Moiseenko1c73cb52011-10-28 13:13:11 -070039#include <map>
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -070040#include <iostream>
Ilya Moiseenko1c73cb52011-10-28 13:13:11 -070041#include <algorithm>
Alexander Afanasyeva46844b2011-11-21 19:13:26 -080042#include <boost/tuple/tuple.hpp>
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -070043
44namespace ns3 {
45
46class Ccnx;
47class CcnxFace;
48class CcnxContentObjectHeader;
49class CcnxInterestHeader;
50
51/**
52 * \ingroup ccnx
53 * \private
54 * \brief Private namespace for CCNx PIT implementation
55 */
56namespace __ccnx_private
57{
Alexander Afanasyev78cf0c92011-09-01 19:57:14 -070058// class i_prefix{}; ///< tag for prefix hash
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -070059class i_timestamp {}; ///< tag for timestamp-ordered records (for cleanup optimization)
60};
61
62/**
63 * \ingroup ccnx
64 * \brief Typedef for RIT container implemented as a Boost.MultiIndex container
65 *
66 * - First index (tag<i_prefix>) is a unique hash index based on
67 * prefixes
68 * - Second index (tag<i_timestamp>) is a sequenced index based on
69 * arrival order (for clean-up optimizations)
70 *
71 * \see http://www.boost.org/doc/libs/1_46_1/libs/multi_index/doc/ for more information on Boost.MultiIndex library
72 */
73struct CcnxPitEntryContainer
74{
75 typedef
76 boost::multi_index::multi_index_container<
77 CcnxPitEntry,
78 boost::multi_index::indexed_by<
79 // indexed by hash
80 boost::multi_index::hashed_unique<
81 boost::multi_index::tag<__ccnx_private::i_prefix>,
82 boost::multi_index::const_mem_fun<CcnxPitEntry, const CcnxNameComponents&, &CcnxPitEntry::GetPrefix>,
83 CcnxPrefixHash
84 >,
85 // sequenced to implement MRU
86 boost::multi_index::sequenced<
87 boost::multi_index::tag<__ccnx_private::i_timestamp> >
88 >
89 > type;
90};
91
92// typedef std::map<int,int> PitCounter;
93// typedef std::map<int,int>::iterator PitCounterIterator;
94
Ilya Moiseenko1c73cb52011-10-28 13:13:11 -070095 typedef std::map<int,double> PitBucket;
96 typedef std::map<int,double>::iterator PitBucketIterator;
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -070097
98
99////////////////////////////////////////////////////////////////////////
100////////////////////////////////////////////////////////////////////////
101
102/**
103 * \ingroup ccnx
104 * \brief Class implementing Pending Interests Table
105 */
Alexander Afanasyevcf133f02011-09-06 12:13:48 -0700106class CcnxPit : public CcnxPitEntryContainer::type, public Object
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700107{
108public:
109 /**
Alexander Afanasyevcf133f02011-09-06 12:13:48 -0700110 * \brief Interface ID
111 *
112 * \return interface ID
113 */
114 static TypeId GetTypeId ();
115
116 /**
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700117 * \brief PIT constructor
118 */
119 CcnxPit ();
120
Alexander Afanasyevd02a5d62011-11-21 11:01:51 -0800121 /**
122 * \brief Destructor
123 */
124 virtual ~CcnxPit ();
125
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -0800126 /**
127 * @brief Try to add outgoing entry to PIT entry.
128 * Will fail if there were too much (other) interests forwarded to this face
129 *
130 * @param pitEntry PIT entry
131 * @param face face
132 * @returns false if rate limit is imposed and no outgoing entry was created. True otherwise
133 */
Ilya Moiseenko1c73cb52011-10-28 13:13:11 -0700134 bool
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -0800135 TryAddOutgoing(const CcnxPitEntry &pitEntry, Ptr<CcnxFace> face);
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800136
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700137 /**
138 * \brief Find corresponding PIT entry for the given content name
139 * \param prefix Prefix for which to lookup the entry
140 * \returns const reference to Pit entry. If record not found,
141 * CcnxPitEntryNotFound exception will be thrown
142 */
143 const CcnxPitEntry&
144 Lookup (const CcnxContentObjectHeader &header) const;
145
146 /**
147 * \brief Find corresponding PIT entry for the given content name
148 * \param prefix Prefix for which to lookup the entry
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800149 * \returns a tuple:
150 * get<0>: `const CcnxPitEntry&`: a valid PIT entry (if record does not exist, it will be created)
151 * get<1>: `bool`: true if a new entry was created
152 * get<2>: `bool`: true if a PIT entry exists and Nonce that present in header has been already seen
153 *
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700154 */
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800155 boost::tuple<const CcnxPitEntry&, bool, bool>
156 Lookup (const CcnxInterestHeader &header);
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700157
158 // remove a PIT entry
159 //void erase (const string &contentName);
160
161 // Reset pending state in outgoing interests
162 // void resetPendingState( PitEntry &pe );
163
164 // // Check if there are any interfaces that we haven't sent data to yet
165 // bool areFreeInterfaces( PitEntry &pe, int interface );
166
Ilya Moiseenko1c73cb52011-10-28 13:13:11 -0700167 // Periodically generate pre-calculated number of tokens (leak buckets)
168 void LeakBuckets( );
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700169
Ilya Moiseenko1c73cb52011-10-28 13:13:11 -0700170 // Selectively leak a bucket
171 void LeakBucket (Ptr<CcnxFace> face, int amount);
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700172
173 /**
174 * \brief Set cleanup timeout
175 *
176 * Side effect: current clean up even (if any) will be cancelled and a new event started
177 *
178 * \param timeout cleanup timeout
179 */
180 void SetCleanupTimeout (const Time &timeout);
181
182 /**
183 * \brief Get cleanup timeout
184 *
185 * \returns cleanup timeout
186 */
187 Time GetCleanupTimeout () const;
188
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800189 Time GetPitEntryPruningTimeout () const
190 {
191 return m_PitEntryPruningTimout;
192 }
193
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700194 /**
195 * \brief Set FIB table
196 */
197 void SetFib (Ptr<CcnxFib> fib);
198
Alexander Afanasyev18252852011-11-21 13:35:31 -0800199protected:
200 // inherited from Object class
201 virtual void NotifyNewAggregate ();
202 virtual void DoDispose ();
203
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700204public:
Ilya Moiseenko1c73cb52011-10-28 13:13:11 -0700205 PitBucket maxBucketsPerFace; // maximum number of buckets. Automatically computed based on link capacity
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700206 // // averaging over 1 second (bandwidth * 1second)
Ilya Moiseenko1c73cb52011-10-28 13:13:11 -0700207 PitBucket leakSize; // size of a periodic bucket leak
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700208
209private:
210 /** \brief Remove expired records from PIT */
211 void CleanExpired ();
212
213 friend std::ostream& operator<< (std::ostream& os, const CcnxPit &fib);
214
215private:
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700216 Time m_cleanupTimeout; ///< \brief Configurable timeout of how often cleanup events are working
217 EventId m_cleanupEvent; ///< \brief Cleanup event
Alexander Afanasyeva46844b2011-11-21 19:13:26 -0800218 Time m_PitEntryPruningTimout;
Alexander Afanasyeva5bbe0e2011-11-22 17:28:39 -0800219 Time m_PitEntryDefaultLifetime;
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700220
Alexander Afanasyevc5a23e22011-09-07 00:37:36 -0700221 Ptr<CcnxFib> m_fib; ///< \brief Link to FIB table
Alexander Afanasyevd02a5d62011-11-21 11:01:51 -0800222 PitBucket m_bucketsPerFace; ///< \brief pending interface counter per face
Alexander Afanasyeva98cdd22011-08-29 17:32:37 -0700223};
224
225///////////////////////////////////////////////////////////////////////////////
226///////////////////////////////////////////////////////////////////////////////
227
228std::ostream& operator<< (std::ostream& os, const CcnxPit &fib);
229std::ostream& operator<< (std::ostream& os, const CcnxPitEntry &entry);
230// std::ostream& operator<< (std::ostream& os, const CcnxFibFaceMetric &metric);
231
232class CcnxPitEntryNotFound {};
233
234} // namespace ns3
235
236#endif /* CCNX_PIT_H */