helper+model: Create helper to select the replacement policy of NFD's CS
Change-Id: I10933b5c96fd95bc395a1d08642a1e07e826dc45
Refs: #3837
diff --git a/helper/ndn-stack-helper.cpp b/helper/ndn-stack-helper.cpp
index 3b5571a..4b9cd90 100644
--- a/helper/ndn-stack-helper.cpp
+++ b/helper/ndn-stack-helper.cpp
@@ -36,6 +36,9 @@
#include <map>
#include <boost/lexical_cast.hpp>
+#include "ns3/ndnSIM/NFD/daemon/table/cs-policy-priority-fifo.hpp"
+#include "ns3/ndnSIM/NFD/daemon/table/cs-policy-lru.hpp"
+
NS_LOG_COMPONENT_DEFINE("ndn.StackHelper");
namespace ns3 {
@@ -51,6 +54,11 @@
{
setCustomNdnCxxClocks();
+ m_csPolicies.insert({"nfd::cs::lru", [] { return make_unique<nfd::cs::LruPolicy>(); }});
+ m_csPolicies.insert({"nfd::cs::priority_fifo", [] () { return make_unique<nfd::cs::PriorityFifoPolicy>(); }});
+
+ m_csPolicyCreationFunc = m_csPolicies["nfd::cs::lru"];
+
m_ndnFactory.SetTypeId("ns3::ndn::L3Protocol");
m_contentStoreFactory.SetTypeId("ns3::ndn::cs::Lru");
@@ -127,6 +135,22 @@
m_maxCsSize = maxSize;
}
+void
+StackHelper::setPolicy(const std::string& policy)
+{
+ auto found = m_csPolicies.find(policy);
+ if (found != m_csPolicies.end()) {
+ m_csPolicyCreationFunc = found->second;
+ }
+ else {
+ NS_FATAL_ERROR("Cache replacement policy " << policy << " not found");
+ NS_LOG_DEBUG("Available cache replacement policies: ");
+ for (auto it = m_csPolicies.begin(); it != m_csPolicies.end(); it++) {
+ NS_LOG_DEBUG(" " << it->first);
+ }
+ }
+}
+
Ptr<FaceContainer>
StackHelper::Install(const NodeContainer& c) const
{
@@ -178,6 +202,10 @@
if (m_maxCsSize == 0) {
ndn->AggregateObject(m_contentStoreFactory.Create<ContentStore>());
}
+ // if NFD's CS is enabled, check if a replacement policy has been specified
+ else {
+ ndn->setCsReplacementPolicy(m_csPolicyCreationFunc);
+ }
// Aggregate L3Protocol on node (must be after setting ndnSIM CS)
node->AggregateObject(ndn);
diff --git a/helper/ndn-stack-helper.hpp b/helper/ndn-stack-helper.hpp
index 0cb3413..bae814f 100644
--- a/helper/ndn-stack-helper.hpp
+++ b/helper/ndn-stack-helper.hpp
@@ -31,6 +31,12 @@
#include "ndn-fib-helper.hpp"
#include "ndn-strategy-choice-helper.hpp"
+namespace nfd {
+namespace cs {
+class Policy;
+} // namespace cs
+} // namespace nfd
+
namespace ns3 {
class Node;
@@ -75,6 +81,12 @@
setCsSize(size_t maxSize);
/**
+ * @brief Set the cache replacement policy for NFD's Content Store
+ */
+ void
+ setPolicy(const std::string& policy);
+
+ /**
* @brief Set ndnSIM 1.0 content store implementation and its attributes
* @param contentStoreClass string, representing class of the content store
* @note ndnSIM 1.0 content store implementation have limited support for Interest selectors
@@ -262,6 +274,11 @@
bool m_needSetDefaultRoutes;
size_t m_maxCsSize;
+ typedef std::function<std::unique_ptr<nfd::cs::Policy>()> PolicyCreationCallback;
+ PolicyCreationCallback m_csPolicyCreationFunc;
+
+ std::map<std::string, PolicyCreationCallback> m_csPolicies;
+
typedef std::list<std::pair<TypeId, FaceCreateCallback>> NetDeviceCallbackList;
NetDeviceCallbackList m_netDeviceCallbacks;
};
diff --git a/model/ndn-l3-protocol.cpp b/model/ndn-l3-protocol.cpp
index 33e0113..e8f7ccc 100644
--- a/model/ndn-l3-protocol.cpp
+++ b/model/ndn-l3-protocol.cpp
@@ -179,6 +179,7 @@
nfd::ConfigSection m_config;
Ptr<ContentStore> m_csFromNdnSim;
+ PolicyCreationCallback m_policy;
};
L3Protocol::L3Protocol()
@@ -239,6 +240,12 @@
}
void
+L3Protocol::setCsReplacementPolicy(const PolicyCreationCallback& policy)
+{
+ m_impl->m_policy = policy;
+}
+
+void
L3Protocol::initializeManagement()
{
auto& forwarder = m_impl->m_forwarder;
@@ -280,6 +287,12 @@
ConfigFile config(&ConfigFile::ignoreUnknownSection);
+ // if we use NFD's CS, we have to specify a replacement policy
+ m_impl->m_csFromNdnSim = GetObject<ContentStore>();
+ if (m_impl->m_csFromNdnSim == nullptr) {
+ forwarder->getCs().setPolicy(m_impl->m_policy());
+ }
+
TablesConfigSection tablesConfig(forwarder->getCs(),
forwarder->getPit(),
forwarder->getFib(),
diff --git a/model/ndn-l3-protocol.hpp b/model/ndn-l3-protocol.hpp
index a34d36f..cca0277 100644
--- a/model/ndn-l3-protocol.hpp
+++ b/model/ndn-l3-protocol.hpp
@@ -40,6 +40,9 @@
namespace pit {
class Entry;
} // namespace pit
+namespace cs {
+class Policy;
+} // namespace cs
} // namespace nfd
namespace ns3 {
@@ -153,6 +156,14 @@
void
injectInterest(const Interest& interest);
+ typedef std::function<std::unique_ptr<nfd::cs::Policy>()> PolicyCreationCallback;
+
+ /**
+ * \brief Set the replacement policy of NFD's CS
+ */
+ void
+ setCsReplacementPolicy(const PolicyCreationCallback& policy);
+
public: // Workaround for python bindings
static Ptr<L3Protocol>
getL3Protocol(Ptr<Object> node);
diff --git a/tests/unit-tests/helper/ndn-stack-helper.t.cpp b/tests/unit-tests/helper/ndn-stack-helper.t.cpp
new file mode 100644
index 0000000..25df0a2
--- /dev/null
+++ b/tests/unit-tests/helper/ndn-stack-helper.t.cpp
@@ -0,0 +1,68 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2011-2016 Regents of the University of California.
+ *
+ * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
+ * contributors.
+ *
+ * ndnSIM is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndnSIM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndnSIM, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "helper/ndn-stack-helper.hpp"
+#include "../tests-common.hpp"
+
+#include "ns3/point-to-point-module.h"
+
+namespace ns3 {
+namespace ndn {
+
+BOOST_FIXTURE_TEST_SUITE(HelperStackHelper, CleanupFixture)
+
+BOOST_AUTO_TEST_CASE(TestNfdContentStorePolicy)
+{
+ // setting default parameters for PointToPoint links and channels
+ Config::SetDefault("ns3::PointToPointNetDevice::DataRate", StringValue("10Mbps"));
+ Config::SetDefault("ns3::PointToPointChannel::Delay", StringValue("10ms"));
+ Config::SetDefault("ns3::DropTailQueue::MaxPackets", StringValue("20"));
+
+ // Creating nodes
+ NodeContainer nodes;
+ nodes.Create(2);
+
+ // Connecting nodes using two links
+ PointToPointHelper p2p;
+ p2p.Install(nodes.Get(0), nodes.Get(1));
+
+ // Install NDN stack on all nodes
+ ndn::StackHelper ndnHelper;
+ ndnHelper.SetDefaultRoutes(true);
+ ndnHelper.setPolicy("nfd::cs::lru");
+ ndnHelper.Install(nodes.Get(0));
+
+ // test which CS policy has be selected for node 0
+ Ptr<L3Protocol> protoNode0 = L3Protocol::getL3Protocol(nodes.Get(0));
+ BOOST_CHECK_EQUAL(protoNode0->getForwarder()->getCs().getPolicy()->getName(), "lru");
+
+ ndnHelper.setPolicy("nfd::cs::priority_fifo");
+ ndnHelper.Install(nodes.Get(1));
+
+ Ptr<L3Protocol> protoNode1 = L3Protocol::getL3Protocol(nodes.Get(1));
+ // test that the CS policy for node 0 did not change
+ BOOST_CHECK_EQUAL(protoNode0->getForwarder()->getCs().getPolicy()->getName(), "lru");
+ // test which CS policy has be selected for node 1
+ BOOST_CHECK_EQUAL(protoNode1->getForwarder()->getCs().getPolicy()->getName(), "fifo");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace ndn
+} // namespace ns3