diff --git a/src/nix-vector-routing/model/ipv4-nix-vector-routing.cc b/src/nix-vector-routing/model/ipv4-nix-vector-routing.cc index e64c4a9da..105c268d5 100644 --- a/src/nix-vector-routing/model/ipv4-nix-vector-routing.cc +++ b/src/nix-vector-routing/model/ipv4-nix-vector-routing.cc @@ -34,6 +34,8 @@ NS_LOG_COMPONENT_DEFINE ("Ipv4NixVectorRouting"); NS_OBJECT_ENSURE_REGISTERED (Ipv4NixVectorRouting); +bool Ipv4NixVectorRouting::g_isCacheDirty = false; + TypeId Ipv4NixVectorRouting::GetTypeId (void) { @@ -86,7 +88,7 @@ Ipv4NixVectorRouting::SetNode (Ptr node) } void -Ipv4NixVectorRouting::FlushGlobalNixRoutingCache () +Ipv4NixVectorRouting::FlushGlobalNixRoutingCache (void) const { NS_LOG_FUNCTION_NOARGS (); NodeList::Iterator listEnd = NodeList::End (); @@ -105,14 +107,14 @@ Ipv4NixVectorRouting::FlushGlobalNixRoutingCache () } void -Ipv4NixVectorRouting::FlushNixCache () +Ipv4NixVectorRouting::FlushNixCache (void) const { NS_LOG_FUNCTION_NOARGS (); m_nixCache.clear (); } void -Ipv4NixVectorRouting::FlushIpv4RouteCache () +Ipv4NixVectorRouting::FlushIpv4RouteCache (void) const { NS_LOG_FUNCTION_NOARGS (); m_ipv4RouteCache.clear (); @@ -168,6 +170,8 @@ Ipv4NixVectorRouting::GetNixVectorInCache (Ipv4Address address) { NS_LOG_FUNCTION_NOARGS (); + CheckCacheStateAndFlush (); + NixMap_t::iterator iter = m_nixCache.find (address); if (iter != m_nixCache.end ()) { @@ -184,6 +188,8 @@ Ipv4NixVectorRouting::GetIpv4RouteInCache (Ipv4Address address) { NS_LOG_FUNCTION_NOARGS (); + CheckCacheStateAndFlush (); + Ipv4RouteMap_t::iterator iter = m_ipv4RouteCache.find (address); if (iter != m_ipv4RouteCache.end ()) { @@ -364,7 +370,7 @@ Ipv4NixVectorRouting::GetNodeByIp (Ipv4Address dest) } uint32_t -Ipv4NixVectorRouting::FindTotalNeighbors () +Ipv4NixVectorRouting::FindTotalNeighbors (void) { uint32_t numberOfDevices = m_node->GetNDevices (); uint32_t totalNeighbors = 0; @@ -488,6 +494,8 @@ Ipv4NixVectorRouting::RouteOutput (Ptr p, const Ipv4Header &header, Ptr< Ptr nixVectorInCache; Ptr nixVectorForPacket; + CheckCacheStateAndFlush (); + NS_LOG_DEBUG ("Dest IP from header: " << header.GetDestination ()); // check if cache nixVectorInCache = GetNixVectorInCache (header.GetDestination ()); @@ -608,6 +616,8 @@ Ipv4NixVectorRouting::RouteInput (Ptr p, const Ipv4Header &header, { NS_LOG_FUNCTION_NOARGS (); + CheckCacheStateAndFlush (); + Ptr rtentry; // Get the nix-vector from the packet @@ -663,6 +673,8 @@ void Ipv4NixVectorRouting::PrintRoutingTable (Ptr stream) const { + CheckCacheStateAndFlush (); + std::ostream* os = stream->GetStream (); *os << "NixCache:" << std::endl; if (m_nixCache.size () > 0) @@ -707,22 +719,22 @@ Ipv4NixVectorRouting::PrintRoutingTable (Ptr stream) const void Ipv4NixVectorRouting::NotifyInterfaceUp (uint32_t i) { - FlushGlobalNixRoutingCache (); + g_isCacheDirty = true; } void Ipv4NixVectorRouting::NotifyInterfaceDown (uint32_t i) { - FlushGlobalNixRoutingCache (); + g_isCacheDirty = true; } void Ipv4NixVectorRouting::NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address) { - FlushGlobalNixRoutingCache (); + g_isCacheDirty = true; } void Ipv4NixVectorRouting::NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address) { - FlushGlobalNixRoutingCache (); + g_isCacheDirty = true; } bool @@ -873,4 +885,14 @@ Ipv4NixVectorRouting::BFS (uint32_t numberOfNodes, Ptr source, return false; } +void +Ipv4NixVectorRouting::CheckCacheStateAndFlush (void) const +{ + if (g_isCacheDirty) + { + FlushGlobalNixRoutingCache (); + g_isCacheDirty = false; + } +} + } // namespace ns3 diff --git a/src/nix-vector-routing/model/ipv4-nix-vector-routing.h b/src/nix-vector-routing/model/ipv4-nix-vector-routing.h index 5282d39e9..edb85e1fe 100644 --- a/src/nix-vector-routing/model/ipv4-nix-vector-routing.h +++ b/src/nix-vector-routing/model/ipv4-nix-vector-routing.h @@ -73,17 +73,22 @@ public: * which iterates through the node list and flushes any * nix vector caches * + * \internal + * \c const is used here due to need to potentially flush the cache + * in const methods such as PrintRoutingTable. Caches are stored in + * mutable variables and flushed in const methods. */ - void FlushGlobalNixRoutingCache (void); + void FlushGlobalNixRoutingCache (void) const; private: + /* flushes the cache which stores nix-vector based on * destination IP */ - void FlushNixCache (void); + void FlushNixCache (void) const; /* flushes the cache which stores the Ipv4 route * based on the destination IP */ - void FlushIpv4RouteCache (void); + void FlushIpv4RouteCache (void) const; /* upon a run-time topology change caches are * flushed and the total number of neighbors is @@ -155,17 +160,27 @@ private: virtual void SetIpv4 (Ptr ipv4); virtual void PrintRoutingTable (Ptr stream) const; + /* + * Flushes routing caches if required. + */ + void CheckCacheStateAndFlush (void) const; - /* cache stores nix-vectors based on destination ip */ - NixMap_t m_nixCache; + /* + * Flag to mark when caches are dirty and need to be flushed. + * Used for lazy cleanup of caches when there are many topology changes. + */ + static bool g_isCacheDirty; - /* cache stores Ipv4Routes based on destination ip */ - Ipv4RouteMap_t m_ipv4RouteCache; + /* Cache stores nix-vectors based on destination ip */ + mutable NixMap_t m_nixCache; + + /* Cache stores Ipv4Routes based on destination ip */ + mutable Ipv4RouteMap_t m_ipv4RouteCache; Ptr m_ipv4; Ptr m_node; - /* total neighbors used for nix-vector to determine + /* Total neighbors used for nix-vector to determine * number of bits */ uint32_t m_totalNeighbors; };