MemoryMapping::data() returns StringPiece ::range() returns ByteRange
[folly.git] / folly / MemoryMapping.h
1 /*
2  * Copyright 2013 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef FOLLY_MEMORYMAPPING_H_
18 #define FOLLY_MEMORYMAPPING_H_
19
20 #include "folly/FBString.h"
21 #include "folly/File.h"
22 #include "folly/Range.h"
23 #include <glog/logging.h>
24 #include <boost/noncopyable.hpp>
25
26 namespace folly {
27
28 /**
29  * Maps files in memory (read-only).
30  *
31  * @author Tudor Bosman (tudorb@fb.com)
32  */
33 class MemoryMapping : boost::noncopyable {
34  public:
35   /**
36    * Lock the pages in memory?
37    * TRY_LOCK  = try to lock, log warning if permission denied
38    * MUST_LOCK = lock, fail assertion if permission denied.
39    */
40   enum class LockMode {
41     TRY_LOCK,
42     MUST_LOCK
43   };
44   /**
45    * Map a portion of the file indicated by filename in memory, causing a CHECK
46    * failure on error.
47    *
48    * By default, map the whole file.  length=-1: map from offset to EOF.
49    * Unlike the mmap() system call, offset and length don't need to be
50    * page-aligned.  length is clipped to the end of the file if it's too large.
51    *
52    * The mapping will be destroyed (and the memory pointed-to by data() will
53    * likely become inaccessible) when the MemoryMapping object is destroyed.
54    */
55   explicit MemoryMapping(File file,
56                          off_t offset=0,
57                          off_t length=-1);
58
59   virtual ~MemoryMapping();
60
61   /**
62    * Lock the pages in memory
63    */
64   bool mlock(LockMode lock);
65
66   /**
67    * Unlock the pages.
68    * If dontneed is true, the kernel is instructed to release these pages
69    * (per madvise(MADV_DONTNEED)).
70    */
71   void munlock(bool dontneed=false);
72
73   /**
74    * Hint that these pages will be scanned linearly.
75    * madvise(MADV_SEQUENTIAL)
76    */
77   void hintLinearScan();
78
79   /**
80    * Advise the kernel about memory access.
81    */
82   void advise(int advice) const;
83
84   /**
85    * A bitwise cast of the mapped bytes as range of values. Only intended for
86    * use with POD or in-place usable types.
87    */
88   template<class T>
89   Range<const T*> asRange() const {
90     size_t count = data_.size() / sizeof(T);
91     return Range<const T*>(static_cast<const T*>(
92                              static_cast<const void*>(data_.data())),
93                            count);
94   }
95
96   /**
97    * A range of bytes mapped by this mapping.
98    */
99   Range<const uint8_t*> range() const {
100     return {data_.begin(), data_.end()};
101   }
102
103   /**
104    * Return the memory area where the file was mapped.
105    */
106   StringPiece data() const {
107     return asRange<const char>();
108   }
109
110   bool mlocked() const {
111     return locked_;
112   }
113
114   int fd() const { return file_.fd(); }
115
116  protected:
117   MemoryMapping();
118
119   void init(File file,
120             off_t offset, off_t length,
121             int prot,
122             bool grow);
123
124   File file_;
125   void* mapStart_;
126   off_t mapLength_;
127   bool locked_;
128   Range<uint8_t*> data_;
129 };
130
131 /**
132  * Maps files in memory for writing.
133  *
134  * @author Tom Jackson (tjackson@fb.com)
135  */
136 class WritableMemoryMapping : public MemoryMapping {
137  public:
138   explicit WritableMemoryMapping(File file,
139                                  off_t offset = 0,
140                                  off_t length = -1);
141   /**
142    * A bitwise cast of the mapped bytes as range of mutable values. Only
143    * intended for use with POD or in-place usable types.
144    */
145   template<class T>
146   Range<T*> asWritableRange() const {
147     size_t count = data_.size() / sizeof(T);
148     return Range<T*>(static_cast<T*>(
149                        static_cast<void*>(data_.data())),
150                      count);
151   }
152
153   /**
154    * A range of mutable bytes mapped by this mapping.
155    */
156   Range<uint8_t*> writableRange() const {
157     return data_;
158   }
159 };
160
161 }  // namespace folly
162
163 #endif /* FOLLY_MEMORYMAPPING_H_ */