Add NodeMerger for merging sorted logs

Following
https://docs.google.com/document/d/1RZ6ZlADRUHmwiFOOmXA87FHPLFuN-7mS7tbFCwguZDE/edit#
further, the next step is to sort all the log files together for a
single node, deduplicating here.  This implements and tests that.

Change-Id: I506ae65b350d83e41ba011521c0860627ac662df
diff --git a/aos/events/logging/logfile_utils.h b/aos/events/logging/logfile_utils.h
index 13c83cf..d0afdc9 100644
--- a/aos/events/logging/logfile_utils.h
+++ b/aos/events/logging/logfile_utils.h
@@ -327,6 +327,7 @@
 
   bool operator<(const Message &m2) const;
   bool operator>=(const Message &m2) const;
+  bool operator==(const Message &m2) const;
 };
 
 std::ostream &operator<<(std::ostream &os, const Message &m);
@@ -369,6 +370,38 @@
   absl::btree_set<Message> messages_;
 };
 
+// Class to run merge sort on the messages from multiple LogPartsSorter
+// instances.
+class NodeMerger {
+ public:
+  NodeMerger(std::vector<std::unique_ptr<LogPartsSorter>> parts);
+
+  // The log file header for one of the log files.
+  const LogFileHeader *log_file_header() const {
+    CHECK(!parts_sorters_.empty());
+    return parts_sorters_[0]->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 set of log files.  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();
+
+ private:
+  // Unsorted list of all parts sorters.
+  std::vector<std::unique_ptr<LogPartsSorter>> parts_sorters_;
+  // Pointer to the parts sorter holding the current Front message if one
+  // exists, or nullptr if a new one needs to be found.
+  LogPartsSorter *current_ = nullptr;
+  // Cached sorted_until value.
+  aos::monotonic_clock::time_point sorted_until_ = monotonic_clock::min_time;
+};
+
 class TimestampMerger;
 
 // A design requirement is that the relevant data for a channel is not more than