Skip to content

Commit

Permalink
[TimeCache] Improve performance for insertData() and pruneList() (#680)
Browse files Browse the repository at this point in the history
Signed-off-by: Eric Cousineau <[email protected]>
Co-authored-by: Chris Lalancette <[email protected]>
  • Loading branch information
EricCousineau-TRI and clalancette authored May 22, 2024
1 parent c9ca2ca commit d700d78
Showing 1 changed file with 34 additions and 12 deletions.
46 changes: 34 additions & 12 deletions tf2/src/cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,25 +248,48 @@ CompactFrameID TimeCache::getParent(

bool TimeCache::insertData(const TransformStorage & new_data)
{
// In order to minimize the number of times we iterate over this data, we:
// (1) Prune all old data first, regardless if new_data is added,
// (2) We use find_if to scan from newest to oldest, and stop at the first
// point where the timestamp is equal or older to new_data's.
// (3) From this point, we scan with more expensive full equality checks to
// ensure we do not reinsert the same exact data.
// (4) If we the data is not duplicated, then we simply insert new_data at
// the point found in (2).
const TimePoint latest_time = getLatestTimestamp();

// (1) Always prune data.
pruneList();

// Avoid inserting data in the past that already exceeds the max_storage_time_
if (!storage_.empty() && new_data.stamp_ < latest_time - max_storage_time_) {
return false;
}

// Find the oldest element in the list before the incoming stamp.
auto last_transform_pos = std::find_if(
storage_.begin(), storage_.end(), [&](const auto & transfrom) {
return transfrom.stamp_ <= new_data.stamp_;
// (2) Find the oldest element in the list before the incoming stamp.
auto insertion_pos = std::find_if(
storage_.begin(), storage_.end(), [&](const auto & transform) {
return transform.stamp_ <= new_data.stamp_;
});

// Insert elements only if not already present
if (std::find(storage_.begin(), storage_.end(), new_data) == storage_.end()) {
storage_.insert(last_transform_pos, new_data);
bool should_insert = true;

// (3) Search along all data with same timestamp (sorted), and see if we have
// an exact duplicate.
auto maybe_same_pos = insertion_pos;
while (maybe_same_pos != storage_.end() && maybe_same_pos->stamp_ == new_data.stamp_) {
if (*maybe_same_pos == new_data) {
should_insert = false;
break;
}
maybe_same_pos++;
}

// (4) Insert elements only if not already present
if (should_insert) {
storage_.insert(insertion_pos, new_data);
}

pruneList();
return true;
}

Expand Down Expand Up @@ -317,9 +340,8 @@ void TimeCache::pruneList()
{
const TimePoint latest_time = getLatestTimestamp();

storage_.remove_if(
[&](const auto & transform) {
return transform.stamp_ < latest_time - max_storage_time_;
});
while (!storage_.empty() && storage_.back().stamp_ + max_storage_time_ < latest_time) {
storage_.pop_back();
}
}
} // namespace tf2

0 comments on commit d700d78

Please sign in to comment.