19 #ifndef NODES_TIMESTAMPED_COMBINED_NODES_H_ 
   20 #define NODES_TIMESTAMPED_COMBINED_NODES_H_ 
   26 #include <gtsam/nonlinear/NonlinearFactorGraph.h> 
   28 #include <boost/optional.hpp> 
   29 #include <boost/serialization/serialization.hpp> 
   36 template <
typename NodeType>
 
   69   boost::optional<T> 
Value(
const gtsam::Key& key) 
const;
 
  104   std::pair<boost::optional<localization_common::Time>, boost::optional<localization_common::Time>>
 
  118   boost::optional<localization_common::TimestampedValue<NodeType>> 
LowerBoundOrEqual(
 
  133   std::vector<localization_common::Time> 
Timestamps() 
const;
 
  149   bool Remove(
const gtsam::KeyVector& keys);
 
  152   virtual gtsam::KeyVector AddNode(
const NodeType& node) = 0;
 
  155   virtual boost::optional<NodeType> GetNode(
const gtsam::KeyVector& keys,
 
  161   friend class boost::serialization::access;
 
  162   template <
class ARCHIVE>
 
  163   void serialize(ARCHIVE& ar, 
const unsigned int );
 
  169 template <
typename NodeType>
 
  171     : values_(
std::move(values)) {}
 
  173 template <
typename NodeType>
 
  175                                                          const NodeType& node) {
 
  176   if (Contains(timestamp)) 
return gtsam::KeyVector();
 
  177   gtsam::KeyVector keys = AddNode(node);
 
  178   timestamp_keys_map_.Add(timestamp, keys);
 
  182 template <
typename NodeType>
 
  184   const auto keys = Keys(timestamp);
 
  185   if (keys.empty()) 
return boost::none;
 
  186   return GetNode(keys, timestamp);
 
  189 template <
typename NodeType>
 
  192   return GetNode(timestamped_keys.
value, timestamped_keys.
timestamp);
 
  195 template <
typename NodeType>
 
  196 template <
typename T>
 
  198   return values_->Value<T>(key);
 
  201 template <
typename NodeType>
 
  203   if (!Contains(timestamp)) 
return {};
 
  204   return (timestamp_keys_map_.Get(timestamp))->value;
 
  207 template <
typename NodeType>
 
  209   const auto value = timestamp_keys_map_.Get(timestamp);
 
  210   if (!value) 
return false;
 
  211   bool successful_removal = 
true;
 
  212   successful_removal = successful_removal && timestamp_keys_map_.
Remove(timestamp);
 
  213   successful_removal = successful_removal && Remove(value->value);
 
  214   return successful_removal;
 
  217 template <
typename NodeType>
 
  219   return values_->
Remove(keys);
 
  222 template <
typename NodeType>
 
  224   return timestamp_keys_map_.
size();
 
  227 template <
typename NodeType>
 
  229   return timestamp_keys_map_.
empty();
 
  232 template <
typename NodeType>
 
  234   const auto oldest = timestamp_keys_map_.Oldest();
 
  235   if (!oldest) 
return boost::none;
 
  236   return oldest->timestamp;
 
  239 template <
typename NodeType>
 
  241   const auto oldest = timestamp_keys_map_.Oldest();
 
  242   if (!oldest) 
return boost::none;
 
  243   return Node(*oldest);
 
  246 template <
typename NodeType>
 
  248   const auto latest = timestamp_keys_map_.Latest();
 
  249   if (!latest) 
return boost::none;
 
  250   return latest->timestamp;
 
  253 template <
typename NodeType>
 
  255   const auto latest = timestamp_keys_map_.Latest();
 
  256   if (!latest) 
return boost::none;
 
  257   return Node(*latest);
 
  260 template <
typename NodeType>
 
  261 std::pair<boost::optional<localization_common::Time>, boost::optional<localization_common::Time>>
 
  263   const auto lower_and_upper_bound = timestamp_keys_map_.LowerAndUpperBound(timestamp);
 
  264   boost::optional<localization_common::Time> lower_bound;
 
  265   if (!lower_and_upper_bound.first)
 
  266     lower_bound = boost::none;
 
  268     lower_bound = lower_and_upper_bound.first->timestamp;
 
  269   boost::optional<localization_common::Time> upper_bound;
 
  270   if (!lower_and_upper_bound.second)
 
  271     upper_bound = boost::none;
 
  273     upper_bound = lower_and_upper_bound.second->timestamp;
 
  274   return {lower_bound, upper_bound};
 
  277 template <
typename NodeType>
 
  278 std::pair<boost::optional<NodeType>, boost::optional<NodeType>>
 
  280   const auto lower_and_upper_bound = timestamp_keys_map_.LowerAndUpperBound(timestamp);
 
  281   boost::optional<NodeType> lower_bound;
 
  282   if (!lower_and_upper_bound.first)
 
  283     lower_bound = boost::none;
 
  285     lower_bound = Node(*(lower_and_upper_bound.first));
 
  286   boost::optional<NodeType> upper_bound;
 
  287   if (!lower_and_upper_bound.second)
 
  288     upper_bound = boost::none;
 
  290     upper_bound = Node(*(lower_and_upper_bound.second));
 
  291   return {lower_bound, upper_bound};
 
  294 template <
typename NodeType>
 
  297   const auto lower_bound_or_equal = timestamp_keys_map_.
LowerBoundOrEqual(timestamp);
 
  298   if (!lower_bound_or_equal) 
return boost::none;
 
  299   const auto node = Node(lower_bound_or_equal->timestamp);
 
  300   if (!node) 
return boost::none;
 
  304 template <
typename NodeType>
 
  309 template <
typename NodeType>
 
  311   return timestamp_keys_map_.
Duration();
 
  314 template <
typename NodeType>
 
  317   const auto old_values = timestamp_keys_map_.OldValues(oldest_allowed_timestamp);
 
  318   std::vector<NodeType> old_nodes;
 
  319   for (
const auto& old_value : old_values) {
 
  320     const auto old_node = Node(old_value);
 
  322       LogError(
"OldNodes: Failed to get node for keys.");
 
  325     old_nodes.emplace_back(*old_node);
 
  330 template <
typename NodeType>
 
  333   const auto old_timestamp_key_sets = timestamp_keys_map_.OldValues(oldest_allowed_timestamp);
 
  334   gtsam::KeyVector all_old_keys;
 
  335   for (
const auto& old_timestamp_key_set : old_timestamp_key_sets) {
 
  336     const auto& old_keys = old_timestamp_key_set.value;
 
  337     all_old_keys.insert(all_old_keys.end(), old_keys.begin(), old_keys.end());
 
  342 template <
typename NodeType>
 
  344   const auto old_values = timestamp_keys_map_.OldValues(oldest_allowed_timestamp);
 
  345   timestamp_keys_map_.RemoveOldValues(oldest_allowed_timestamp);
 
  346   int num_removed_nodes = 0;
 
  347   for (
const auto& old_value : old_values)
 
  348     if (Remove(old_value.value)) ++num_removed_nodes;
 
  349   return num_removed_nodes;
 
  352 template <
typename NodeType>
 
  355   const auto closest = timestamp_keys_map_.Closest(timestamp);
 
  356   if (!closest) 
return boost::none;
 
  357   return Node(*closest);
 
  360 template <
typename NodeType>
 
  363   const auto closest = timestamp_keys_map_.Closest(timestamp);
 
  364   if (!closest) 
return boost::none;
 
  365   return closest->timestamp;
 
  368 template <
typename NodeType>
 
  373 template <
typename NodeType>
 
  375   return timestamp_keys_map_.
Contains(timestamp);
 
  378 template <
typename NodeType>
 
  379 template <
class ARCHIVE>
 
  381   ar& BOOST_SERIALIZATION_NVP(values_);
 
  382   ar& BOOST_SERIALIZATION_NVP(timestamp_keys_map_);
 
  386 #endif  // NODES_TIMESTAMPED_COMBINED_NODES_H_