Read all timestamps into RAM where possible when reading logs

There are cases where we fail to buffer far enough in the future to
solve the timestamp problem, or where we end up choosing to buffer until
the end of time to solve the timestamp problem.  These both result in
log reading failures either through CHECKs or OOMs.

Timestamps are tiny.  The existence of timestamp_extractor proves that
we can store the whole timestamp problem in memory relatively easily.
When timestamps are stored in separate files, let's just load them at
the start.

This also adds flags to force this behavior on and off.  When a log with
data and timestamps mixed in it is found, and the flag forces it on, we
will read the data files twice to extract the timestamps the first time.

I'd like to add more tests to logfile_utils_test to test this all
explicitly, but the multinode_logger tests appear to do a really good
job already.

Change-Id: I38e23836afa980e3e3a839125e78e132066e2c90
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/aos/events/logging/multinode_logger_test.cc b/aos/events/logging/multinode_logger_test.cc
index b843e3e..a055006 100644
--- a/aos/events/logging/multinode_logger_test.cc
+++ b/aos/events/logging/multinode_logger_test.cc
@@ -27,13 +27,28 @@
         ::testing::Values(
             ConfigParams{"multinode_pingpong_combined_config.json", true,
                          kCombinedConfigSha1(), kCombinedConfigSha1(),
-                         FileStrategy::kKeepSeparate},
+                         FileStrategy::kKeepSeparate,
+                         ForceTimestampBuffering::kForceBufferTimestamps},
+            ConfigParams{"multinode_pingpong_combined_config.json", true,
+                         kCombinedConfigSha1(), kCombinedConfigSha1(),
+                         FileStrategy::kKeepSeparate,
+                         ForceTimestampBuffering::kAutoBuffer},
             ConfigParams{"multinode_pingpong_split_config.json", false,
                          kSplitConfigSha1(), kReloggedSplitConfigSha1(),
-                         FileStrategy::kKeepSeparate},
+                         FileStrategy::kKeepSeparate,
+                         ForceTimestampBuffering::kForceBufferTimestamps},
             ConfigParams{"multinode_pingpong_split_config.json", false,
                          kSplitConfigSha1(), kReloggedSplitConfigSha1(),
-                         FileStrategy::kCombine}),
+                         FileStrategy::kKeepSeparate,
+                         ForceTimestampBuffering::kAutoBuffer},
+            ConfigParams{"multinode_pingpong_split_config.json", false,
+                         kSplitConfigSha1(), kReloggedSplitConfigSha1(),
+                         FileStrategy::kCombine,
+                         ForceTimestampBuffering::kForceBufferTimestamps},
+            ConfigParams{"multinode_pingpong_split_config.json", false,
+                         kSplitConfigSha1(), kReloggedSplitConfigSha1(),
+                         FileStrategy::kCombine,
+                         ForceTimestampBuffering::kAutoBuffer}),
         ::testing::ValuesIn(SupportedCompressionAlgorithms())));
 
 INSTANTIATE_TEST_SUITE_P(
@@ -42,13 +57,28 @@
         ::testing::Values(
             ConfigParams{"multinode_pingpong_combined_config.json", true,
                          kCombinedConfigSha1(), kCombinedConfigSha1(),
-                         FileStrategy::kKeepSeparate},
+                         FileStrategy::kKeepSeparate,
+                         ForceTimestampBuffering::kForceBufferTimestamps},
+            ConfigParams{"multinode_pingpong_combined_config.json", true,
+                         kCombinedConfigSha1(), kCombinedConfigSha1(),
+                         FileStrategy::kKeepSeparate,
+                         ForceTimestampBuffering::kAutoBuffer},
             ConfigParams{"multinode_pingpong_split_config.json", false,
                          kSplitConfigSha1(), kReloggedSplitConfigSha1(),
-                         FileStrategy::kKeepSeparate},
+                         FileStrategy::kKeepSeparate,
+                         ForceTimestampBuffering::kForceBufferTimestamps},
             ConfigParams{"multinode_pingpong_split_config.json", false,
                          kSplitConfigSha1(), kReloggedSplitConfigSha1(),
-                         FileStrategy::kCombine}),
+                         FileStrategy::kKeepSeparate,
+                         ForceTimestampBuffering::kAutoBuffer},
+            ConfigParams{"multinode_pingpong_split_config.json", false,
+                         kSplitConfigSha1(), kReloggedSplitConfigSha1(),
+                         FileStrategy::kCombine,
+                         ForceTimestampBuffering::kForceBufferTimestamps},
+            ConfigParams{"multinode_pingpong_split_config.json", false,
+                         kSplitConfigSha1(), kReloggedSplitConfigSha1(),
+                         FileStrategy::kCombine,
+                         ForceTimestampBuffering::kAutoBuffer}),
         ::testing::ValuesIn(SupportedCompressionAlgorithms())));
 
 // Tests that we can write and read simple multi-node log files.