pal_statistics_utils.h
Go to the documentation of this file.
1 
26 #ifndef PAL_STATISTICS_UTILS_H
27 #define PAL_STATISTICS_UTILS_H
28 
29 #include <boost/lockfree/queue.hpp>
30 #include <boost/bimap.hpp>
31 #include <boost/bimap/multiset_of.hpp>
32 #include <boost/bimap/set_of.hpp>
33 #include <boost/thread/lock_guard.hpp>
34 #include <boost/thread/mutex.hpp>
35 #include <boost/variant.hpp>
36 #include <atomic>
37 #include <vector>
38 #include <map>
39 #include <ros/ros.h>
40 #include <pal_statistics_msgs/Statistics.h>
41 #include <pal_statistics_msgs/StatisticsNames.h>
42 #include <pal_statistics_msgs/StatisticsValues.h>
44 namespace pal_statistics
45 {
46 typedef unsigned int IdType;
47 
53 template <typename T>
54 class LockFreeQueue : private boost::lockfree::queue<T>
55 {
56 public:
57  typedef boost::lockfree::queue<T> BaseType;
58 
59  LockFreeQueue() : BaseType(0), reserved_size(0)
60  {
61  }
62  void set_capacity(typename BaseType::size_type n)
63  {
64  long long missing_size = n - reserved_size;
65  if (missing_size > 0)
66  {
67  BaseType::reserve(missing_size);
68  reserved_size += missing_size;
69  }
70  }
71 
72  bool bounded_push(T const &t)
73  {
74  return BaseType::bounded_push(t);
75  }
76 
77  template <typename U>
78  bool pop(U &ret)
79  {
80  return BaseType::pop(ret);
81  }
82 
83 private:
84  std::atomic<size_t> reserved_size;
85 };
86 
87 
88 class StatisticsRegistry;
89 
95 {
96 public:
97  Registration(const std::string &name, IdType id,
98  const boost::weak_ptr<StatisticsRegistry> &obj);
99  Registration(Registration &&other) = default;
100  Registration &operator=(Registration &&) = default;
101 
102  ~Registration();
103 
104  std::string name_;
105  IdType id_;
106  boost::weak_ptr<StatisticsRegistry> obj_;
107 private:
108  // This object should not be copied, because we may unregister variables prematurely
109  Registration( const Registration& ) = delete; // non construction-copyable
110  Registration& operator=( const Registration& ) = delete; // non copyable
111 };
112 
118 {
119 public:
121  void add(Registration &&registration);
122  bool remove(const std::string &name);
123  bool remove(IdType id);
124  void removeAll();
125 
126  bool enable(const std::string &name);
127  bool enable(IdType id);
128  bool enableAll();
129 
130  bool disable(const std::string &name);
131  bool disable(IdType id);
132  bool disableAll();
133 
134 private:
135  // This object should not be copied, because Registration is not copiable
136  RegistrationsRAII( const RegistrationsRAII& ) = delete; // non construction-copyable
137  RegistrationsRAII& operator=( const RegistrationsRAII& ) = delete; // non copyable
138 
139  std::vector<Registration>::iterator find(const std::string &name);
140  std::vector<Registration>::iterator find(IdType id);
141 
142  boost::mutex mutex_;
143  std::vector<Registration> registrations_;
144 };
145 
146 
148 {
149 public:
151  {
152  // We just implement it because it's needed by the vector resize method, but
153  // we never use it to increase the size
154  throw std::runtime_error("VariableHolder default constructor should never be called");
155  }
156 
157  VariableHolder(const double *const pointer) : v_ptr_(pointer)
158  {
159  v_ptr_ = pointer;
160  }
161 
162  VariableHolder(const boost::function<double()> &function) : v_ptr_(nullptr), v_func_(function)
163  {
164  }
165 
166  VariableHolder(const VariableHolder &other) = delete;
167  void operator=(const VariableHolder &other) = delete;
168 
170  {
171  *this = std::move(other);
172  }
173 
174  void operator=(const VariableHolder &&other)
175  {
176  v_ptr_ = std::move(other.v_ptr_);
177  v_func_ = std::move(other.v_func_);
178  }
180  {
181  }
182 
183  inline double getValue() const
184  {
185  if (v_ptr_)
186  return *v_ptr_;
187  else
188  return v_func_();
189  }
190 
191 private:
192  const double *v_ptr_;
193  boost::function<double()> v_func_;
194 };
195 
196 
203 {
204 public:
205  RegistrationList(size_t internal_buffer_capacity = 100);
206  int registerVariable(const std::string &name, VariableHolder &&holder, bool enabled = true);
207 
208 
209  void unregisterVariable(const IdType &id);
210 
211  void setEnabled(const IdType &id, bool enabled);
212 
213 
214  void unregisterVariable(const std::string &name);
215 
216  void doUpdate();
217 
221  void fillMsg(pal_statistics_msgs::StatisticsNames &names, pal_statistics_msgs::StatisticsValues &value);
222 
231  bool smartFillMsg(pal_statistics_msgs::StatisticsNames &names, pal_statistics_msgs::StatisticsValues &values);
235  size_t size() const;
236 
237  bool hasPendingData() const;
238 
239 
240  // How many messages where lost because the buffer was full
242 
243 private:
244  void deleteElement(size_t index);
245  void registrationsChanged();
246 
247  int last_id_;
248  unsigned int names_version_;
249 
250  // Bidirectional map between names and ids.
251  // Can have multiple variables with the same name but different id, but not multiple id
252  typedef boost::bimap<boost::bimaps::multiset_of<std::string>, boost::bimaps::set_of<IdType>> NameIdBiMap;
253 
254  NameIdBiMap name_id_;
255 
256  size_t buffer_size_;
257  std::vector<std::string> names_;
258  std::vector<IdType> ids_;
259  std::vector<VariableHolder> references_;
260  std::vector<bool> enabled_;
261 
262  struct NameValues
263  {
264  NameValues(size_t capacity)
265  : names(capacity, IdType(0)), values(capacity, 0.)
266  {}
267 
268  std::vector<IdType> names;
269  std::vector<double> values;
270  };
271 
272  typedef std::pair<NameValues, ros::Time> LastValuesStamped;
275 
277 };
278 }
279 
280 #endif // PAL_STATISTICS_UTILS_H
std::vector< VariableHolder > references_
The RegistrationList class.
VariableHolder(const double *const pointer)
VariableHolder(const VariableHolder &&other)
The StatisticsRegistry class reads the value of registered variables and publishes them on the specif...
boost::bimap< boost::bimaps::multiset_of< std::string >, boost::bimaps::set_of< IdType > > NameIdBiMap
boost::function< double()> v_func_
boost::lockfree::queue< T > BaseType
void set_capacity(typename BaseType::size_type n)
std::vector< std::string > names_
VariableHolder(const boost::function< double()> &function)
The Registration class is a handle to a registered variable, when out of scope unregisters the variab...
void operator=(const VariableHolder &&other)
std::vector< Registration > registrations_
std::atomic< size_t > reserved_size
std::pair< NameValues, ros::Time > LastValuesStamped
The RegistrationsRAII class holds handles to registered variables and when it is destroyed, unregisters them automatically.
boost::weak_ptr< StatisticsRegistry > obj_
Simple wrapper around boost lockfree queue to keep track of the reserved memory Boost&#39;s implementatio...
StaticCircularBuffer< LastValuesStamped > last_values_buffer_


pal_statistics
Author(s):
autogenerated on Mon Feb 28 2022 23:04:05