Use ResizeableBuffer for FlatbufferVector

This speeds up fastbuild log reading a lot.

Change-Id: I4452096a9a1d5b0330cbfeed5762dcc4f15d0d20
diff --git a/aos/BUILD b/aos/BUILD
index 286882f..a46911e 100644
--- a/aos/BUILD
+++ b/aos/BUILD
@@ -453,6 +453,7 @@
     visibility = ["//visibility:public"],
     deps = [
         "//aos:macros",
+        "//aos/containers:resizeable_buffer",
         "@com_github_google_flatbuffers//:flatbuffers",
         "@com_github_google_glog//:glog",
         "@com_google_absl//absl/strings",
diff --git a/aos/events/event_loop.h b/aos/events/event_loop.h
index 1e7d25b..6ffb0fe 100644
--- a/aos/events/event_loop.h
+++ b/aos/events/event_loop.h
@@ -79,9 +79,10 @@
   // underlying flatbuffer.
   template <typename T>
   FlatbufferVector<T> CopyFlatBuffer() const {
-    return FlatbufferVector<T>(
-        std::vector<uint8_t>(reinterpret_cast<const uint8_t *>(data),
-                             reinterpret_cast<const uint8_t *>(data) + size));
+    ResizeableBuffer buffer;
+    buffer.resize(size);
+    memcpy(buffer.data(), data, size);
+    return FlatbufferVector<T>(std::move(buffer));
   }
 };
 
diff --git a/aos/events/logging/logfile_utils.cc b/aos/events/logging/logfile_utils.cc
index c7f013d..9d8145d 100644
--- a/aos/events/logging/logfile_utils.cc
+++ b/aos/events/logging/logfile_utils.cc
@@ -300,8 +300,10 @@
       << ": Failed to read header from: " << filename;
 
   // And copy the config so we have it forever, removing the size prefix.
-  std::vector<uint8_t> data(
-      config_data.begin() + sizeof(flatbuffers::uoffset_t), config_data.end());
+  ResizeableBuffer data;
+  data.resize(config_data.size() - sizeof(flatbuffers::uoffset_t));
+  memcpy(data.data(), config_data.begin() + sizeof(flatbuffers::uoffset_t),
+         data.size());
   return FlatbufferVector<LogFileHeader>(std::move(data));
 }
 
@@ -317,9 +319,11 @@
         << ": Failed to read data from: " << filename;
   }
 
-  // And copy the data so we have it forever.
-  std::vector<uint8_t> data(data_span.begin() + sizeof(flatbuffers::uoffset_t),
-                            data_span.end());
+  // And copy the config so we have it forever, removing the size prefix.
+  ResizeableBuffer data;
+  data.resize(data_span.size() - sizeof(flatbuffers::uoffset_t));
+  memcpy(data.data(), data_span.begin() + sizeof(flatbuffers::uoffset_t),
+         data.size());
   return FlatbufferVector<MessageHeader>(std::move(data));
 }
 
@@ -334,8 +338,11 @@
       << ": Failed to read header from: " << filename;
 
   // And copy the header data so we have it forever.
-  std::vector<uint8_t> header_data_copy(
-      header_data.begin() + sizeof(flatbuffers::uoffset_t), header_data.end());
+  ResizeableBuffer header_data_copy;
+  header_data_copy.resize(header_data.size() - sizeof(flatbuffers::uoffset_t));
+  memcpy(header_data_copy.data(),
+         header_data.begin() + sizeof(flatbuffers::uoffset_t),
+         header_data_copy.size());
   raw_log_file_header_ =
       FlatbufferVector<LogFileHeader>(std::move(header_data_copy));
 
@@ -352,8 +359,12 @@
     return std::nullopt;
   }
 
