12
12
// See the License for the specific language governing permissions and
13
13
// limitations under the License.
14
14
15
+ #include < algorithm>
15
16
#include < deque>
16
17
#include < memory>
17
18
#include < vector>
@@ -25,8 +26,11 @@ namespace rosbag2_cpp
25
26
namespace cache
26
27
{
27
28
28
- MessageCacheCircularBuffer::MessageCacheCircularBuffer (size_t max_cache_size)
29
- : max_bytes_size_(max_cache_size)
29
+ MessageCacheCircularBuffer::MessageCacheCircularBuffer (
30
+ size_t max_cache_size,
31
+ const std::unordered_map<std::string,
32
+ rosbag2_storage::TopicInformation> & topics_names_to_info)
33
+ : max_bytes_size_(max_cache_size), topics_names_to_info_(topics_names_to_info)
30
34
{
31
35
}
32
36
@@ -38,10 +42,37 @@ bool MessageCacheCircularBuffer::push(CacheBufferInterface::buffer_element_t msg
38
42
return false ;
39
43
}
40
44
41
- // Remove any old items until there is room for new message
45
+ // Remove any old items that is no transient local until there is room for new message
42
46
while (buffer_bytes_size_ > (max_bytes_size_ - msg->serialized_data ->buffer_length )) {
43
- buffer_bytes_size_ -= buffer_.front ()->serialized_data ->buffer_length ;
44
- buffer_.pop_front ();
47
+ auto is_not_transient_local = [this ](buffer_element_t buffer_element)
48
+ {
49
+ auto it_matching_topic_name = topics_names_to_info_.find (buffer_element->topic_name );
50
+ if (it_matching_topic_name != topics_names_to_info_.end ()) {
51
+ return it_matching_topic_name->second .topic_metadata .offered_qos_profiles .find (
52
+ " durability: 1" ) == std::string::npos;
53
+ }
54
+ return true ;
55
+ };
56
+
57
+ // Find the first element which is non transient local
58
+ auto it_first_not_transient = std::find_if (
59
+ buffer_.begin (),
60
+ buffer_.end (), is_not_transient_local);
61
+
62
+ size_t position_first_not_transient = std::distance (buffer_.begin (), it_first_not_transient);
63
+
64
+ // Remove the first non transient msg if found and if older transient messages account for less
65
+ // than 10% of the total number of messages in the buffer
66
+ // else pop_front
67
+ if (it_first_not_transient != buffer_.end () &&
68
+ (position_first_not_transient + 1 ) < buffer_.size () / 10 )
69
+ {
70
+ buffer_bytes_size_ -= it_first_not_transient->get ()->serialized_data ->buffer_length ;
71
+ buffer_.erase (it_first_not_transient);
72
+ } else {
73
+ buffer_.pop_front ();
74
+ buffer_bytes_size_ -= buffer_.front ()->serialized_data ->buffer_length ;
75
+ }
45
76
}
46
77
// Add new message to end of buffer
47
78
buffer_bytes_size_ += msg->serialized_data ->buffer_length ;
0 commit comments