lsa-segment-storage.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
22 #include "lsa-segment-storage.hpp"
23 #include "logger.hpp"
24 #include "lsa.hpp"
25 #include "utility/name-helper.hpp"
26 
27 namespace nlsr {
28 
29 INIT_LOGGER(LsaSegmentStorage);
30 
31 LsaSegmentStorage::LsaSegmentStorage(ndn::Scheduler& scheduler,
32  const ndn::time::seconds lsaDeletionTimepoint)
33  : m_scheduler(scheduler)
34  , m_lsaDeletionTimepoint(lsaDeletionTimepoint)
35 {
36 }
37 
38 void
39 LsaSegmentStorage::connectToFetcher(ndn::util::SegmentFetcher& fetcher)
40 {
41  fetcher.afterSegmentValidated.connect(std::bind(&LsaSegmentStorage::afterFetcherSignalEmitted,
42  this, _1));
43 }
44 
45 const ndn::Data*
46 LsaSegmentStorage::getLsaSegment(const ndn::Interest& interest)
47 {
48  ndn::Name lsaSegmentsKey = interest.getName();
49 
50  // If this is the first interest then it does not contain the segment number,
51  // so need to append zero segment component at the end to match with the data
52  if (lsaSegmentsKey.size() > 0) {
53  if (!lsaSegmentsKey.get(-1).isSegment()) {
54  lsaSegmentsKey.appendSegment(0);
55  }
56 
57  auto it = m_lsaSegments.find(lsaSegmentsKey);
58  if (it == m_lsaSegments.end()) {
59  NLSR_LOG_TRACE("Data for interest: " << interest.getName() << " cannot be found in the lsa storage");
60 
61  return nullptr;
62  }
63  else {
64  NLSR_LOG_TRACE("Data for interest: " << interest.getName() << " is in the storage.");
65  return &(it->second);
66  }
67  }
68  else {
69  NLSR_LOG_ERROR("Received interest has empty name.");
70  return nullptr;
71  }
72 }
73 
74 void
75 LsaSegmentStorage::afterFetcherSignalEmitted(const ndn::Data& lsaSegment)
76 {
77  NLSR_LOG_TRACE("Received a LSA segment: " << lsaSegment.getName());
78 
79  // lsaSegmentName is /<router-prefix>/<LS type>/<sequence no.>/<version no.>/<segment no.>
80  auto lsaSegmentName = lsaSegment.getName();
81 
82  if (lsaSegmentName.size() > 0) {
83  // lsaSegmentsKey is /<router-prefix>/<LS type>/<sequence no.>/<segment no.>
84  ndn::Name lsaSegmentsKey(lsaSegmentName.getPrefix(lsaSegmentName.size() - 2));
85  lsaSegmentsKey.append(lsaSegmentName.get(-1));
86 
87  // No need to store same LSA multiple time
88  if (m_lsaSegments.find(lsaSegmentsKey) == m_lsaSegments.end()) {
89  NLSR_LOG_TRACE("Received LSA segment is new. Storing it in the storage.\n"
90  << " LSA data name: " << lsaSegmentName);
91 
92  // Delete the same LSA with lower sequence number
93  deleteOldLsas(lsaSegmentName);
94 
95  m_lsaSegments[lsaSegmentsKey] = lsaSegment;
96  }
97  else {
98  NLSR_LOG_TRACE("The received segment is already in the storage.");
99  }
100 
101  // schedule the segment deletion
102  scheduleLsaSegmentDeletion(lsaSegmentsKey);
103  }
104  else {
105  NLSR_LOG_ERROR("The received LSA segment has empty name.");
106  }
107 }
108 
109 void
110 LsaSegmentStorage::deleteOldLsas(const ndn::Name& newLsaName)
111 {
112  auto newLsaKey = newLsaName.getPrefix(newLsaName.size() - 3);
113  auto newSeqNo = newLsaName.get(-3).toNumber();
114 
115  std::vector<decltype(m_lsaSegments)::key_type> lsaToDelete;
116 
117  for (auto& segment : m_lsaSegments) {
118  ndn::Name segmentKey = segment.first;
119  auto oldSeqNo = segmentKey.get(-2).toNumber();
120  auto existingLsaKey = segmentKey.getPrefix(segmentKey.size() - 2);
121 
122  if (newLsaKey == existingLsaKey) {
123  if (newSeqNo > oldSeqNo) { // in the key the second last component is the sequence number
124  NLSR_LOG_TRACE("Outdated LSA: " << segmentKey << " with seq no: " <<
125  oldSeqNo << " is deleted.");
126  lsaToDelete.push_back(segmentKey);
127  }
128  }
129  }
130 
131  for (auto& segmentKey : lsaToDelete) {
132  m_lsaSegments.erase(segmentKey);
133  }
134 }
135 
136 void
137 LsaSegmentStorage::scheduleLsaSegmentDeletion(const ndn::Name& lsaSegmentsKey)
138 {
139  m_scheduler.scheduleEvent(m_lsaDeletionTimepoint,
140  [&, this] {
141  m_lsaSegments.erase(lsaSegmentsKey);
142  });
143 }
144 
145 } // namespace nlsr
Copyright (c) 2014-2018, The University of Memphis, Regents of the University of California.
#define INIT_LOGGER(name)
Definition: logger.hpp:35
void connectToFetcher(ndn::util::SegmentFetcher &fetcher)
Get connected to the signal emitted by SegmentFetcher.
LsaSegmentStorage(ndn::Scheduler &scheduler, const ndn::time::seconds lsaDeletionTimepoint)
const ndn::Data * getLsaSegment(const ndn::Interest &interest)
Returns an LSA segment for an interest from LsaSegmentStorage.
#define NLSR_LOG_ERROR(x)
Definition: logger.hpp:41
Copyright (c) 2014-2018, The University of Memphis, Regents of the University of California, Arizona Board of Regents.
#define NLSR_LOG_TRACE(x)
Definition: logger.hpp:37