Initial redesign of internal data structures
diff --git a/model/ccnx-bestroute-strategy.cc b/model/ccnx-bestroute-strategy.cc
index e688cec..8fc6f1e 100644
--- a/model/ccnx-bestroute-strategy.cc
+++ b/model/ccnx-bestroute-strategy.cc
@@ -72,7 +72,7 @@
int propagatedCount = 0;
- BOOST_FOREACH (const CcnxFibFaceMetric &metricFace, pitEntry.m_fibEntry.m_faces.get<i_metric> ())
+ BOOST_FOREACH (const CcnxFibFaceMetric &metricFace, pitEntry.m_fibEntry->m_faces.get<i_metric> ())
{
if (metricFace.m_status == CcnxFibFaceMetric::NDN_FIB_RED) // all non-read faces are in front
break;
diff --git a/model/ccnx-content-store.cc b/model/ccnx-content-store.cc
index c5a66c9..ccbf200 100644
--- a/model/ccnx-content-store.cc
+++ b/model/ccnx-content-store.cc
@@ -43,6 +43,7 @@
.AddTraceSource ("CacheHits", "Trace called every time there is a cache hit",
MakeTraceSourceAccessor (&CcnxContentStore::m_cacheHitsTrace))
+
.AddTraceSource ("CacheMisses", "Trace called every time there is a cache miss",
MakeTraceSourceAccessor (&CcnxContentStore::m_cacheMissesTrace))
;
diff --git a/model/ccnx-content-store.h b/model/ccnx-content-store.h
index 07888e7..27bcda4 100644
--- a/model/ccnx-content-store.h
+++ b/model/ccnx-content-store.h
@@ -151,11 +151,6 @@
/**
* \brief Print out content store entries
- *
- * Debug build provides dumping of content store entries in
- * lexicographical order of corresponding prefixes
- *
- * Release build dumps everything in MRU order
*/
virtual void
Print () const = 0;
diff --git a/model/ccnx-fib.h b/model/ccnx-fib.h
index 7c2c6af..bbbc44f 100644
--- a/model/ccnx-fib.h
+++ b/model/ccnx-fib.h
@@ -271,6 +271,8 @@
class CcnxFib : public Object
{
public:
+ typedef CcnxFibEntryContainer::type::iterator iterator;
+
/**
* \brief Interface ID
*
diff --git a/model/ccnx-flooding-strategy.cc b/model/ccnx-flooding-strategy.cc
index 290497e..3135afd 100644
--- a/model/ccnx-flooding-strategy.cc
+++ b/model/ccnx-flooding-strategy.cc
@@ -83,7 +83,7 @@
int propagatedCount = 0;
- BOOST_FOREACH (const CcnxFibFaceMetric &metricFace, pitEntry.m_fibEntry.m_faces.get<i_metric> ())
+ BOOST_FOREACH (const CcnxFibFaceMetric &metricFace, pitEntry.m_fibEntry->m_faces.get<i_metric> ())
{
NS_LOG_DEBUG ("Trying " << boost::cref(metricFace));
if (metricFace.m_status == CcnxFibFaceMetric::NDN_FIB_RED) // all non-read faces are in the front of the list
diff --git a/model/ccnx-forwarding-strategy.cc b/model/ccnx-forwarding-strategy.cc
index 93c3847..4983860 100644
--- a/model/ccnx-forwarding-strategy.cc
+++ b/model/ccnx-forwarding-strategy.cc
@@ -92,7 +92,7 @@
int propagatedCount = 0;
- BOOST_FOREACH (const CcnxFibFaceMetric &metricFace, pitEntry.m_fibEntry.m_faces.get<i_metric> ())
+ BOOST_FOREACH (const CcnxFibFaceMetric &metricFace, pitEntry.m_fibEntry->m_faces.get<i_metric> ())
{
if (metricFace.m_status == CcnxFibFaceMetric::NDN_FIB_RED ||
metricFace.m_status == CcnxFibFaceMetric::NDN_FIB_YELLOW)
diff --git a/model/ccnx-l3-protocol.cc b/model/ccnx-l3-protocol.cc
index aa5be00..9abe297 100644
--- a/model/ccnx-l3-protocol.cc
+++ b/model/ccnx-l3-protocol.cc
@@ -182,8 +182,8 @@
// If this face is the only for the associated FIB entry, then FIB entry will be removed soon.
// Thus, we have to remove the whole PIT entry
- if (pitEntry.m_fibEntry.m_faces.size () == 1 &&
- pitEntry.m_fibEntry.m_faces.begin ()->m_face == face)
+ if (pitEntry.m_fibEntry->m_faces.size () == 1 &&
+ pitEntry.m_fibEntry->m_faces.begin ()->m_face == face)
{
entriesToRemoves.push_back (boost::cref (pitEntry));
}
@@ -293,22 +293,18 @@
NS_LOG_FUNCTION (incomingFace << header << packet);
m_inNacks (header, incomingFace);
- tuple<const CcnxPitEntry&,bool,bool> ret = m_pit->Lookup (*header);
- CcnxPitEntry const& pitEntry = ret.get<0> ();
- bool isNew = ret.get<1> ();
- bool isDuplicated = ret.get<2> ();
-
- if (isNew || !isDuplicated) // potential flow
+ CcnxPit::iterator pitEntry = m_pit->Lookup (*header);
+ if (pitEntry == m_pit->end ())
{
// somebody is doing something bad
m_dropNacks (header, NON_DUPLICATED, incomingFace);
return;
}
- // CcnxPitEntryIncomingFaceContainer::type::iterator inFace = pitEntry.m_incoming.find (incomingFace);
- CcnxPitEntryOutgoingFaceContainer::type::iterator outFace = pitEntry.m_outgoing.find (incomingFace);
+ // CcnxPitEntryIncomingFaceContainer::type::iterator inFace = pitEntry->m_incoming.find (incomingFace);
+ CcnxPitEntryOutgoingFaceContainer::type::iterator outFace = pitEntry->m_outgoing.find (incomingFace);
- if (outFace == pitEntry.m_outgoing.end ())
+ if (outFace == pitEntry->m_outgoing.end ())
{
// NS_ASSERT_MSG (false,
// "Node " << GetObject<Node> ()->GetId () << ", outgoing entry should exist for face " << boost::cref(*incomingFace) << "\n" <<
@@ -325,7 +321,7 @@
NS_LOG_ERROR ("Nack on " << boost::cref(*incomingFace));
- m_pit->modify (m_pit->iterator_to (pitEntry),
+ m_pit->modify (pitEntry,
ll::bind (&CcnxPitEntry::SetWaitingInVain, ll::_1, outFace));
// If NACK is NACK_GIVEUP_PIT, then neighbor gave up trying to and removed it's PIT entry.
@@ -333,22 +329,22 @@
if (header->GetNack () == CcnxInterestHeader::NACK_GIVEUP_PIT)
{
- m_pit->modify (m_pit->iterator_to (pitEntry),
+ m_pit->modify (pitEntry,
ll::bind (&CcnxPitEntry::RemoveIncoming, ll::_1, incomingFace));
}
- m_fib->m_fib.modify (m_fib->m_fib.iterator_to (pitEntry.m_fibEntry),
+ m_fib->m_fib.modify (pitEntry->m_fibEntry,
ll::bind (&CcnxFibEntry::UpdateStatus,
ll::_1, incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW));
- if (pitEntry.m_incoming.size () == 0) // interest was actually satisfied
+ if (pitEntry->m_incoming.size () == 0) // interest was actually satisfied
{
// no need to do anything
m_dropNacks (header, AFTER_SATISFIED, incomingFace);
return;
}
- if (!pitEntry.AreAllOutgoingInVain ()) // not all ougtoing are in vain
+ if (!pitEntry->AreAllOutgoingInVain ()) // not all ougtoing are in vain
{
NS_LOG_DEBUG ("Not all outgoing are in vain");
// suppress
@@ -362,7 +358,7 @@
nonNackInterest->AddHeader (*header);
bool propagated = m_forwardingStrategy->
- PropagateInterest (pitEntry, incomingFace, header, nonNackInterest);
+ PropagateInterest (*pitEntry, incomingFace, header, nonNackInterest);
// // ForwardingStrategy will try its best to forward packet to at least one interface.
// // If no interests was propagated, then there is not other option for forwarding or
@@ -383,15 +379,22 @@
const Ptr<const Packet> &packet)
{
m_inInterests (header, incomingFace);
- // NS_LOG_DEBUG (*m_pit);
- // Lookup of Pit (and associated Fib) entry for this Interest
- tuple<const CcnxPitEntry&,bool,bool> ret = m_pit->Lookup (*header);
- CcnxPitEntry const& pitEntry = ret.get<0> ();
- bool isNew = ret.get<1> ();
- bool isDuplicated = ret.get<2> ();
+ CcnxPit::iterator pitEntry = m_pit->Lookup (*header);
+ if (pitEntry == m_pit->end ())
+ {
+ pitEntry = m_pit->Create (*header);
+ }
- // NS_LOG_DEBUG ("isNew: " << isNew << ", isDup: " << isDuplicated);
+ if (pitEntry == m_pit->end ())
+ {
+ // if it is still not created, then give up processing
+ m_dropInterests (header, PIT_LIMIT, incomingFace);
+ return;
+ }
+
+ bool isNew = pitEntry->m_incoming.size () == 0 && pitEntry->m_outgoing.size () == 0;
+ bool isDuplicated = m_pit->CheckIfDuplicate (pitEntry, *header);
NS_LOG_FUNCTION (header->GetName () << header->GetNonce () << boost::cref (*incomingFace) << isDuplicated);
@@ -406,12 +409,12 @@
/////////////////////////////////////////////////////////////////////////////////////////
// Data is not in cache
- CcnxPitEntryIncomingFaceContainer::type::iterator inFace = pitEntry.m_incoming.find (incomingFace);
- CcnxPitEntryOutgoingFaceContainer::type::iterator outFace = pitEntry.m_outgoing.find (incomingFace);
+ CcnxPitEntry::in_iterator inFace = pitEntry->m_incoming.find (incomingFace);
+ CcnxPitEntry::out_iterator outFace = pitEntry->m_outgoing.find (incomingFace);
bool isRetransmitted = false;
- if (inFace != pitEntry.m_incoming.end ())
+ if (inFace != pitEntry->m_incoming.end ())
{
// CcnxPitEntryIncomingFace.m_arrivalTime keeps track arrival time of the first packet... why?
@@ -420,7 +423,7 @@
}
else
{
- m_pit->modify (m_pit->iterator_to (pitEntry),
+ m_pit->modify (pitEntry,
ll::var(inFace) = ll::bind (&CcnxPitEntry::AddIncoming, ll::_1, incomingFace));
}
//////////////////////////////////////////////////////////////////////////////////
@@ -466,11 +469,11 @@
}
// update PIT entry lifetime
- m_pit->modify (m_pit->iterator_to (pitEntry),
+ m_pit->modify (pitEntry,
ll::bind (&CcnxPitEntry::UpdateLifetime, ll::_1,
header->GetInterestLifetime ()));
- if (outFace != pitEntry.m_outgoing.end ())
+ if (outFace != pitEntry->m_outgoing.end ())
{
NS_LOG_DEBUG ("Non duplicate interests from the face we have sent interest to. Don't suppress");
// got a non-duplicate interest from the face we have sent interest to
@@ -481,7 +484,7 @@
// ?? not sure if we need to do that ?? ...
- m_fib->m_fib.modify(m_fib->m_fib.iterator_to (pitEntry.m_fibEntry),
+ m_fib->m_fib.modify(pitEntry->m_fibEntry,
ll::bind (&CcnxFibEntry::UpdateStatus,
ll::_1, incomingFace, CcnxFibFaceMetric::NDN_FIB_YELLOW));
}
@@ -499,17 +502,17 @@
/////////////////////////////////////////////////////////////////////
bool propagated = m_forwardingStrategy->
- PropagateInterest (pitEntry, incomingFace, header, packet);
+ PropagateInterest (*pitEntry, incomingFace, header, packet);
if (!propagated && isRetransmitted) //give another chance if retransmitted
{
// increase max number of allowed retransmissions
- m_pit->modify (m_pit->iterator_to (pitEntry),
+ m_pit->modify (pitEntry,
ll::bind (&CcnxPitEntry::IncreaseAllowedRetxCount, ll::_1));
// try again
propagated = m_forwardingStrategy->
- PropagateInterest (pitEntry, incomingFace, header, packet);
+ PropagateInterest (*pitEntry, incomingFace, header, packet);
}
// ForwardingStrategy will try its best to forward packet to at least one interface.
@@ -529,10 +532,9 @@
const Ptr<const Packet> &packet)
{
// 1. Lookup PIT entry
- try
+ CcnxPit::iterator pitEntry = m_pit->Lookup (*header);
+ if (pitEntry != m_pit->end ())
{
- CcnxPitEntryContainer::type::iterator pitEntry = m_pit->Lookup (*header);
-
//satisfy all pending incoming Interests
BOOST_FOREACH (const CcnxPitEntryIncomingFace &incoming, pitEntry->m_incoming)
{
@@ -554,12 +556,10 @@
ll::bind (&CcnxPitEntry::ClearOutgoing, ll::_1));
// Set pruning timout on PIT entry (instead of deleting the record)
- m_pit->modify (pitEntry,
- ll::bind (&CcnxPitEntry::SetExpireTime, ll::_1,
- Simulator::Now () + m_pit->GetPitEntryPruningTimeout ()));
+ m_pit->MarkErased (pitEntry);
}
}
- catch (CcnxPitEntryNotFound)
+ else
{
NS_LOG_DEBUG ("Pit entry not found (was satisfied and removed before)");
return; // do not process unsoliced data packets
@@ -576,21 +576,19 @@
NS_LOG_FUNCTION (incomingFace << header->GetName () << payload << packet);
m_inData (header, payload, incomingFace);
- // NS_LOG_DEBUG (*m_pit);
// 1. Lookup PIT entry
- try
+ CcnxPit::iterator pitEntry = m_pit->Lookup (*header);
+ if (pitEntry != m_pit->end ())
{
- CcnxPitEntryContainer::type::iterator pitEntry = m_pit->Lookup (*header);
-
// Note that with MultiIndex we need to modify entries indirectly
- CcnxPitEntryOutgoingFaceContainer::type::iterator out = pitEntry->m_outgoing.find (incomingFace);
+ CcnxPitEntry::out_iterator out = pitEntry->m_outgoing.find (incomingFace);
// If we have sent interest for this data via this face, then update stats.
if (out != pitEntry->m_outgoing.end ())
{
- m_fib->m_fib.modify (m_fib->m_fib.iterator_to (pitEntry->m_fibEntry),
+ m_fib->m_fib.modify (pitEntry->m_fibEntry,
ll::bind (&CcnxFibEntry::UpdateFaceRtt,
ll::_1,
incomingFace,
@@ -617,7 +615,7 @@
}
// Update metric status for the incoming interface in the corresponding FIB entry
- m_fib->m_fib.modify (m_fib->m_fib.iterator_to (pitEntry->m_fibEntry),
+ m_fib->m_fib.modify (pitEntry->m_fibEntry,
ll::bind (&CcnxFibEntry::UpdateStatus, ll::_1,
incomingFace, CcnxFibFaceMetric::NDN_FIB_GREEN));
@@ -630,16 +628,14 @@
if (pitEntry->m_incoming.size () == 0)
{
// Set pruning timout on PIT entry (instead of deleting the record)
- m_pit->modify (pitEntry,
- ll::bind (&CcnxPitEntry::SetExpireTime, ll::_1,
- Simulator::Now () + m_pit->GetPitEntryPruningTimeout ()));
+ m_pit->MarkErased (pitEntry);
}
else
{
OnDataDelayed (header, payload, packet);
}
}
- catch (CcnxPitEntryNotFound)
+ else
{
NS_LOG_DEBUG ("Pit entry not found");
if (m_cacheUnsolicitedData)
@@ -660,18 +656,18 @@
}
void
-CcnxL3Protocol::GiveUpInterest (const CcnxPitEntry &pitEntry,
+CcnxL3Protocol::GiveUpInterest (CcnxPit::iterator pitEntry,
Ptr<CcnxInterestHeader> header)
{
- NS_LOG_FUNCTION (this << &pitEntry);
- // NS_LOG_DEBUG (*m_pit);
+ NS_LOG_FUNCTION (this);
+
if (m_nacksEnabled)
{
Ptr<Packet> packet = Create<Packet> ();
header->SetNack (CcnxInterestHeader::NACK_GIVEUP_PIT);
packet->AddHeader (*header);
- BOOST_FOREACH (const CcnxPitEntryIncomingFace &incoming, pitEntry.m_incoming)
+ BOOST_FOREACH (const CcnxPitEntryIncomingFace &incoming, pitEntry->m_incoming)
{
NS_LOG_DEBUG ("Send NACK for " << boost::cref (header->GetName ()) << " to " << boost::cref (*incoming.m_face));
incoming.m_face->Send (packet->Copy ());
@@ -680,17 +676,15 @@
}
// All incoming interests cannot be satisfied. Remove them
- m_pit->modify (m_pit->iterator_to (pitEntry),
+ m_pit->modify (pitEntry,
ll::bind (&CcnxPitEntry::ClearIncoming, ll::_1));
// Remove also outgoing
- m_pit->modify (m_pit->iterator_to (pitEntry),
+ m_pit->modify (pitEntry,
ll::bind (&CcnxPitEntry::ClearOutgoing, ll::_1));
// Set pruning timout on PIT entry (instead of deleting the record)
- m_pit->modify (m_pit->iterator_to (pitEntry),
- ll::bind (&CcnxPitEntry::SetExpireTime, ll::_1,
- Simulator::Now () + m_pit->GetPitEntryPruningTimeout ()));
+ m_pit->MarkErased (pitEntry);
}
}
diff --git a/model/ccnx-l3-protocol.h b/model/ccnx-l3-protocol.h
index 1d5a3af..4d01da2 100644
--- a/model/ccnx-l3-protocol.h
+++ b/model/ccnx-l3-protocol.h
@@ -160,20 +160,8 @@
CcnxL3Protocol(const CcnxL3Protocol &); ///< copy constructor is disabled
CcnxL3Protocol &operator = (const CcnxL3Protocol &); ///< copy operator is disabled
- // /// \brief Set buckets leak interval
- // void
- // SetBucketLeakInterval (Time interval);
-
- // /// \brief Get buckets leak interval
- // Time
- // GetBucketLeakInterval () const;
-
- // /// \brief Periodically generate pre-calculated number of tokens (leak buckets)
- // void
- // LeakBuckets ();
-
void
- GiveUpInterest (const CcnxPitEntry &pitEntry,
+ GiveUpInterest (CcnxPit::iterator pitEntry,
Ptr<CcnxInterestHeader> header);
void
diff --git a/model/ccnx-pit-entry.cc b/model/ccnx-pit-entry.cc
index 9c8c389..127b589 100644
--- a/model/ccnx-pit-entry.cc
+++ b/model/ccnx-pit-entry.cc
@@ -36,12 +36,10 @@
CcnxPitEntry::CcnxPitEntry (Ptr<CcnxNameComponents> prefix,
const Time &expireTime,
- const CcnxFibEntry &fibEntry)
+ CcnxFib::iterator fibEntry)
: m_prefix (prefix)
, m_fibEntry (fibEntry)
, m_expireTime (Simulator::Now () + expireTime)
- // , m_timerExpired (false)
- // , m_counterExpirations (0)
, m_maxRetxCount (0)
{
}
@@ -53,7 +51,6 @@
m_expireTime = expireTime;
}
-
void
CcnxPitEntry::UpdateLifetime (const Time &offsetTime)
{
@@ -66,10 +63,10 @@
NS_LOG_INFO ("Updated lifetime to " << m_expireTime.ToDouble (Time::S));
}
-CcnxPitEntryIncomingFaceContainer::type::iterator
+CcnxPitEntry::in_iterator
CcnxPitEntry::AddIncoming (Ptr<CcnxFace> face)
{
- std::pair<CcnxPitEntryIncomingFaceContainer::type::iterator,bool> ret =
+ std::pair<in_iterator,bool> ret =
m_incoming.insert (CcnxPitEntryIncomingFace (face));
NS_ASSERT_MSG (ret.second, "Something is wrong");
@@ -84,10 +81,10 @@
}
-CcnxPitEntryOutgoingFaceContainer::type::iterator
+CcnxPitEntry::out_iterator
CcnxPitEntry::AddOutgoing (Ptr<CcnxFace> face)
{
- std::pair<CcnxPitEntryOutgoingFaceContainer::type::iterator,bool> ret =
+ std::pair<out_iterator,bool> ret =
m_outgoing.insert (CcnxPitEntryOutgoingFace (face));
if (!ret.second)
@@ -102,13 +99,12 @@
void
CcnxPitEntry::RemoveAllReferencesToFace (Ptr<CcnxFace> face)
{
- CcnxPitEntryIncomingFaceContainer::type::iterator incoming =
- m_incoming.find (face);
+ in_iterator incoming = m_incoming.find (face);
if (incoming != m_incoming.end ())
m_incoming.erase (incoming);
- CcnxPitEntryOutgoingFaceContainer::type::iterator outgoing =
+ out_iterator outgoing =
m_outgoing.find (face);
if (outgoing != m_outgoing.end ())
@@ -116,7 +112,7 @@
}
void
-CcnxPitEntry::SetWaitingInVain (CcnxPitEntryOutgoingFaceContainer::type::iterator face)
+CcnxPitEntry::SetWaitingInVain (CcnxPitEntry::out_iterator face)
{
NS_LOG_DEBUG (boost::cref (*face->m_face));
diff --git a/model/ccnx-pit-entry.h b/model/ccnx-pit-entry.h
index 6c69f99..bc81c89 100644
--- a/model/ccnx-pit-entry.h
+++ b/model/ccnx-pit-entry.h
@@ -52,29 +52,6 @@
/**
* \ingroup ccnx
- * \brief Typedef for indexed face container of CcnxPitEntryIncomingFace
- *
- * Indexes:
- * - by face (may be it will be possible to replace with just the std::map)
- */
-struct CcnxPitEntryIncomingFaceContainer
-{
- /// @cond include_hidden
- typedef boost::multi_index::multi_index_container<
- CcnxPitEntryIncomingFace,
- boost::multi_index::indexed_by<
- // For fast access to elements using CcnxFace
- boost::multi_index::ordered_unique<
- boost::multi_index::tag<__ccnx_private::i_face>,
- boost::multi_index::member<CcnxPitEntryIncomingFace, Ptr<CcnxFace>, &CcnxPitEntryIncomingFace::m_face>
- >
- >
- > type;
- /// @endcond
-};
-
-/**
- * \ingroup ccnx
* \brief Typedef for indexed face container of CcnxPitEntryOutgoingFace
*
* Indexes:
@@ -108,13 +85,21 @@
struct CcnxPitEntry
{
public:
+ typedef std::set< CcnxPitEntryIncomingFace > in_container; ///< @brief incoming faces container type
+ typedef in_container::iterator in_iterator; ///< @brief iterator to incoming faces
+
+ typedef CcnxPitEntryOutgoingFaceContainer::type out_container; ///< @brief outgoing faces container type
+ typedef out_container::iterator out_iterator; ///< @brief iterator to outgoing faces
+
+ typedef std::set< uint32_t > nonce_container; ///< @brief nonce container type
+
/**
* \brief PIT entry constructor
* \param prefix Prefix of the PIT entry
* \param offsetTime Relative time to the current moment, representing PIT entry lifetime
* \param fibEntry A FIB entry associated with the PIT entry
*/
- CcnxPitEntry (Ptr<CcnxNameComponents> prefix, const Time &offsetTime, const CcnxFibEntry &fibEntry);
+ CcnxPitEntry (Ptr<CcnxNameComponents> prefix, const Time &offsetTime, CcnxFib::iterator fibEntry);
/**
* @brief Update lifetime of PIT entry
@@ -177,7 +162,7 @@
* @param face Face to add to the list of incoming faces
* @returns iterator to the added entry
*/
- CcnxPitEntryIncomingFaceContainer::type::iterator
+ in_iterator
AddIncoming (Ptr<CcnxFace> face);
/**
@@ -199,7 +184,7 @@
* @param face Face to add to the list of outgoing faces
* @returns iterator to the added entry
*/
- CcnxPitEntryOutgoingFaceContainer::type::iterator
+ out_iterator
AddOutgoing (Ptr<CcnxFace> face);
/**
@@ -222,7 +207,7 @@
* @brief Flag outgoing face as hopeless
*/
void
- SetWaitingInVain (CcnxPitEntryOutgoingFaceContainer::type::iterator face);
+ SetWaitingInVain (out_iterator face);
/**
* @brief Check if all outgoing faces are NACKed
@@ -250,15 +235,15 @@
/**
* \brief Default constructor
*/
- CcnxPitEntry () : m_fibEntry(*((CcnxFibEntry*)0)) {};
+ CcnxPitEntry () {};
public:
Ptr<CcnxNameComponents> m_prefix; ///< \brief Prefix of the PIT entry
- const CcnxFibEntry &m_fibEntry; ///< \brief FIB entry related to this prefix
- std::set<uint32_t> m_seenNonces; ///< \brief map of nonces that were seen for this prefix
+ CcnxFib::iterator m_fibEntry; ///< \brief FIB entry related to this prefix
- CcnxPitEntryIncomingFaceContainer::type m_incoming; ///< \brief container for incoming interests
- CcnxPitEntryOutgoingFaceContainer::type m_outgoing; ///< \brief container for outgoing interests
+ nonce_container m_seenNonces; ///< \brief map of nonces that were seen for this prefix
+ in_container m_incoming; ///< \brief container for incoming interests
+ out_container m_outgoing; ///< \brief container for outgoing interests
Time m_expireTime; ///< \brief Time when PIT entry will be removed
diff --git a/model/ccnx-pit.cc b/model/ccnx-pit.cc
index 4186af4..4824bb1 100644
--- a/model/ccnx-pit.cc
+++ b/model/ccnx-pit.cc
@@ -26,13 +26,14 @@
#include "ccnx-interest-header.h"
#include "ccnx-content-object-header.h"
-#include <boost/bind.hpp>
+#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>
NS_LOG_COMPONENT_DEFINE ("CcnxPit");
using namespace boost::tuples;
using namespace boost;
+namespace ll = boost::lambda;
namespace ns3 {
@@ -121,7 +122,7 @@
void CcnxPit::CleanExpired ()
{
- NS_LOG_LOGIC ("Cleaning PIT. Total: " << size ());
+ // NS_LOG_LOGIC ("Cleaning PIT. Total: " << size ());
Time now = Simulator::Now ();
// uint32_t count = 0;
@@ -137,19 +138,15 @@
break; // nothing else to do. All later records will not be stale
}
- // NS_LOG_LOGIC ("Cleaned " << count << " records. Total: " << size ());
- // schedule next even
-
+ // schedule next event
m_cleanupEvent = Simulator::Schedule (m_cleanupTimeout,
&CcnxPit::CleanExpired, this);
}
-CcnxPitEntryContainer::type::iterator
+CcnxPit::iterator
CcnxPit::Lookup (const CcnxContentObjectHeader &header) const
{
- // NS_LOG_FUNCTION_NOARGS ();
-
- CcnxPitEntryContainer::type::iterator entry = end ();
+ iterator entry = end ();
// do the longest prefix match
const CcnxNameComponents &name = header.GetName ();
@@ -163,69 +160,70 @@
if (entry != end())
return entry;
}
-
- throw CcnxPitEntryNotFound();
+
+ return end ();
}
-boost::tuple<const CcnxPitEntry&, bool, bool>
+CcnxPit::iterator
CcnxPit::Lookup (const CcnxInterestHeader &header)
{
NS_LOG_FUNCTION (header.GetName ());
NS_ASSERT_MSG (m_fib != 0, "FIB should be set");
- bool isDuplicate = false;
- bool isNew = true;
-
- CcnxPitEntryContainer::type::iterator entry =
- get<i_prefix> ().find (header.GetName ());
-
+ iterator entry = get<i_prefix> ().find (header.GetName ());
if (entry == end ())
- {
- if (m_maxSize > 0 &&
- size () >= m_maxSize)
- {
- // remove old record
- get<i_timestamp> ().erase (get<i_timestamp> ().begin ());
- }
-
- CcnxFibEntryContainer::type::iterator fibEntry = m_fib->LongestPrefixMatch (header);
- NS_ASSERT_MSG (fibEntry != m_fib->m_fib.end (),
- "There should be at least default route set" << " Prefix = "<<header.GetName() << "NodeID == " << m_fib->GetObject<Node>()->GetId() << "\n" << *m_fib);
+ return end ();
+
+ return entry;
+}
- entry = insert (end (),
- CcnxPitEntry (Create<CcnxNameComponents> (header.GetName ()),
- header.GetInterestLifetime ().IsZero ()?m_PitEntryDefaultLifetime
- : header.GetInterestLifetime (),
- *fibEntry));
-
- // isDuplicate = false; // redundant
- // isNew = true; // also redundant
- }
- else
- {
- NS_LOG_INFO ("ExpireTime: " << entry->m_expireTime.ToDouble (Time::S));
- if (entry->m_expireTime - Simulator::Now () < MilliSeconds (10))
- {
- modify (entry,
- boost::bind(&CcnxPitEntry::ClearIncoming, boost::lambda::_1));
-
- modify (entry,
- boost::bind(&CcnxPitEntry::ClearOutgoing, boost::lambda::_1));
- }
-
- isNew = entry->m_incoming.size () == 0 && entry->m_outgoing.size () == 0; // entry was preserved to detect loops, but technically removed
- isDuplicate = entry->IsNonceSeen (header.GetNonce ());
- }
-
- if (!isDuplicate)
+bool
+CcnxPit::CheckIfDuplicate (CcnxPit::iterator entry, const CcnxInterestHeader &header)
+{
+ if (!entry->IsNonceSeen (header.GetNonce ()))
{
modify (entry,
- boost::bind(&CcnxPitEntry::AddSeenNonce, boost::lambda::_1, header.GetNonce ()));
+ boost::bind(&CcnxPitEntry::AddSeenNonce, ll::_1, header.GetNonce ()));
+ return false;
}
-
- return make_tuple (cref(*entry), isNew, isDuplicate);
+ else
+ return true;
}
+CcnxPit::iterator
+CcnxPit::Create (const CcnxInterestHeader &header)
+{
+ NS_ASSERT_MSG (get<i_prefix> ().find (header.GetName ()) == end (),
+ "Entry already exists, Create must not be called!!!");
+
+ if (m_maxSize > 0 &&
+ size () >= m_maxSize)
+ {
+ // remove old record
+ get<i_timestamp> ().erase (get<i_timestamp> ().begin ());
+ }
+
+ CcnxFib::iterator fibEntry = m_fib->LongestPrefixMatch (header);
+ // NS_ASSERT_MSG (fibEntry != m_fib->m_fib.end (),
+ // "There should be at least default route set" << " Prefix = "<<header.GetName() << "NodeID == " << m_fib->GetObject<Node>()->GetId() << "\n" << *m_fib);
+
+ return insert (end (),
+ CcnxPitEntry (ns3::Create<CcnxNameComponents> (header.GetName ()),
+ header.GetInterestLifetime ().IsZero ()?m_PitEntryDefaultLifetime
+ : header.GetInterestLifetime (),
+ fibEntry));
+}
+
+
+void
+CcnxPit::MarkErased (CcnxPit::iterator entry)
+{
+ modify (entry,
+ ll::bind (&CcnxPitEntry::SetExpireTime, ll::_1,
+ Simulator::Now () + m_PitEntryPruningTimout));
+}
+
+
std::ostream& operator<< (std::ostream& os, const CcnxPit &pit)
{
BOOST_FOREACH (const CcnxPitEntry &entry, pit)
diff --git a/model/ccnx-pit.h b/model/ccnx-pit.h
index 826f49f..be9c80f 100644
--- a/model/ccnx-pit.h
+++ b/model/ccnx-pit.h
@@ -124,32 +124,50 @@
/**
* \brief Find corresponding PIT entry for the given content name
* \param prefix Prefix for which to lookup the entry
- * \returns const reference to Pit entry. If record not found,
- * CcnxPitEntryNotFound exception will be thrown
+ * \returns iterator to Pit entry. If record not found,
+ * return end() iterator
*/
- CcnxPitEntryContainer::type::iterator
+ iterator
Lookup (const CcnxContentObjectHeader &header) const;
/**
- * \brief Find corresponding PIT entry for the given content name
- * \param prefix Prefix for which to lookup the entry
- * \returns a tuple:
- * get<0>: `const CcnxPitEntry&`: a valid PIT entry (if record does not exist, it will be created)
- * get<1>: `bool`: true if a new entry was created
- * get<2>: `bool`: true if a PIT entry exists and Nonce that present in header has been already seen
- *
+ * \brief Find a PIT entry for the given content interest
+ * \param header parsed interest header
+ * \returns iterator to Pit entry. If record not found,
+ * return end() iterator
*/
- boost::tuple<const CcnxPitEntry&, bool, bool>
+ iterator
Lookup (const CcnxInterestHeader &header);
/**
- * @brief Get pruning timeout for PIT entries (configuration parameter)
+ * @brief Check if the Interest carries an existent nonce.
+ * If not, nonce will be added to the list of known nonces
+ * @returns true if interest is duplicate (carries an existent nonce), false otherwise
*/
- Time GetPitEntryPruningTimeout () const
- {
- return m_PitEntryPruningTimout;
- }
+ bool
+ CheckIfDuplicate (iterator entry, const CcnxInterestHeader &header);
+ /**
+ * @brief Creates a PIT entry for the given interest
+ * @param header parsed interest header
+ * @returns iterator to Pit entry. If record could not be created (e.g., limit reached),
+ * return end() iterator
+ *
+ * Note. This call assumes that the entry does not exist (i.e., there was a Lookup call before)
+ */
+ iterator
+ Create (const CcnxInterestHeader &header);
+
+ /**
+ * @brief Mark PIT entry deleted
+ * @param entry PIT entry
+ *
+ * Effectively, this method removes all incoming/outgoing faces and set
+ * lifetime +m_PitEntryDefaultLifetime from Now ()
+ */
+ void
+ MarkErased (iterator entry);
+
protected:
// inherited from Object class
virtual void NotifyNewAggregate (); ///< @brief Even when object is aggregated to another Object
@@ -195,11 +213,6 @@
std::ostream& operator<< (std::ostream& os, const CcnxPit &pit);
-/**
- * @brief Class for exception when PIT entry is not found
- */
-class CcnxPitEntryNotFound {};
-
} // namespace ns3
#endif /* CCNX_PIT_H */
diff --git a/model/ccnx.h b/model/ccnx.h
index 41e950a..573a567 100644
--- a/model/ccnx.h
+++ b/model/ccnx.h
@@ -142,7 +142,8 @@
NO_FACES, // Interests
NON_DUPLICATED, // Nacks
AFTER_SATISFIED, // Nacks
- UNSOLICITED // data
+ UNSOLICITED, // data
+ PIT_LIMIT // PIT limit reached
};
protected: