19 #ifndef LOCALIZATION_COMMON_TIMESTAMPED_SET_H_
20 #define LOCALIZATION_COMMON_TIMESTAMPED_SET_H_
25 #include <boost/optional.hpp>
26 #include <boost/serialization/serialization.hpp>
27 #include <boost/serialization/unordered_map.hpp>
51 explicit TimestampedSet(
const boost::optional<int> max_size = boost::none);
55 TimestampedSet(
const std::vector<Time>& timestamps,
const std::vector<T>& values,
56 const boost::optional<int> max_size = boost::none);
60 bool Add(
const Time timestamp,
const T& value);
68 boost::optional<TimestampedValue<T>>
Get(
const Time timestamp)
const;
81 boost::optional<TimestampedValue<T>>
Oldest()
const;
89 boost::optional<TimestampedValue<T>>
Latest()
const;
101 std::pair<boost::optional<TimestampedValue<T>>, boost::optional<TimestampedValue<T>>>
LowerAndUpperBound(
102 const Time timestamp)
const;
106 boost::optional<TimestampedValue<T>>
Closest(
const Time timestamp)
const;
124 std::vector<TimestampedValue<T>>
LatestValues(
const Time oldest_allowed_timestamp)
const;
128 std::vector<TimestampedValue<T>>
OldValues(
const Time oldest_allowed_timestamp)
const;
132 template <
typename TimestampSetType>
133 std::vector<TimestampedValue<T>>
DownsampledValues(
const TimestampSetType& allowed_timestamps)
const;
148 const std::map<Time, T>&
set()
const;
151 std::map<Time, T>&
set();
154 typename std::map<Time, T>::const_iterator
cend()
const;
159 std::pair<typename std::map<Time, T>::const_iterator,
typename std::map<Time, T>::const_iterator>
InRangeValues(
160 const Time oldest_allowed_timestamp,
const Time latest_allowed_timestamp);
163 friend class boost::serialization::access;
164 template <
class ARCHIVE>
165 void serialize(ARCHIVE& ar,
const unsigned int );
167 std::map<Time, T> timestamp_value_map_;
168 boost::optional<int> max_size_;
172 template <
typename T>
175 template <
typename T>
177 const boost::optional<int> max_size)
178 : max_size_(max_size) {
179 for (
int i = 0; i < values.size(); ++i) {
180 Add(timestamps[i], values[i]);
184 template <
typename T>
186 if (Contains(timestamp))
return false;
187 timestamp_value_map_.emplace(timestamp, value);
189 if (max_size_ && size() > *max_size_) {
190 auto end_it = timestamp_value_map_.begin();
191 std::advance(end_it, *max_size_ / 2);
192 timestamp_value_map_.erase(timestamp_value_map_.begin(), end_it);
197 template <
typename T>
199 if (!Contains(timestamp))
return false;
200 timestamp_value_map_.erase(timestamp);
204 template <
typename T>
206 if (!Contains(timestamp))
return boost::none;
210 template <
typename T>
212 return timestamp_value_map_.
size();
215 template <
typename T>
217 return timestamp_value_map_.
empty();
220 template <
typename T>
222 timestamp_value_map_.clear();
225 template <
typename T>
228 LogDebug(
"Oldest: No timestamps available.");
234 template <
typename T>
237 LogDebug(
"OldestTimestamp: No timestamps available.");
240 return timestamp_value_map_.cbegin()->first;
243 template <
typename T>
246 LogDebug(
"Latest: No values available.");
252 template <
typename T>
255 LogDebug(
"LatestTimestamp: No values available.");
258 return timestamp_value_map_.crbegin()->first;
261 template <
typename T>
263 const auto oldest = Oldest();
264 const auto latest = Latest();
265 if (!oldest || !latest) {
266 LogError(
"WithinBounds: Failed to get time bounds.");
269 return (time >= oldest->timestamp && time <= latest->timestamp);
272 template <
typename T>
273 std::pair<boost::optional<TimestampedValue<T>>, boost::optional<TimestampedValue<T>>>
276 LogDebug(
"LowerAndUpperBound: No timestamps available.");
277 return {boost::none, boost::none};
281 const auto upper_bound_it = timestamp_value_map_.lower_bound(timestamp);
282 if (upper_bound_it == timestamp_value_map_.cend()) {
283 LogDebug(
"LowerAndUpperBoundTimestamps: No upper bound timestamp exists.");
284 return {boost::optional<TimestampedValue<T>>(*(timestamp_value_map_.crbegin())), boost::none};
285 }
else if (upper_bound_it->first == timestamp) {
287 return {boost::optional<TimestampedValue<T>>(*upper_bound_it),
288 boost::optional<TimestampedValue<T>>(*upper_bound_it)};
289 }
else if (upper_bound_it == timestamp_value_map_.cbegin()) {
290 LogDebug(
"LowerAndUpperBoundTimestamps: No lower bound timestamp exists.");
291 return {boost::none, boost::optional<TimestampedValue<T>>(*upper_bound_it)};
293 const auto lower_bound_it = std::prev(upper_bound_it);
295 return {boost::optional<TimestampedValue<T>>(*lower_bound_it), boost::optional<TimestampedValue<T>>(*upper_bound_it)};
298 template <
typename T>
300 const auto lower_and_upper_bound_values = LowerAndUpperBound(timestamp);
301 if (!lower_and_upper_bound_values.first && !lower_and_upper_bound_values.second) {
302 LogDebug(
"LowerBoundOrEqual: Failed to get lower or upper bound values.");
307 if (lower_and_upper_bound_values.second && lower_and_upper_bound_values.second->timestamp == timestamp) {
308 return lower_and_upper_bound_values.second;
311 return lower_and_upper_bound_values.first;
314 template <
typename T>
316 std::vector<Time> timestamps;
317 for (
const auto& timestamped_value : timestamp_value_map_) {
318 timestamps.emplace_back(timestamped_value.first);
323 template <
typename T>
325 if (empty())
return 0;
326 return (*LatestTimestamp() - *OldestTimestamp());
329 template <
typename T>
332 LogDebug(
"Closest: No values available.");
336 const auto lower_and_upper_bound_values = LowerAndUpperBound(timestamp);
337 if (!lower_and_upper_bound_values.first && !lower_and_upper_bound_values.second) {
338 LogDebug(
"Closest: Failed to get lower or upper bound values.");
342 if (!lower_and_upper_bound_values.first) {
343 return lower_and_upper_bound_values.second;
344 }
else if (!lower_and_upper_bound_values.second) {
345 return lower_and_upper_bound_values.first;
347 const Time lower_bound_timestamp = lower_and_upper_bound_values.first->timestamp;
348 const Time upper_bound_timestamp = lower_and_upper_bound_values.second->timestamp;
349 const double upper_bound_dt = std::abs(timestamp - upper_bound_timestamp);
350 const double lower_bound_dt = std::abs(timestamp - lower_bound_timestamp);
351 return (upper_bound_dt < lower_bound_dt) ? lower_and_upper_bound_values.second : lower_and_upper_bound_values.first;
355 template <
typename T>
357 return timestamp_value_map_.count(timestamp) > 0;
360 template <
typename T>
362 std::vector<TimestampedValue<T>> latest_values;
363 std::transform(timestamp_value_map_.lower_bound(oldest_allowed_timestamp), timestamp_value_map_.end(),
364 std::back_inserter(latest_values),
365 [](
const std::pair<Time, T>& value) { return TimestampedValue<T>(value); });
366 return latest_values;
369 template <
typename T>
371 std::vector<TimestampedValue<T>> old_values;
372 std::transform(timestamp_value_map_.begin(), timestamp_value_map_.lower_bound(oldest_allowed_timestamp),
373 std::back_inserter(old_values),
374 [](
const std::pair<Time, T>& value) { return TimestampedValue<T>(value); });
378 template <
typename T>
379 template <
typename TimestampSetType>
381 const TimestampSetType& allowed_timestamps)
const {
382 std::vector<TimestampedValue<T>> downsampled_values;
383 for (
const auto& pair : timestamp_value_map_) {
384 if (allowed_timestamps.count(pair.first) > 0) {
388 return downsampled_values;
391 template <
typename T>
393 const int initial_num_values = size();
394 timestamp_value_map_.erase(timestamp_value_map_.begin(), timestamp_value_map_.lower_bound(oldest_allowed_timestamp));
395 return initial_num_values - size();
398 template <
typename T>
400 const int initial_num_values = size();
401 const auto upper_bound = timestamp_value_map_.lower_bound(timestamp);
402 const auto lower_bound =
403 upper_bound != timestamp_value_map_.cbegin() ? std::prev(upper_bound) : timestamp_value_map_.cbegin();
404 timestamp_value_map_.erase(timestamp_value_map_.begin(), lower_bound);
405 return initial_num_values - size();
408 template <
typename T>
410 const auto oldest = Oldest();
411 if (oldest) Remove(oldest->timestamp);
415 template <
typename T>
417 return timestamp_value_map_;
420 template <
typename T>
422 return timestamp_value_map_;
425 template <
typename T>
427 return timestamp_value_map_.
cend();
430 template <
typename T>
431 std::pair<typename std::map<Time, T>::const_iterator,
typename std::map<Time, T>::const_iterator>
433 auto upper_bound = timestamp_value_map_.upper_bound(latest_allowed_timestamp);
434 auto lower_bound = timestamp_value_map_.lower_bound(oldest_allowed_timestamp);
436 if (upper_bound == timestamp_value_map_.cbegin())
return {cend(), cend()};
437 return std::make_pair(timestamp_value_map_.lower_bound(oldest_allowed_timestamp), upper_bound);
440 template <
typename T>
441 template <
class ARCHIVE>
443 ar& BOOST_SERIALIZATION_NVP(timestamp_value_map_);
444 ar& BOOST_SERIALIZATION_NVP(max_size_);
448 #endif // LOCALIZATION_COMMON_TIMESTAMPED_SET_H_