Fast DDS  Version 3.6.1.0
Fast DDS
LocatorSelector.hpp
1 // Copyright 2019 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
19 #ifndef FASTDDS_RTPS_COMMON__LOCATORSELECTOR_HPP
20 #define FASTDDS_RTPS_COMMON__LOCATORSELECTOR_HPP
21 
22 #include <fastdds/rtps/common/LocatorSelectorEntry.hpp>
23 #include <fastdds/rtps/common/Guid.hpp>
24 #include <fastdds/rtps/common/Locator.hpp>
25 #include <fastdds/rtps/common/LocatorsIterator.hpp>
26 #include <fastdds/utils/collections/ResourceLimitedVector.hpp>
27 #include <fastdds/utils/IPLocator.hpp>
28 
29 #include <algorithm>
30 
31 namespace eprosima {
32 namespace fastdds {
33 namespace rtps {
34 
55 {
56 public:
57 
64  const ResourceLimitedContainerConfig& entries_allocation)
65  : entries_(entries_allocation)
66  , selections_(entries_allocation)
67  , last_state_(entries_allocation)
68  {
69  static_cast<void>(initial_allow_to_send_);
70  static_cast<void>(force_reset_);
71  }
72 
76  void clear()
77  {
78  entries_.clear();
79  selections_.clear();
80  last_state_.clear();
81  }
82 
88  bool add_entry(
89  LocatorSelectorEntry* entry)
90  {
91  return entries_.push_back(entry) != nullptr;
92  }
93 
99  const GUID_t& guid)
100  {
101  return entries_.remove_if(
102  [&guid](LocatorSelectorEntry* entry)
103  {
104  return entry->remote_guid == guid;
105  });
106  }
107 
113  void reset(
114  bool enable_all)
115  {
116  last_state_.clear();
117  for (LocatorSelectorEntry* entry : entries_)
118  {
119  last_state_.push_back(entry->enabled ? 1 : 0);
120  entry->enable(enable_all);
121  }
122  }
123 
129  void enable(
130  const GUID_t& guid)
131  {
132  for (LocatorSelectorEntry* entry : entries_)
133  {
134  if (entry->remote_guid == guid)
135  {
136  entry->enabled = true;
137  break;
138  }
139  }
140  }
141 
147  bool state_has_changed() const
148  {
149  if (entries_.size() != last_state_.size())
150  {
151  return true;
152  }
153 
154  for (size_t i = 0; i < entries_.size(); ++i)
155  {
156  if (last_state_.at(i) != (entries_.at(i)->enabled ? 1 : 0))
157  {
158  return true;
159  }
160  }
161 
162  return false;
163  }
164 
169  {
170  selections_.clear();
171  for (LocatorSelectorEntry* entry : entries_)
172  {
173  entry->reset();
174  }
175  }
176 
185  {
186  for (LocatorSelectorEntry* entry : entries_)
187  {
188  entry->transport_should_process = entry->enabled;
189  }
190 
191  return entries_;
192  }
193 
199  void select(
200  size_t index)
201  {
202  if (index < entries_.size() &&
203  std::find(selections_.begin(), selections_.end(), index) == selections_.end())
204  {
205  selections_.push_back(index);
206  }
207  }
208 
214  size_t selected_size() const
215  {
216  size_t result = 0;
217 
218  for (size_t index : selections_)
219  {
220  LocatorSelectorEntry* entry = entries_.at(index);
221  result += entry->state.multicast.size();
222  result += entry->state.unicast.size();
223  }
224 
225  return result;
226  }
227 
236  const Locator_t locator) const
237  {
238  if (IPLocator::isMulticast(locator))
239  {
240  for (size_t index : selections_)
241  {
242  LocatorSelectorEntry* entry = entries_.at(index);
243  for (size_t loc_index : entry->state.multicast)
244  {
245  if (entry->multicast.at(loc_index) == locator)
246  {
247  return true;
248  }
249  }
250  }
251  }
252  else
253  {
254  for (size_t index : selections_)
255  {
256  LocatorSelectorEntry* entry = entries_.at(index);
257  for (size_t loc_index : entry->state.unicast)
258  {
259  if (entry->unicast.at(loc_index) == locator)
260  {
261  return true;
262  }
263  }
264  }
265  }
266  return false;
267  }
268 
276  template<class UnaryPredicate>
277  void for_each(
278  UnaryPredicate action) const
279  {
280  for (size_t index : selections_)
281  {
282  LocatorSelectorEntry* entry = entries_.at(index);
283  for (size_t loc_index : entry->state.multicast)
284  {
285  action(entry->multicast.at(loc_index));
286  }
287  for (size_t loc_index : entry->state.unicast)
288  {
289  action(entry->unicast.at(loc_index));
290  }
291  }
292  }
293 
295  {
297  size_t state_index;
300  };
301 
302  class iterator :
303  public LocatorsIterator
304  {
305  // use of std::iterator to introduce the following aliases is deprecated
306  using iterator_category = std::input_iterator_tag;
307  using value_type = Locator_t;
309  using pointer = Locator_t*;
310  using reference = Locator_t&;
311 
312  const LocatorSelector& locator_selector_;
313  IteratorIndex current_;
314 
315  void go_to_next_entry()
316  {
317  // While entries selected
318  while (++current_.selections_index < locator_selector_.selections_.size())
319  {
320  LocatorSelectorEntry* entry =
321  locator_selector_.entries_.at(locator_selector_.selections_[current_.selections_index]);
322 
323  // No multicast locators in this entry
324  if (entry->state.multicast.size() == 0)
325  {
326  // But there's unicast
327  if (entry->state.unicast.size() > 0)
328  {
329  current_.locator = &entry->unicast[entry->state.unicast.at(0)];
330  return;
331  }
332  }
333  else // process multicast
334  {
335  current_.state_multicast_done = false;
336  current_.locator = &entry->multicast[entry->state.multicast.at(0)];
337  return;
338  }
339  }
340 
341  current_.locator = nullptr;
342  }
343 
344  public:
345 
346  enum class Position
347  {
348  Begin,
349  End
350  };
351 
352  explicit iterator(
353  const LocatorSelector& locator_selector,
354  Position index_pos)
355  : locator_selector_(locator_selector)
356  {
357  current_ = {(std::numeric_limits<size_t>::max)(), 0, true, nullptr};
358 
359  if (index_pos == Position::Begin)
360  {
361  go_to_next_entry();
362  }
363  }
364 
366  const iterator& other)
367  : locator_selector_(other.locator_selector_)
368  , current_(other.current_)
369  {
370  }
371 
373  {
374  // Shouldn't call ++ when index already at the end
375  assert(current_.selections_index < locator_selector_.selections_.size());
376 
377  LocatorSelectorEntry* entry =
378  locator_selector_.entries_.at(locator_selector_.selections_[current_.selections_index]);
379 
380  // Index at unicast locators
381  if (current_.state_multicast_done)
382  {
383  // No more unicast locators selected
384  if (++current_.state_index >= entry->state.unicast.size())
385  {
386  current_.state_index = 0;
387  go_to_next_entry();
388  }
389  else // current unicast locator
390  {
391  current_.locator = &entry->unicast[entry->state.unicast.at(current_.state_index)];
392  }
393  }
394  else // Index at multicast locators
395  {
396  // No more multicast locators selected
397  if (++current_.state_index >= entry->state.multicast.size())
398  {
399  // Reset index to process unicast
400  current_.state_multicast_done = true;
401  current_.state_index = 0;
402  // No unicast locators
403  if (current_.state_index >= entry->state.unicast.size())
404  {
405  go_to_next_entry();
406  }
407  else // current unicast locator
408  {
409  current_.locator = &entry->unicast[entry->state.unicast.at(current_.state_index)];
410  }
411  }
412  else // current multicast locator
413  {
414  current_.locator = &entry->multicast[entry->state.multicast.at(current_.state_index)];
415  }
416  }
417 
418  return *this;
419  }
420 
422  const LocatorsIterator& other) const
423  {
424  return *this == static_cast<const iterator&>(other);
425  }
426 
428  const LocatorsIterator& other) const
429  {
430  return !(*this == other);
431  }
432 
434  const iterator& other) const
435  {
436  return (current_.locator == other.current_.locator);
437  }
438 
440  const iterator& other) const
441  {
442  return !(*this == other);
443  }
444 
446  {
447  return current_.locator;
448  }
449 
451  {
452  return *current_.locator;
453  }
454 
455  };
456 
457  iterator begin() const
458  {
459  return iterator(*this, iterator::Position::Begin);
460  }
461 
462  iterator end() const
463  {
464  return iterator(*this, iterator::Position::End);
465  }
466 
467 private:
468 
472  ResourceLimitedVector<size_t> selections_;
474  ResourceLimitedVector<int> last_state_;
475 
477  bool initial_allow_to_send_ {true};
478 
480  bool force_reset_ {false};
481 };
482 
483 } // namespace rtps
484 } // namespace fastdds
485 } // namespace eprosima
486 
487 #endif // FASTDDS_RTPS_COMMON__LOCATORSELECTOR_HPP
Resource limited wrapper of std::vector.
Definition: ResourceLimitedVector.hpp:59
size_type size() const noexcept
Definition: ResourceLimitedVector.hpp:479
reference at(size_type pos)
Wrappers to other basic vector methods.
Definition: ResourceLimitedVector.hpp:370
iterator begin() noexcept
Definition: ResourceLimitedVector.hpp:414
pointer push_back(const value_type &val)
Add element at the end.
Definition: ResourceLimitedVector.hpp:174
void clear()
Definition: ResourceLimitedVector.hpp:494
iterator end() noexcept
Definition: ResourceLimitedVector.hpp:429
static FASTDDS_EXPORTED_API bool isMulticast(const Locator_t &locator)
Checks if the locator has a multicast IP address.
Class Locator_t, uniquely identifies a communication channel for a particular transport.
Definition: Locator.hpp:74
Definition: LocatorSelector.hpp:304
iterator(const iterator &other)
Definition: LocatorSelector.hpp:365
bool operator!=(const LocatorsIterator &other) const
Not equal to operator.
Definition: LocatorSelector.hpp:427
iterator(const LocatorSelector &locator_selector, Position index_pos)
Definition: LocatorSelector.hpp:352
bool operator==(const LocatorsIterator &other) const
Equal to operator.
Definition: LocatorSelector.hpp:421
reference operator*() const
Dereference operator.
Definition: LocatorSelector.hpp:450
Position
Definition: LocatorSelector.hpp:347
pointer operator->() const
Definition: LocatorSelector.hpp:445
iterator & operator++()
Increment operator.
Definition: LocatorSelector.hpp:372
A class used for the efficient selection of locators when sending data to multiple entities.
Definition: LocatorSelector.hpp:55
iterator begin() const
Definition: LocatorSelector.hpp:457
LocatorSelector(const ResourceLimitedContainerConfig &entries_allocation)
Construct a LocatorSelector.
Definition: LocatorSelector.hpp:63
void select(size_t index)
Marks an entry as selected.
Definition: LocatorSelector.hpp:199
size_t selected_size() const
Count the number of selected locators.
Definition: LocatorSelector.hpp:214
bool remove_entry(const GUID_t &guid)
Remove an entry from this selector.
Definition: LocatorSelector.hpp:98
iterator end() const
Definition: LocatorSelector.hpp:462
bool state_has_changed() const
Check if enabling state has changed.
Definition: LocatorSelector.hpp:147
bool add_entry(LocatorSelectorEntry *entry)
Add an entry to this selector.
Definition: LocatorSelector.hpp:88
void selection_start()
Reset the selection state of the selector.
Definition: LocatorSelector.hpp:168
void for_each(UnaryPredicate action) const
Performs an action on each selected locator.
Definition: LocatorSelector.hpp:277
void enable(const GUID_t &guid)
Enable an entry given its GUID.
Definition: LocatorSelector.hpp:129
void clear()
Clears all internal data.
Definition: LocatorSelector.hpp:76
void reset(bool enable_all)
Reset the enabling state of the selector.
Definition: LocatorSelector.hpp:113
bool is_selected(const Locator_t locator) const
Check if a locator is present in the selections of this object.
Definition: LocatorSelector.hpp:235
ResourceLimitedVector< LocatorSelectorEntry * > & transport_starts()
Called when the selection algorithm starts for a specific transport.
Definition: LocatorSelector.hpp:184
Specifies the configuration of a resource limited collection.
Definition: ResourceLimitedContainerConfig.hpp:36
Structure GUID_t, entity identifier, unique in DDS-RTPS Domain.
Definition: Guid.hpp:40
size_t selections_index
Definition: LocatorSelector.hpp:296
size_t state_index
Definition: LocatorSelector.hpp:297
bool state_multicast_done
Definition: LocatorSelector.hpp:298
Locator_t * locator
Definition: LocatorSelector.hpp:299
ResourceLimitedVector< size_t > unicast
Unicast locators selection state.
Definition: LocatorSelectorEntry.hpp:60
ResourceLimitedVector< size_t > multicast
Multicast locators selection state.
Definition: LocatorSelectorEntry.hpp:62
An entry for the LocatorSelector.
Definition: LocatorSelectorEntry.hpp:39
ResourceLimitedVector< Locator_t > unicast
List of unicast locators to send data to the remote entity.
Definition: LocatorSelectorEntry.hpp:137
ResourceLimitedVector< Locator_t > multicast
List of multicast locators to send data to the remote entity.
Definition: LocatorSelectorEntry.hpp:139
GUID_t remote_guid
GUID of the remote entity.
Definition: LocatorSelectorEntry.hpp:135
EntryState state
State of the entry.
Definition: LocatorSelectorEntry.hpp:141
Provides a Locator's iterator interface that can be used by different Locator's containers.
Definition: LocatorsIterator.hpp:33