MemoryMapping::data() returns StringPiece ::range() returns ByteRange
authorLucian Grijincu <lucian@fb.com>
Wed, 27 Feb 2013 23:44:37 +0000 (15:44 -0800)
committerJordan DeLong <jdelong@fb.com>
Tue, 19 Mar 2013 00:07:56 +0000 (17:07 -0700)
Summary: MemoryMapping::data() returns StringPiece ::range() returns ByteRange

Test Plan: tests

Reviewed By: philipp@fb.com

FB internal diff: D720985

folly/MemoryMapping.h
folly/test/MemoryMappingTest.cpp

index 244727b4a6db12ff46249ea7a78c0c632eeaee01..3a355892ed01397808a43e1ee9248ca95a941ac8 100644 (file)
@@ -87,7 +87,6 @@ class MemoryMapping : boost::noncopyable {
    */
   template<class T>
   Range<const T*> asRange() const {
-    CHECK(mapStart_);
     size_t count = data_.size() / sizeof(T);
     return Range<const T*>(static_cast<const T*>(
                              static_cast<const void*>(data_.data())),
@@ -104,14 +103,16 @@ class MemoryMapping : boost::noncopyable {
   /**
    * Return the memory area where the file was mapped.
    */
-  ByteRange data() const {
-    return range();
+  StringPiece data() const {
+    return asRange<const char>();
   }
 
   bool mlocked() const {
     return locked_;
   }
 
+  int fd() const { return file_.fd(); }
+
  protected:
   MemoryMapping();
 
@@ -143,7 +144,6 @@ class WritableMemoryMapping : public MemoryMapping {
    */
   template<class T>
   Range<T*> asWritableRange() const {
-    CHECK(mapStart_);
     size_t count = data_.size() / sizeof(T);
     return Range<T*>(static_cast<T*>(
                        static_cast<void*>(data_.data())),
index 662c54c360f605fb55b7a02b0d761605c7d62410..61dceb2af1b1cda4b12a409f1a1ce6c1ff227da3 100644 (file)
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <cstdlib>
 #include <gtest/gtest.h>
 #include "folly/MemoryMapping.h"
 
@@ -54,4 +55,73 @@ TEST(MemoryMapping, DoublyMapped) {
   EXPECT_EQ(*dr, 43 * M_PI);
 }
 
+namespace {
+
+void writeStringToFileOrDie(const std::string& str, int fd) {
+  const char* b = str.c_str();
+  size_t count = str.size();
+  ssize_t total_bytes = 0;
+  ssize_t r;
+  do {
+    r = write(fd, b, count);
+    if (r == -1) {
+      if (errno == EINTR) {
+        continue;
+      }
+      PCHECK(r) << "write";
+    }
+
+    total_bytes += r;
+    b += r;
+    count -= r;
+  } while (r != 0 && count);
+}
+
+}  // anonymous namespace
+
+TEST(MemoryMapping, Simple) {
+  File f = File::temporary();
+  writeStringToFileOrDie("hello", f.fd());
+
+  {
+    MemoryMapping m(f.fd());
+    EXPECT_EQ("hello", m.data());
+  }
+  {
+    MemoryMapping m(f.fd(), 1, 2);
+    EXPECT_EQ("el", m.data());
+  }
+}
+
+TEST(MemoryMapping, LargeFile) {
+  std::string fileData;
+  size_t fileSize = sysconf(_SC_PAGESIZE) * 3 + 10;
+  fileData.reserve(fileSize);
+  for (size_t i = 0; i < fileSize; i++) {
+    fileData.push_back(0xff & random());
+  }
+
+  File f = File::temporary();
+  writeStringToFileOrDie(fileData, f.fd());
+
+  {
+    MemoryMapping m(f.fd());
+    EXPECT_EQ(fileData, m.data());
+  }
+  {
+    size_t size = sysconf(_SC_PAGESIZE) * 2;
+    StringPiece s(fileData.data() + 9, size - 9);
+    MemoryMapping m(f.fd(), 9, size - 9);
+    EXPECT_EQ(s.toString(), m.data());
+  }
+}
+
+TEST(MemoryMapping, ZeroLength) {
+  File f = File::temporary();
+  MemoryMapping m(f.fd());
+  EXPECT_TRUE(m.mlock(MemoryMapping::LockMode::MUST_LOCK));
+  EXPECT_TRUE(m.mlocked());
+  EXPECT_EQ(0, m.data().size());
+}
+
 } // namespace folly