PageRenderTime 45ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/src/topology-read/model/rocketfuel-topology-reader.cc

https://gitlab.com/msepahkar/location_in_wireless_ndn
C++ | 446 lines | 333 code | 64 blank | 49 comment | 68 complexity | 24f6b81b1b4b309a27a792f7d22c27f5 MD5 | raw file
  1. /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
  2. /*
  3. * Copyright (c) 2010 Hajime Tazaki
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation;
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. *
  18. * Author: Hajime Tazaki (tazaki@sfc.wide.ad.jp)
  19. */
  20. #include <fstream>
  21. #include <cstdlib>
  22. #include <iostream>
  23. #include <sstream>
  24. #include <regex.h>
  25. #include "ns3/log.h"
  26. #include "ns3/unused.h"
  27. #include "rocketfuel-topology-reader.h"
  28. NS_LOG_COMPONENT_DEFINE ("RocketfuelTopologyReader");
  29. namespace ns3 {
  30. // NS_OBJECT_ENSURE_REGISTERED (RocketfuelTopologyReader);
  31. // TypeId RocketfuelTopologyReader::GetTypeId (void)
  32. // {
  33. // static TypeId tid = TypeId ("ns3::RocketfuelTopologyReader")
  34. // .SetParent<Object> ()
  35. // ;
  36. // return tid;
  37. // }
  38. RocketfuelTopologyReader::RocketfuelTopologyReader ()
  39. {
  40. m_linksNumber = 0;
  41. m_nodesNumber = 0;
  42. NS_LOG_FUNCTION (this);
  43. }
  44. RocketfuelTopologyReader::~RocketfuelTopologyReader ()
  45. {
  46. NS_LOG_FUNCTION (this);
  47. }
  48. /* uid @loc [+] [bb] (num_neigh) [&ext] -> <nuid-1> <nuid-2> ... {-euid} ... =name[!] rn */
  49. #define REGMATCH_MAX 16
  50. #define START "^"
  51. #define END "$"
  52. #define SPACE "[ \t]+"
  53. #define MAYSPACE "[ \t]*"
  54. #define ROCKETFUEL_MAPS_LINE \
  55. START "(-*[0-9]+)" SPACE "(@[?A-Za-z0-9,+]+)" SPACE \
  56. "(\\+)*" MAYSPACE "(bb)*" MAYSPACE \
  57. "\\(([0-9]+)\\)" SPACE "(&[0-9]+)*" MAYSPACE \
  58. "->" MAYSPACE "(<[0-9 \t<>]+>)*" MAYSPACE \
  59. "(\\{-[0-9\\{\\} \t-]+\\})*" SPACE \
  60. "=([A-Za-z0-9.!-]+)" SPACE "r([0-9])" \
  61. MAYSPACE END
  62. #define ROCKETFUEL_WEIGHTS_LINE \
  63. START "([^ \t]+)" SPACE "([^ \t]+)" SPACE "([0-9.]+)" MAYSPACE END
  64. /**
  65. * \brief Print node info
  66. * \param uid node ID
  67. * \param loc node location
  68. * \param dns is a DNS node ?
  69. * \param bb is a BB node ?
  70. * \param neighListSize size of neighbor list
  71. * \param name node name
  72. * \param radius node radius
  73. */
  74. static inline void
  75. PrintNodeInfo (std::string & uid, std::string & loc, bool dns, bool bb,
  76. std::vector <std::string>::size_type neighListSize,
  77. std::string & name, int radius)
  78. {
  79. /* uid @loc [+] [bb] (num_neigh) [&ext] -> <nuid-1> <nuid-2> ... {-euid} ... =name[!] rn */
  80. NS_LOG_INFO ("Load Node[" << uid << "]: location: " << loc << " dns: " << dns
  81. << " bb: " << bb << " neighbors: " << neighListSize
  82. << "(" << "%d" << ") externals: \"%s\"(%d) "
  83. << "name: " << name << " radius: " << radius);
  84. }
  85. NodeContainer
  86. RocketfuelTopologyReader::GenerateFromMapsFile (int argc, char *argv[])
  87. {
  88. std::string uid;
  89. std::string loc;
  90. std::string ptr;
  91. std::string name;
  92. std::string nuid;
  93. bool dns = false;
  94. bool bb = false;
  95. int num_neigh_s = 0;
  96. unsigned int num_neigh = 0;
  97. int radius = 0;
  98. std::vector <std::string> neigh_list;
  99. NodeContainer nodes;
  100. uid = argv[0];
  101. loc = argv[1];
  102. if (argv[2])
  103. {
  104. dns = true;
  105. }
  106. if (argv[3])
  107. {
  108. bb = true;
  109. }
  110. num_neigh_s = ::atoi (argv[4]);
  111. if (num_neigh_s < 0)
  112. {
  113. num_neigh = 0;
  114. NS_LOG_WARN ("Negative number of neighbors given");
  115. }
  116. else
  117. {
  118. num_neigh = num_neigh_s;
  119. }
  120. /* neighbors */
  121. if (argv[6])
  122. {
  123. char *nbr;
  124. char *stringp = argv[6];
  125. while ((nbr = strsep (&stringp, " \t")) != NULL)
  126. {
  127. nbr[strlen (nbr) - 1] = '\0';
  128. neigh_list.push_back (nbr + 1);
  129. }
  130. }
  131. if (num_neigh != neigh_list.size ())
  132. {
  133. NS_LOG_WARN ("Given number of neighbors = " << num_neigh << " != size of neighbors list = " << neigh_list.size ());
  134. }
  135. /* externs */
  136. if (argv[7])
  137. {
  138. // euid = argv[7];
  139. }
  140. /* name */
  141. if (argv[8])
  142. {
  143. name = argv[8];
  144. }
  145. radius = ::atoi (&argv[9][1]);
  146. if (radius > 0)
  147. {
  148. return nodes;
  149. }
  150. PrintNodeInfo (uid, loc, dns, bb, neigh_list.size (), name, radius);
  151. // Create node and link
  152. if (!uid.empty ())
  153. {
  154. if (m_nodeMap[uid] == 0)
  155. {
  156. Ptr<Node> tmpNode = CreateObject<Node> ();
  157. m_nodeMap[uid] = tmpNode;
  158. nodes.Add (tmpNode);
  159. m_nodesNumber++;
  160. }
  161. for (uint32_t i = 0; i < neigh_list.size (); ++i)
  162. {
  163. nuid = neigh_list[i];
  164. if (nuid.empty ())
  165. {
  166. return nodes;
  167. }
  168. if (m_nodeMap[nuid] == 0)
  169. {
  170. Ptr<Node> tmpNode = CreateObject<Node> ();
  171. m_nodeMap[nuid] = tmpNode;
  172. nodes.Add (tmpNode);
  173. m_nodesNumber++;
  174. }
  175. NS_LOG_INFO (m_linksNumber << ":" << m_nodesNumber << " From: " << uid << " to: " << nuid);
  176. Link link (m_nodeMap[uid], uid, m_nodeMap[nuid], nuid);
  177. AddLink (link);
  178. m_linksNumber++;
  179. }
  180. }
  181. NS_LOG_INFO ("Rocketfuel topology created with " << m_nodesNumber << " nodes and " << m_linksNumber << " links");
  182. return nodes;
  183. }
  184. NodeContainer
  185. RocketfuelTopologyReader::GenerateFromWeightsFile (int argc, char *argv[])
  186. {
  187. /* uid @loc [+] [bb] (num_neigh) [&ext] -> <nuid-1> <nuid-2> ... {-euid} ... =name[!] rn */
  188. std::string sname;
  189. std::string tname;
  190. char *endptr;
  191. NodeContainer nodes;
  192. sname = argv[0];
  193. tname = argv[1];
  194. double v = strtod (argv[2], &endptr); // weight
  195. NS_UNUSED (v); // suppress "set but not used" compiler warning in optimized builds
  196. if (*endptr != '\0')
  197. {
  198. NS_LOG_WARN ("invalid weight: " << argv[2]);
  199. return nodes;
  200. }
  201. // Create node and link
  202. if (!sname.empty () && !tname.empty ())
  203. {
  204. if (m_nodeMap[sname] == 0)
  205. {
  206. Ptr<Node> tmpNode = CreateObject<Node> ();
  207. m_nodeMap[sname] = tmpNode;
  208. nodes.Add (tmpNode);
  209. m_nodesNumber++;
  210. }
  211. if (m_nodeMap[tname] == 0)
  212. {
  213. Ptr<Node> tmpNode = CreateObject<Node> ();
  214. m_nodeMap[tname] = tmpNode;
  215. nodes.Add (tmpNode);
  216. m_nodesNumber++;
  217. }
  218. NS_LOG_INFO (m_linksNumber << ":" << m_nodesNumber << " From: " << sname << " to: " << tname);
  219. TopologyReader::ConstLinksIterator iter;
  220. bool found = false;
  221. for (iter = LinksBegin (); iter != LinksEnd (); iter++)
  222. {
  223. if ((iter->GetFromNode () == m_nodeMap[tname])
  224. && (iter->GetToNode () == m_nodeMap[sname]))
  225. {
  226. found = true;
  227. break;
  228. }
  229. }
  230. if (!found)
  231. {
  232. Link link (m_nodeMap[sname], sname, m_nodeMap[tname], tname);
  233. AddLink (link);
  234. m_linksNumber++;
  235. }
  236. }
  237. NS_LOG_INFO ("Rocketfuel topology created with " << m_nodesNumber << " nodes and " << m_linksNumber << " links");
  238. return nodes;
  239. }
  240. enum RocketfuelTopologyReader::RF_FileType
  241. RocketfuelTopologyReader::GetFileType (const char *line)
  242. {
  243. int ret;
  244. regmatch_t regmatch[REGMATCH_MAX];
  245. regex_t regex;
  246. char errbuf[512];
  247. // Check whether MAPS file or not
  248. ret = regcomp (&regex, ROCKETFUEL_MAPS_LINE, REG_EXTENDED | REG_NEWLINE);
  249. if (ret != 0)
  250. {
  251. regerror (ret, &regex, errbuf, sizeof (errbuf));
  252. return RF_UNKNOWN;
  253. }
  254. ret = regexec (&regex, line, REGMATCH_MAX, regmatch, 0);
  255. if (ret != REG_NOMATCH)
  256. {
  257. regfree (&regex);
  258. return RF_MAPS;
  259. }
  260. regfree (&regex);
  261. // Check whether Weights file or not
  262. ret = regcomp (&regex, ROCKETFUEL_WEIGHTS_LINE, REG_EXTENDED | REG_NEWLINE);
  263. if (ret != 0)
  264. {
  265. regerror (ret, &regex, errbuf, sizeof (errbuf));
  266. return RF_UNKNOWN;
  267. }
  268. ret = regexec (&regex, line, REGMATCH_MAX, regmatch, 0);
  269. if (ret != REG_NOMATCH)
  270. {
  271. regfree (&regex);
  272. return RF_WEIGHTS;
  273. }
  274. regfree (&regex);
  275. return RF_UNKNOWN;
  276. }
  277. NodeContainer
  278. RocketfuelTopologyReader::Read (void)
  279. {
  280. std::ifstream topgen;
  281. topgen.open (GetFileName ().c_str ());
  282. NodeContainer nodes;
  283. std::istringstream lineBuffer;
  284. std::string line;
  285. int lineNumber = 0;
  286. enum RF_FileType ftype = RF_UNKNOWN;
  287. char errbuf[512];
  288. if (!topgen.is_open ())
  289. {
  290. NS_LOG_WARN ("Couldn't open the file " << GetFileName ());
  291. return nodes;
  292. }
  293. while (!topgen.eof ())
  294. {
  295. int ret;
  296. int argc;
  297. char *argv[REGMATCH_MAX];
  298. char *buf;
  299. lineNumber++;
  300. line.clear ();
  301. lineBuffer.clear ();
  302. getline (topgen, line);
  303. buf = (char *)line.c_str ();
  304. if (lineNumber == 1)
  305. {
  306. ftype = GetFileType (buf);
  307. if (ftype == RF_UNKNOWN)
  308. {
  309. NS_LOG_INFO ("Unknown File Format (" << GetFileName () << ")");
  310. break;
  311. }
  312. }
  313. regmatch_t regmatch[REGMATCH_MAX];
  314. regex_t regex;
  315. if (ftype == RF_MAPS)
  316. {
  317. ret = regcomp (&regex, ROCKETFUEL_MAPS_LINE, REG_EXTENDED | REG_NEWLINE);
  318. if (ret != 0)
  319. {
  320. regerror (ret, &regex, errbuf, sizeof (errbuf));
  321. regfree (&regex);
  322. break;
  323. }
  324. ret = regexec (&regex, buf, REGMATCH_MAX, regmatch, 0);
  325. if (ret == REG_NOMATCH)
  326. {
  327. NS_LOG_WARN ("match failed (maps file): %s" << buf);
  328. regfree (&regex);
  329. break;
  330. }
  331. }
  332. else if (ftype == RF_WEIGHTS)
  333. {
  334. ret = regcomp (&regex, ROCKETFUEL_WEIGHTS_LINE, REG_EXTENDED | REG_NEWLINE);
  335. if (ret != 0)
  336. {
  337. regerror (ret, &regex, errbuf, sizeof (errbuf));
  338. regfree (&regex);
  339. break;
  340. }
  341. ret = regexec (&regex, buf, REGMATCH_MAX, regmatch, 0);
  342. if (ret == REG_NOMATCH)
  343. {
  344. NS_LOG_WARN ("match failed (weights file): %s" << buf);
  345. regfree (&regex);
  346. break;
  347. }
  348. }
  349. line = buf;
  350. argc = 0;
  351. /* regmatch[0] is the entire strings that matched */
  352. for (int i = 1; i < REGMATCH_MAX; i++)
  353. {
  354. if (regmatch[i].rm_so == -1)
  355. {
  356. argv[i - 1] = NULL;
  357. }
  358. else
  359. {
  360. line[regmatch[i].rm_eo] = '\0';
  361. argv[i - 1] = &line[regmatch[i].rm_so];
  362. argc = i;
  363. }
  364. }
  365. if (ftype == RF_MAPS)
  366. {
  367. nodes.Add (GenerateFromMapsFile (argc, argv));
  368. }
  369. else if (ftype == RF_WEIGHTS)
  370. {
  371. nodes.Add (GenerateFromWeightsFile (argc, argv));
  372. }
  373. else
  374. {
  375. NS_LOG_WARN ("Unsupported file format (only Maps/Weights are supported)");
  376. }
  377. regfree (&regex);
  378. }
  379. topgen.close ();
  380. return nodes;
  381. }
  382. } /* namespace ns3 */