All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
TopicStorage.hh
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Open Source Robotics Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16 */
17 
18 #ifndef IGN_TRANSPORT_TOPICSTORAGE_HH_
19 #define IGN_TRANSPORT_TOPICSTORAGE_HH_
20 
21 #include <algorithm>
22 #include <map>
23 #include <string>
24 #include <vector>
25 
29 
30 namespace ignition
31 {
32  namespace transport
33  {
37  template<typename T> class IGNITION_TRANSPORT_VISIBLE TopicStorage
38  {
40  public: TopicStorage() = default;
41 
43  public: virtual ~TopicStorage() = default;
44 
49  public: bool AddPublisher(const T &_publisher)
50  {
51  // The topic does not exist.
52  if (this->data.find(_publisher.Topic()) == this->data.end())
53  {
54  // VS2013 is buggy with initializer list here {}
55  this->data[_publisher.Topic()] =
56  std::map<std::string, std::vector<T>>();
57  }
58 
59  // Check if the process uuid exists.
60  auto &m = this->data[_publisher.Topic()];
61  if (m.find(_publisher.PUuid()) != m.end())
62  {
63  // Check that the Publisher does not exist.
64  auto &v = m[_publisher.PUuid()];
65  auto found = std::find_if(v.begin(), v.end(),
66  [&](const T &_pub)
67  {
68  return _pub.Addr() == _publisher.Addr() &&
69  _pub.NUuid() == _publisher.NUuid();
70  });
71 
72  // The publisher was already existing, just exit.
73  if (found != v.end())
74  return false;
75  }
76 
77  // Add a new Publisher entry.
78  m[_publisher.PUuid()].push_back(T(_publisher));
79  return true;
80  }
81 
85  public: bool HasTopic(const std::string &_topic) const
86  {
87  return this->data.find(_topic) != this->data.end();
88  }
89 
96  public: bool HasTopic(const std::string &_topic,
97  const std::string &_type) const
98  {
99  if (!this->HasTopic(_topic))
100  return false;
101 
102  // m is {pUUID=>std::vector<Publisher>}.
103  auto &m = this->data.at(_topic);
104 
105  for (auto const &procs : m)
106  {
107  // Vector of publishers for a given topic and pUuid.
108  auto &v = procs.second;
109  auto found = std::find_if(v.begin(), v.end(),
110  [&](const T &_pub)
111  {
112  return _pub.MsgTypeName() == _type ||
113  _pub.MsgTypeName() == kGenericMessageType;
114  });
115 
116  // Type found!
117  if (found != v.end())
118  return true;
119  }
120 
121  return false;
122  }
123 
130  public: bool HasAnyPublishers(const std::string &_topic,
131  const std::string &_pUuid) const
132  {
133  if (!this->HasTopic(_topic))
134  return false;
135 
136  return this->data.at(_topic).find(_pUuid) !=
137  this->data.at(_topic).end();
138  }
139 
143  public: bool HasPublisher(const std::string &_addr) const
144  {
145  for (auto const &topic : this->data)
146  {
147  for (auto const &proc : topic.second)
148  {
149  for (auto const &pub : proc.second)
150  {
151  if (pub.Addr() == _addr)
152  return true;
153  }
154  }
155  }
156  return false;
157  }
158 
165  public: bool Publisher(const std::string &_topic,
166  const std::string &_pUuid,
167  const std::string &_nUuid,
168  T &_publisher) const
169  {
170  // Topic not found.
171  if (this->data.find(_topic) == this->data.end())
172  return false;
173 
174  // m is {pUUID=>Publisher}.
175  auto &m = this->data.at(_topic);
176 
177  // pUuid not found.
178  if (m.find(_pUuid) == m.end())
179  return false;
180 
181  // Vector of 0MQ known addresses for a given topic and pUuid.
182  auto &v = m.at(_pUuid);
183  auto found = std::find_if(v.begin(), v.end(),
184  [&](const T &_pub)
185  {
186  return _pub.NUuid() == _nUuid;
187  });
188  // Address found!
189  if (found != v.end())
190  {
191  _publisher = *found;
192  return true;
193  }
194 
195  // nUuid not found.
196  return false;
197  }
198 
203  public: bool Publishers(const std::string &_topic,
204  std::map<std::string, std::vector<T>> &_info) const
205  {
206  if (!this->HasTopic(_topic))
207  return false;
208 
209  _info = this->data.at(_topic);
210  return true;
211  }
212 
218  public: bool DelPublisherByNode(const std::string &_topic,
219  const std::string &_pUuid,
220  const std::string &_nUuid)
221  {
222  size_t counter = 0;
223 
224  // Iterate over all the topics.
225  if (this->data.find(_topic) != this->data.end())
226  {
227  // m is {pUUID=>Publisher}.
228  auto &m = this->data[_topic];
229 
230  // The pUuid exists.
231  if (m.find(_pUuid) != m.end())
232  {
233  // Vector of 0MQ known addresses for a given topic and pUuid.
234  auto &v = m[_pUuid];
235  auto priorSize = v.size();
236  v.erase(std::remove_if(v.begin(), v.end(),
237  [&](const T &_pub)
238  {
239  return _pub.NUuid() == _nUuid;
240  }),
241  v.end());
242  counter = priorSize - v.size();
243 
244  if (v.empty())
245  m.erase(_pUuid);
246 
247  if (m.empty())
248  this->data.erase(_topic);
249  }
250  }
251 
252  return counter > 0;
253  }
254 
258  public: bool DelPublishersByProc(const std::string &_pUuid)
259  {
260  size_t counter = 0;
261 
262  // Iterate over all the topics.
263  for (auto it = this->data.begin(); it != this->data.end();)
264  {
265  // m is {pUUID=>Publisher}.
266  auto &m = it->second;
267  counter += m.erase(_pUuid);
268  if (m.empty())
269  this->data.erase(it++);
270  else
271  ++it;
272  }
273 
274  return counter > 0;
275  }
276 
282  public: void PublishersByProc(const std::string &_pUuid,
283  std::map<std::string, std::vector<T>> &_pubs) const
284  {
285  _pubs.clear();
286 
287  // Iterate over all the topics.
288  for (auto const &topic : this->data)
289  {
290  // m is {pUUID=>Publisher}.
291  auto &m = topic.second;
292  if (m.find(_pUuid) != m.end())
293  {
294  auto &v = m.at(_pUuid);
295  for (auto const &pub : v)
296  {
297  _pubs[pub.NUuid()].push_back(T(pub));
298  }
299  }
300  }
301  }
302 
308  public: void PublishersByNode(const std::string &_pUuid,
309  const std::string &_nUuid,
310  std::vector<T> &_pubs) const
311  {
312  _pubs.clear();
313 
314  // Iterate over all the topics.
315  for (auto const &topic : this->data)
316  {
317  // m is {pUUID=>Publisher}.
318  auto const &m = topic.second;
319  if (m.find(_pUuid) != m.end())
320  {
321  auto const &v = m.at(_pUuid);
322  for (auto const &pub : v)
323  {
324  if (pub.NUuid() == _nUuid)
325  {
326  _pubs.push_back(T(pub));
327  }
328  }
329  }
330  }
331  }
332 
335  public: void TopicList(std::vector<std::string> &_topics) const
336  {
337  for (auto const &topic : this->data)
338  _topics.push_back(topic.first);
339  }
340 
342  public: void Print() const
343  {
344  std::cout << "---" << std::endl;
345  for (auto const &topic : this->data)
346  {
347  std::cout << "[" << topic.first << "]" << std::endl;
348  auto &m = topic.second;
349  for (auto const &proc : m)
350  {
351  std::cout << "\tProc. UUID: " << proc.first << std::endl;
352  auto &v = proc.second;
353  for (auto const &publisher : v)
354  {
355  std::cout << publisher;
356  }
357  }
358  }
359  }
360 
363  private: std::map<std::string,
364  std::map<std::string, std::vector<T>>> data;
365  };
366  }
367 }
368 
369 #endif
bool AddPublisher(const T &_publisher)
Add a new address associated to a given topic and node UUID.
Definition: TopicStorage.hh:49
bool HasTopic(const std::string &_topic) const
Return if there is any publisher stored for the given topic.
Definition: TopicStorage.hh:85
void Print() const
Print all the information for debugging purposes.
Definition: TopicStorage.hh:342
bool HasAnyPublishers(const std::string &_topic, const std::string &_pUuid) const
Return if there is any publisher stored for the given topic and process UUID.
Definition: TopicStorage.hh:130
bool Publisher(const std::string &_topic, const std::string &_pUuid, const std::string &_nUuid, T &_publisher) const
Get the address information for a given topic and node UUID.
Definition: TopicStorage.hh:165
bool HasTopic(const std::string &_topic, const std::string &_type) const
Return if there is any publisher stored for the given topic and type.
Definition: TopicStorage.hh:96
void PublishersByNode(const std::string &_pUuid, const std::string &_nUuid, std::vector< T > &_pubs) const
Given a process UUID and the node UUID, the function returns the list of publishers contained in the ...
Definition: TopicStorage.hh:308
bool DelPublishersByProc(const std::string &_pUuid)
Remove all the publishers associated to a given process.
Definition: TopicStorage.hh:258
void PublishersByProc(const std::string &_pUuid, std::map< std::string, std::vector< T >> &_pubs) const
Given a process UUID, the function returns the list of publishers contained in this process UUID with...
Definition: TopicStorage.hh:282
void TopicList(std::vector< std::string > &_topics) const
Get the list of topics currently stored.
Definition: TopicStorage.hh:335
bool HasPublisher(const std::string &_addr) const
Return if the requested publisher's address is stored.
Definition: TopicStorage.hh:143
#define IGNITION_TRANSPORT_VISIBLE
Use to represent "symbol visible" if supported.
Definition: Helpers.hh:57
bool DelPublisherByNode(const std::string &_topic, const std::string &_pUuid, const std::string &_nUuid)
Remove a publisher associated to a given topic and UUID pair.
Definition: TopicStorage.hh:218
const std::string kGenericMessageType
The string type used for generic messages.
Definition: TransportTypes.hh:132
Store address information about topics and provide convenient methods for adding new topics...
Definition: TopicStorage.hh:37
bool Publishers(const std::string &_topic, std::map< std::string, std::vector< T >> &_info) const
Get the map of publishers stored for a given topic.
Definition: TopicStorage.hh:203