Add LogPartsSorter to sort messages from a log file
Based on https://docs.google.com/document/d/1RZ6ZlADRUHmwiFOOmXA87FHPLFuN-7mS7tbFCwguZDE/edit#
we need to start by sorting all the messages from a set of parts. Make
a class and test this. (The testing infrastructure looks a bit
over-kill, but will be re-used a lot for the following tests).
Change-Id: Ifa1ba880ddf7cf923f24826e504b902a4787ad03
diff --git a/aos/events/logging/logfile_utils.h b/aos/events/logging/logfile_utils.h
index 25f02f9..13c83cf 100644
--- a/aos/events/logging/logfile_utils.h
+++ b/aos/events/logging/logfile_utils.h
@@ -14,6 +14,7 @@
#include <utility>
#include <vector>
+#include "absl/container/btree_set.h"
#include "absl/types/span.h"
#include "aos/containers/resizeable_buffer.h"
#include "aos/events/event_loop.h"
@@ -280,6 +281,10 @@
std::string_view filename() const { return message_reader_.filename(); }
+ const LogFileHeader *log_file_header() const {
+ return message_reader_.log_file_header();
+ }
+
// Returns the minimum amount of data needed to queue up for sorting before
// we are guarenteed to not see data out of order.
std::chrono::nanoseconds max_out_of_order_duration() const {
@@ -326,6 +331,44 @@
std::ostream &operator<<(std::ostream &os, const Message &m);
+// Class to sort the resulting messages from a PartsMessageReader.
+class LogPartsSorter {
+ public:
+ LogPartsSorter(LogParts log_parts);
+
+ // Returns the current log file header.
+ // TODO(austin): Is this the header we want to report? Do we want a better
+ // start time?
+ // TODO(austin): Report a start time from the LogParts. Figure out how that
+ // all works.
+ const LogFileHeader *log_file_header() const {
+ return parts_message_reader_.log_file_header();
+ }
+
+ // The time this data is sorted until.
+ monotonic_clock::time_point sorted_until() const { return sorted_until_; }
+
+ // Returns the next sorted message from the log file. It is safe to call
+ // std::move() on the result to move the data flatbuffer from it.
+ Message *Front();
+ // Pops the front message. This should only be called after a call to
+ // Front().
+ void PopFront();
+
+ // Returns a debug string representing the contents of this sorter.
+ std::string DebugString() const;
+
+ private:
+ // Log parts reader we are wrapping.
+ PartsMessageReader parts_message_reader_;
+ // Cache of the time we are sorted until.
+ aos::monotonic_clock::time_point sorted_until_ = monotonic_clock::min_time;
+
+ // Set used for efficient sorting of messages. We can benchmark and evaluate
+ // other data structures if this proves to be the bottleneck.
+ absl::btree_set<Message> messages_;
+};
+
class TimestampMerger;
// A design requirement is that the relevant data for a channel is not more than