MMapping for flatbuffers

This lets us lazily load flatbuffers using mmap to both reduce memory
usage and to increase speed for use cases where we don't need to access
everything.

Change-Id: Ia271350b4c7cbb7a0a86ca094ef69c34716ba754
Signed-off-by: Austin Schuh <austin.schuh@bluerivertech.com>
diff --git a/aos/util/BUILD b/aos/util/BUILD
index 59dec18..daacba1 100644
--- a/aos/util/BUILD
+++ b/aos/util/BUILD
@@ -246,6 +246,7 @@
         "//aos/scoped:scoped_fd",
         "@com_github_google_glog//:glog",
         "@com_google_absl//absl/strings",
+        "@com_google_absl//absl/types:span",
     ],
 )
 
diff --git a/aos/util/file.cc b/aos/util/file.cc
index 4473d4d..cec5a6e 100644
--- a/aos/util/file.cc
+++ b/aos/util/file.cc
@@ -2,6 +2,7 @@
 
 #include <fcntl.h>
 #include <fts.h>
+#include <sys/mman.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
@@ -151,5 +152,24 @@
   }
 }
 
+std::shared_ptr<absl::Span<uint8_t>> MMapFile(const std::string &path) {
+  int fd = open(path.c_str(), O_RDONLY);
+  PCHECK(fd != -1) << "Unable to open file " << path;
+  struct stat sb;
+  PCHECK(fstat(fd, &sb) != -1) << ": Unable to get file size of " << path;
+  uint8_t *start = reinterpret_cast<uint8_t *>(
+      mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0));
+  CHECK(start != MAP_FAILED) << ": Unable to open mapping to file " << path;
+  std::shared_ptr<absl::Span<uint8_t>> span =
+      std::shared_ptr<absl::Span<uint8_t>>(
+          new absl::Span<uint8_t>(start, sb.st_size),
+          [](absl::Span<uint8_t> *span) {
+            PCHECK(munmap(span->data(), span->size()) != -1);
+            delete span;
+          });
+  close(fd);
+  return span;
+}
+
 }  // namespace util
 }  // namespace aos
diff --git a/aos/util/file.h b/aos/util/file.h
index 8089225..7c06ece 100644
--- a/aos/util/file.h
+++ b/aos/util/file.h
@@ -2,9 +2,12 @@
 #define AOS_UTIL_FILE_H_
 
 #include <sys/stat.h>
+
+#include <memory>
 #include <string>
 #include <string_view>
 
+#include "absl/types/span.h"
 #include "glog/logging.h"
 
 namespace aos {
@@ -32,6 +35,9 @@
 // runs across.
 void UnlinkRecursive(std::string_view path);
 
+// Maps file from disk into memory
+std::shared_ptr<absl::Span<uint8_t>> MMapFile(const std::string &path);
+
 }  // namespace util
 }  // namespace aos