-  FlatbufferVector<MessageHeader> result{std::vector<uint8_t>(
-      msg_data.begin() + sizeof(flatbuffers::uoffset_t), msg_data.end())};
+  ResizeableBuffer result_buffer;
+  result_buffer.resize(msg_data.size() - sizeof(flatbuffers::uoffset_t));
+  memcpy(result_buffer.data(),
+         msg_data.begin() + sizeof(flatbuffers::uoffset_t),
+         result_buffer.size());
+  FlatbufferVector<MessageHeader> result(std::move(result_buffer));
 
   const monotonic_clock::time_point timestamp = monotonic_clock::time_point(
       chrono::nanoseconds(result.message().monotonic_sent_time()));
diff --git a/aos/flatbuffers.h b/aos/flatbuffers.h
index 33d50d3..5da7466 100644
--- a/aos/flatbuffers.h
+++ b/aos/flatbuffers.h
@@ -5,6 +5,7 @@
 #include <string_view>
 
 #include "absl/types/span.h"
+#include "aos/containers/resizeable_buffer.h"
 #include "aos/macros.h"
 #include "flatbuffers/flatbuffers.h"
 #include "glog/logging.h"
@@ -164,15 +165,16 @@
 class FlatbufferVector : public Flatbuffer<T> {
  public:
   // Builds a Flatbuffer around a vector.
-  FlatbufferVector(std::vector<uint8_t> &&data) : data_(std::move(data)) {}
+  FlatbufferVector(ResizeableBuffer &&data) : data_(std::move(data)) {}
 
   // Builds a Flatbuffer by copying the data from the other flatbuffer.
-  FlatbufferVector(const Flatbuffer<T> &other)
-      : data_(other.data(), other.data() + other.size()) {}
+  FlatbufferVector(const Flatbuffer<T> &other) {
+    data_.resize(other.size());
+    memcpy(data_.data(), other.data(), data_.size());
+  }
 
   // Copy constructor.
-  FlatbufferVector(const FlatbufferVector<T> &other)
-      : data_(other.data(), other.data() + other.size()) {}
+  FlatbufferVector(const FlatbufferVector<T> &other) : data_(other.data_) {}
 
   // Move constructor.
   FlatbufferVector(FlatbufferVector<T> &&other)
@@ -180,7 +182,7 @@
 
   // Copies the data from the other flatbuffer.
   FlatbufferVector &operator=(const FlatbufferVector<T> &other) {
-    data_ = std::vector<uint8_t>(other.data(), other.data() + other.size());
+    data_ = other.data_;
     return *this;
   }
   FlatbufferVector &operator=(FlatbufferVector<T> &&other) {
@@ -190,7 +192,7 @@
 
   // Constructs an empty flatbuffer of type T.
   static FlatbufferVector<T> Empty() {
-    return FlatbufferVector<T>(std::vector<uint8_t>{});
+    return FlatbufferVector<T>(ResizeableBuffer());
   }
 
   virtual ~FlatbufferVector() override {}
@@ -200,7 +202,7 @@
   size_t size() const override { return data_.size(); }
 
  private:
-  std::vector<uint8_t> data_;
+  ResizeableBuffer data_;
 };
 
 // This object associates the message type with the memory storing the
diff --git a/aos/json_to_flatbuffer.h b/aos/json_to_flatbuffer.h
index 381621e..c997f03 100644
--- a/aos/json_to_flatbuffer.h
+++ b/aos/json_to_flatbuffer.h
@@ -122,8 +122,12 @@
 template <typename T>
 inline FlatbufferVector<T> FileToFlatbuffer(const std::string_view path) {
   std::ifstream instream(std::string(path), std::ios::in | std::ios::binary);
-  std::vector<uint8_t> data((std::istreambuf_iterator<char>(instream)),
-                            std::istreambuf_iterator<char>());
+  ResizeableBuffer data;
+  std::istreambuf_iterator<char> it(instream);
+  while (it != std::istreambuf_iterator<char>()) {
+    data.push_back(*it);
+    ++it;
+  }
   return FlatbufferVector<T>(std::move(data));
 }