nix-vector-routing: (merges !380) Provide faster lookups by IP address
Use hash table to lookup nodes by IP addresses rather than linear search
This commit is contained in:
committed by
Tom Henderson
parent
4d1387cac0
commit
8fa163fb0a
@@ -25,6 +25,7 @@
|
||||
#include "ns3/abort.h"
|
||||
#include "ns3/names.h"
|
||||
#include "ns3/ipv4-list-routing.h"
|
||||
#include "ns3/loopback-net-device.h"
|
||||
|
||||
#include "ipv4-nix-vector-routing.h"
|
||||
|
||||
@@ -35,6 +36,7 @@ NS_LOG_COMPONENT_DEFINE ("Ipv4NixVectorRouting");
|
||||
NS_OBJECT_ENSURE_REGISTERED (Ipv4NixVectorRouting);
|
||||
|
||||
bool Ipv4NixVectorRouting::g_isCacheDirty = false;
|
||||
Ipv4NixVectorRouting::Ipv4AddressToNodeMap Ipv4NixVectorRouting::g_ipv4AddressToNodeMap;
|
||||
|
||||
TypeId
|
||||
Ipv4NixVectorRouting::GetTypeId (void)
|
||||
@@ -105,6 +107,10 @@ Ipv4NixVectorRouting::FlushGlobalNixRoutingCache (void) const
|
||||
rp->FlushNixCache ();
|
||||
rp->FlushIpv4RouteCache ();
|
||||
}
|
||||
|
||||
// IPv4 address to node mapping is potentially invalid so clear it.
|
||||
// Will be repopulated in lazy evaluation when mapping is needed.
|
||||
g_ipv4AddressToNodeMap.clear ();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -342,29 +348,68 @@ Ipv4NixVectorRouting::GetAdjacentNetDevices (Ptr<NetDevice> netDevice, Ptr<Chann
|
||||
}
|
||||
}
|
||||
|
||||
Ptr<Node>
|
||||
Ipv4NixVectorRouting::GetNodeByIp (Ipv4Address dest)
|
||||
{
|
||||
void
|
||||
Ipv4NixVectorRouting::BuildIpv4AddressToNodeMap (void)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
|
||||
NodeContainer allNodes = NodeContainer::GetGlobal ();
|
||||
Ptr<Node> destNode;
|
||||
|
||||
for (NodeContainer::Iterator i = allNodes.Begin (); i != allNodes.End (); ++i)
|
||||
for (NodeList::Iterator it = NodeList::Begin (); it != NodeList::End (); ++it)
|
||||
{
|
||||
Ptr<Node> node = *i;
|
||||
Ptr<Node> node = *it;
|
||||
Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
|
||||
if (ipv4->GetInterfaceForAddress (dest) != -1)
|
||||
|
||||
if(ipv4)
|
||||
{
|
||||
destNode = node;
|
||||
break;
|
||||
uint32_t numberOfDevices = node->GetNDevices ();
|
||||
|
||||
for (uint32_t deviceId = 0; deviceId < numberOfDevices; deviceId++)
|
||||
{
|
||||
Ptr<NetDevice> device = node->GetDevice (deviceId);
|
||||
|
||||
// If this is not a loopback device add the IPv4 address to the map
|
||||
if ( !DynamicCast<LoopbackNetDevice>(device) )
|
||||
{
|
||||
int32_t interfaceIndex = (ipv4)->GetInterfaceForDevice (node->GetDevice (deviceId));
|
||||
if (interfaceIndex != -1)
|
||||
{
|
||||
Ipv4InterfaceAddress ifAddr = ipv4->GetAddress (interfaceIndex, 0);
|
||||
Ipv4Address addr = ifAddr.GetLocal ();
|
||||
|
||||
NS_ABORT_MSG_IF (g_ipv4AddressToNodeMap.count (addr),
|
||||
"Duplicate IPv4 address (" << addr << ") found during NIX Vector map construction for node " << node->GetId ());
|
||||
|
||||
NS_LOG_LOGIC ("Adding IPv4 address " << addr << " for node " << node->GetId () << " to NIX Vector IPv4 address to node map");
|
||||
g_ipv4AddressToNodeMap[addr] = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!destNode)
|
||||
Ptr<Node>
|
||||
Ipv4NixVectorRouting::GetNodeByIp (Ipv4Address dest)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
|
||||
// Populate lookup table if is empty.
|
||||
if ( g_ipv4AddressToNodeMap.empty () )
|
||||
{
|
||||
BuildIpv4AddressToNodeMap ();
|
||||
}
|
||||
|
||||
Ptr<Node> destNode;
|
||||
|
||||
Ipv4AddressToNodeMap::iterator iter = g_ipv4AddressToNodeMap.find(dest);
|
||||
|
||||
if(iter == g_ipv4AddressToNodeMap.end ())
|
||||
{
|
||||
NS_LOG_ERROR ("Couldn't find dest node given the IP" << dest);
|
||||
return 0;
|
||||
destNode = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
destNode = iter -> second;
|
||||
}
|
||||
|
||||
return destNode;
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
#ifndef IPV4_NIX_VECTOR_ROUTING_H
|
||||
#define IPV4_NIX_VECTOR_ROUTING_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "ns3/channel.h"
|
||||
#include "ns3/node-container.h"
|
||||
#include "ns3/node-list.h"
|
||||
@@ -33,6 +31,9 @@
|
||||
#include "ns3/bridge-net-device.h"
|
||||
#include "ns3/nstime.h"
|
||||
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
@@ -227,6 +228,11 @@ private:
|
||||
*/
|
||||
void CheckCacheStateAndFlush (void) const;
|
||||
|
||||
/**
|
||||
* Build map from IPv4 Address to Node for faster lookup.
|
||||
*/
|
||||
void BuildIpv4AddressToNodeMap (void);
|
||||
|
||||
/**
|
||||
* Flag to mark when caches are dirty and need to be flushed.
|
||||
* Used for lazy cleanup of caches when there are many topology changes.
|
||||
@@ -244,6 +250,33 @@ private:
|
||||
|
||||
/** Total neighbors used for nix-vector to determine number of bits */
|
||||
uint32_t m_totalNeighbors;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Hashing for the ipv4Address class
|
||||
*/
|
||||
struct Ipv4AddressHash
|
||||
{
|
||||
/**
|
||||
* \brief operator ()
|
||||
* \param address the IPv4 address to hash
|
||||
* \return the hash of the address
|
||||
*/
|
||||
size_t operator() (const Ipv4Address &address) const
|
||||
{
|
||||
return std::hash<uint32_t>()(address.Get ());
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Mapping of IPv4 address to ns-3 node.
|
||||
*
|
||||
* Used to avoid linear searching of nodes/devices to find a node in
|
||||
* GetNodeByIp() method. NIX vector routing assumes IP addresses
|
||||
* are unique so mapping can be done without duplication.
|
||||
**/
|
||||
typedef std::unordered_map<Ipv4Address, ns3::Ptr<ns3::Node>, Ipv4AddressHash > Ipv4AddressToNodeMap;
|
||||
static Ipv4AddressToNodeMap g_ipv4AddressToNodeMap;
|
||||
};
|
||||
} // namespace ns3
|
||||
|
||||
|
||||
Reference in New Issue
Block a user