examples: New example with custom strategy "random-load-balancer-strategy"
Based on Steve DiBenedetto's tutorial code https://github.com/dibenede/ndn-tutorial-gec21
diff --git a/examples/ndn-load-balancer/random-load-balancer-strategy.cpp b/examples/ndn-load-balancer/random-load-balancer-strategy.cpp
new file mode 100644
index 0000000..6083dd3
--- /dev/null
+++ b/examples/ndn-load-balancer/random-load-balancer-strategy.cpp
@@ -0,0 +1,100 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, Regents of the University of California,
+ * Arizona Board of Regents,
+ * Colorado State University,
+ * University Pierre & Marie Curie, Sorbonne University,
+ * Washington University in St. Louis,
+ * Beijing Institute of Technology,
+ * The University of Memphis
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD 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.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "random-load-balancer-strategy.hpp"
+
+#include <boost/random/uniform_int_distribution.hpp>
+
+#include <ndn-cxx/util/random.hpp>
+
+#include "core/logger.hpp"
+
+NFD_LOG_INIT("RandomLoadBalancerStrategy");
+
+namespace nfd {
+namespace fw {
+
+const Name
+ RandomLoadBalancerStrategy::STRATEGY_NAME("ndn:/localhost/nfd/strategy/random-load-balancer");
+
+RandomLoadBalancerStrategy::RandomLoadBalancerStrategy(Forwarder& forwarder, const Name& name)
+ : Strategy(forwarder, name)
+{
+}
+
+RandomLoadBalancerStrategy::~RandomLoadBalancerStrategy()
+{
+}
+
+static bool
+canForwardToNextHop(shared_ptr<pit::Entry> pitEntry, const fib::NextHop& nexthop)
+{
+ return pitEntry->canForwardTo(*nexthop.getFace());
+}
+
+static bool
+hasFaceForForwarding(const fib::NextHopList& nexthops, shared_ptr<pit::Entry>& pitEntry)
+{
+ return std::find_if(nexthops.begin(), nexthops.end(), bind(&canForwardToNextHop, pitEntry, _1))
+ != nexthops.end();
+}
+
+void
+RandomLoadBalancerStrategy::afterReceiveInterest(const Face& inFace, const Interest& interest,
+ shared_ptr<fib::Entry> fibEntry,
+ shared_ptr<pit::Entry> pitEntry)
+{
+ NFD_LOG_TRACE("afterReceiveInterest");
+
+ if (pitEntry->hasUnexpiredOutRecords()) {
+ // not a new Interest, don't forward
+ return;
+ }
+
+ const fib::NextHopList& nexthops = fibEntry->getNextHops();
+
+ // Ensure there is at least 1 Face is available for forwarding
+ if (!hasFaceForForwarding(nexthops, pitEntry)) {
+ this->rejectPendingInterest(pitEntry);
+ return;
+ }
+
+ fib::NextHopList::const_iterator selected;
+ do {
+ boost::random::uniform_int_distribution<> dist(0, nexthops.size() - 1);
+ const size_t randomIndex = dist(m_randomGenerator);
+
+ uint64_t currentIndex = 0;
+
+ for (selected = nexthops.begin(); selected != nexthops.end() && currentIndex != randomIndex;
+ ++selected, ++currentIndex) {
+ }
+ } while (!canForwardToNextHop(pitEntry, *selected));
+
+ this->sendInterest(pitEntry, selected->getFace());
+}
+
+} // namespace fw
+} // namespace nfd