Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1336)

Unified Diff: src/pgbr/helper/multiple-flows-application-helper.cc

Issue 15530043: New module pgbr (PGBR routing protocol) and extension of topology-read module
Patch Set: Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/pgbr/helper/multiple-flows-application-helper.cc
===================================================================
new file mode 100644
--- /dev/null
+++ b/src/pgbr/helper/multiple-flows-application-helper.cc
@@ -0,0 +1,266 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) Waterford Institute of Technology, 2013, Julien Mineraud, BioFINT.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Julien Mineraud <julien.mineraud@gmail.com>
+ *
+ * Acknowledgements:
+ * This work has received support from Science Foundation Ireland via the
+ * "A Biologically inspired framework supporting network management for
+ * the Future Internet" starting investigator award (grant no. 09/SIRG/I1643).
+ */
+
+#include "multiple-flows-application-helper.h"
+#include "ns3/string.h"
+#include "ns3/node.h"
+#include "ns3/names.h"
+#include "ns3/log.h"
+#include <list>
+#include "ns3/flow-id-tag.h"
+
+NS_LOG_COMPONENT_DEFINE ("MultipleFlowsApplicationHelper");
+
+namespace ns3 {
+namespace pgbr {
+
+MultipleFlowsApplicationHelper::MultipleFlowsApplicationHelper (std::string protocol, Address address)
+{
+ m_durationInterval = Seconds (10);
+ m_durationVariable = UniformVariable (6.0, 10.0);
+ m_startVariable = ExponentialVariable (0.5);
+ m_payloadVariable = UniformVariable (20000, 100000);
+ m_factory.SetTypeId ("ns3::pgbr::MultipleFlowsApplication");
+ m_factory.Set ("Protocol", StringValue (protocol));
+ m_factory.Set ("Remote", AddressValue (address));
+}
+
+void
+MultipleFlowsApplicationHelper::SetAttribute (std::string name, const AttributeValue &value)
+{
+ m_factory.Set (name, value);
+}
+
+ApplicationContainer
+MultipleFlowsApplicationHelper::InstallFlows (Ptr<Node> node, uint32_t packetSize, bool justOnePacket)
+{
+ std::list<Flow> flows = GetFlowList ();
+ ApplicationContainer applications;
+ Ptr<MultipleFlowsApplication> multipleFlowApp = Install (node);
+ for (std::list<Flow>::const_iterator it = flows.begin (); it != flows.end (); it++)
+ {
+ Flow f = (*it);
+ if (f.duration > 0)
+ {
+ multipleFlowApp->AddInnerFlow (f.start, f.duration, f.bitRate, packetSize, false);
+ }
+ }
+ NS_LOG_DEBUG ("I generated normally " << flows.size() << " flows");
+ applications.Add (multipleFlowApp);
+ return applications;
+}
+
+void
+MultipleFlowsApplicationHelper::Save (Ptr<OutputStreamWrapper> stream, Ptr<Node> src, Ptr<Node> dst)
+{
+ std::list<Flow> flows = GetFlowList ();
+ for (std::list<Flow>::const_iterator it = flows.begin (); it != flows.end (); it++)
+ {
+ Flow f = (*it);
+ if (f.duration > 0)
+ {
+ *stream->GetStream () << f.start << "\t" << f.duration << "\t" << src->GetId () << "\t" << dst->GetId () << "\t" << f.bitRate << std::endl;
+ }
+ }
+}
+
+void
+MultipleFlowsApplicationHelper::AddInterval (DataRate dataRate)
+{
+ m_cbrRates.push_back (dataRate);
+}
+
+void
+MultipleFlowsApplicationHelper::SetDurationInterval (Time durationInterval)
+{
+ NS_ASSERT (durationInterval.IsStrictlyPositive ());
+ m_durationInterval = durationInterval;
+}
+
+void
+MultipleFlowsApplicationHelper::SetStartVariable (RandomVariable startVariable)
+{
+ m_startVariable = startVariable;
+}
+
+void
+MultipleFlowsApplicationHelper::SetDurationVariable (RandomVariable durationVariable)
+{
+ m_durationVariable = durationVariable;
+}
+
+void
+MultipleFlowsApplicationHelper::SetPayloadVariable (RandomVariable payloadVariable)
+{
+ m_payloadVariable = payloadVariable;
+}
+
+std::list<MultipleFlowsApplicationHelper::Flow>
+MultipleFlowsApplicationHelper::GetFlowList ()
+{
+ std::list<Flow> flows;
+ double_t intervalDuration = m_durationInterval.GetSeconds ();
+ //std::list<Flow> acceptedFlows; //To reduce the number of flows that I have to search through, I can put the one that started and finished before the current interval in there
+ for (uint32_t zone = 0; zone < m_cbrRates.size (); zone++)
+ {
+ NS_LOG_DEBUG ("Welcome to the zone " << zone << "!");
+ //First thing is to calculate in a zone, the expected
+ uint64_t expectedGeneratedBits = m_cbrRates[zone].GetBitRate () * intervalDuration;
+ NS_LOG_DEBUG ("The expected generated bits for zone " << zone << "=" << expectedGeneratedBits);
+
+ //Second get the already generated bits from the flow vector.
+ uint64_t alreadyInThePipe = 0;
+ for (std::list<Flow>::const_iterator it = flows.begin (); it != flows.end (); it++)
+ {
+ Flow f = (*it);
+ if (f.start + f.duration > (zone * intervalDuration))
+ {
+ double start = (zone * intervalDuration);
+ double stop = (f.start + f.duration > ((zone + 1) * intervalDuration)) ? ((zone + 1) * intervalDuration) : f.start + f.duration;
+ alreadyInThePipe += (stop - start) * f.bitRate;
+ }
+ }
+ NS_LOG_DEBUG ("There are already " << alreadyInThePipe << " bits in the pipe");
+ //Then there are three option.
+ if (alreadyInThePipe == expectedGeneratedBits)
+ {
+ NS_LOG_DEBUG ("The bits were generated, no need to do anything");
+ continue;
+ }
+ else if (alreadyInThePipe < expectedGeneratedBits)
+ {
+ NS_LOG_DEBUG ("I need to generate more flows");
+ double_t tempStart = (zone * intervalDuration);
+ while (alreadyInThePipe < expectedGeneratedBits)
+ {
+ Flow f;
+ f.id = flows.size () + 1;
+ f.start = tempStart + m_startVariable.GetValue ();
+ f.duration = m_durationVariable.GetValue ();
+ f.bitRate = m_payloadVariable.GetValue ();
+ double_t end = (f.start + f.duration > ((zone + 1) * intervalDuration)) ? ((zone + 1) * intervalDuration) : f.start + f.duration;
+ double_t diff = end - f.start;
+ uint64_t addedBits = diff * f.bitRate;
+ uint32_t leftBits = expectedGeneratedBits - alreadyInThePipe;
+ if (addedBits > leftBits)
+ {
+ NS_LOG_DEBUG ("I need to modify the duration of this request to generate less bits");
+ double_t newDiff = leftBits * 1.0 / f.bitRate;
+ f.duration = newDiff;
+ addedBits = leftBits;
+ }
+ alreadyInThePipe += addedBits;
+ //std::cout << "I add flow " << f << " and now, there are " << alreadyInThePipe << " bits generated for this zone\n";
+ //tempStart = f.start;
+ flows.push_back (f);
+ }
+ }
+ else
+ {
+ NS_LOG_DEBUG ("I would have to remove some flows");
+ while (alreadyInThePipe > expectedGeneratedBits)
+ {
+ uint64_t bitstooMany = alreadyInThePipe - expectedGeneratedBits;
+ NS_LOG_DEBUG ("There are still " << bitstooMany << " many bits in the pipe");
+ //Find the flow that generate the most bits in the interval and stop this flows at the time required (min being the beginning of the interval)
+ //Reproduce until I have the required number of flows.
+ uint32_t maxBits = 0;
+ uint32_t maxFlowId = 0;
+ for (std::list<Flow>::const_iterator it = flows.begin (); it != flows.end (); it++)
+ {
+ Flow f = (*it);
+ if (f.start + f.duration > (zone * intervalDuration))
+ {
+ double_t start = f.start > (zone * intervalDuration) ? f.start : (zone * intervalDuration);
+ double_t end = f.start + f.duration > ((zone + 1) * intervalDuration) ? (zone + 1) * intervalDuration : f.start + f.duration;
+ double_t diff = end - start;
+ uint32_t bitsInZone = diff * f.bitRate;
+ if (bitsInZone > maxBits)
+ {
+ maxBits = bitsInZone;
+ maxFlowId = f.id;
+ }
+ }
+ }
+ NS_ASSERT (maxBits > 0 && maxFlowId > 0);
+ for (std::list<Flow>::iterator it = flows.begin (); it != flows.end (); it++)
+ {
+ if (it->id == maxFlowId)
+ {
+ //std::cout << "The flow that generate the most bits in zone " << zone << " is " << (*it) << "\n";
+ double_t start = it->start > (zone * intervalDuration) ? it->start : (zone * intervalDuration);
+ double_t end = it->start + it->duration > ((zone + 1) * intervalDuration) ? (zone + 1) * intervalDuration : it->start + it->duration;
+ double_t diff = end - start;
+ uint32_t bitsInZone = diff * it->bitRate;
+ NS_LOG_DEBUG ("It has generated " << bitsInZone << " bits in that zone");
+
+ if (bitsInZone < bitstooMany)
+ {
+ NS_LOG_DEBUG ("reset duration so it finishes at the zone");
+ //Easy, I just set the start at zone * intervalDuration
+ if (it->start < (zone * intervalDuration))
+ {
+ it->duration = (zone * intervalDuration) - it->start;
+ }
+ else
+ {
+ NS_LOG_DEBUG ("We even kill the damned thing");
+ it->duration = 0;
+ }
+ alreadyInThePipe -= bitsInZone;
+ }
+ else
+ {
+ NS_LOG_DEBUG ("I dont have to reset until the beginning of the zone, normally it should be the last call");
+ //In that case I have to count how much I have to remove
+ if (it->start + it->duration > ((zone + 1) * intervalDuration))
+ {
+ it->duration = ((zone + 1) * intervalDuration) - it->start;
+ }
+
+ double_t timeToMakeTheBitsToMany = bitstooMany * 1.0 / it->bitRate;
+ it->duration = it->duration - timeToMakeTheBitsToMany;
+ NS_ASSERT (it->duration >= 0);
+ alreadyInThePipe = expectedGeneratedBits;
+ }
+ //std::cout << "The modified flow is now " << (*it) << "\n";
+ break;
+ }
+ }
+ }
+ }
+ }
+ return flows;
+}
+
+Ptr<MultipleFlowsApplication>
+MultipleFlowsApplicationHelper::Install (Ptr<Node> node)
+{
+ Ptr<MultipleFlowsApplication> app = m_factory.Create<MultipleFlowsApplication> ();
+ node->AddApplication (app);
+ return app;
+}
+
+}} // namespace pgbr, ns3
« no previous file with comments | « src/pgbr/helper/multiple-flows-application-helper.h ('k') | src/pgbr/helper/net-device-load-sensor-helper.h » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b