2626#define KEYVI_DICTIONARY_FSA_INTERNAL_MEMORY_MAP_MANAGER_H_
2727
2828#include < algorithm>
29+ #include < cstring>
2930#include < fstream>
3031#include < string>
32+ #include < utility>
3133#include < vector>
3234
3335#include < boost/filesystem.hpp>
@@ -59,13 +61,7 @@ class MemoryMapManager final {
5961 MemoryMapManager (const size_t chunk_size, const boost::filesystem::path directory,
6062 const boost::filesystem::path filename_pattern)
6163 : chunk_size_(chunk_size), directory_(directory), filename_pattern_(filename_pattern) {}
62-
63- ~MemoryMapManager () {
64- for (auto & m : mappings_) {
65- delete m.mapping_ ;
66- delete m.region_ ;
67- }
68- }
64+ ~MemoryMapManager () = default ;
6965
7066 /* Using GetAdress to read multiple bytes is unsafe as it might be a buffer overflow
7167 *
@@ -82,7 +78,8 @@ class MemoryMapManager final {
8278
8379 void * chunk_address = GetChunk (chunk_number);
8480
85- return (reinterpret_cast <char *>(chunk_address) + chunk_offset);
81+ // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
82+ return static_cast <char *>(chunk_address) + chunk_offset;
8683 }
8784
8885 /* Get a buffer as copy.
@@ -97,12 +94,15 @@ class MemoryMapManager final {
9794 size_t second_chunk_size = buffer_length - first_chunk_size;
9895
9996 void * chunk_address = GetChunk (chunk_number);
100- std::memcpy (buffer, reinterpret_cast <char *>(chunk_address) + chunk_offset, first_chunk_size);
97+
98+ // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
99+ std::memcpy (buffer, static_cast <char *>(chunk_address) + chunk_offset, first_chunk_size);
101100
102101 if (second_chunk_size > 0 ) {
103102 void * chunk_address_part2 = GetChunk (chunk_number + 1 );
104- std::memcpy (reinterpret_cast <char *>(buffer) + first_chunk_size,
105- reinterpret_cast <const char *>(chunk_address_part2), second_chunk_size);
103+ // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
104+ std::memcpy (static_cast <char *>(buffer) + first_chunk_size, static_cast <const char *>(chunk_address_part2),
105+ second_chunk_size);
106106 }
107107 }
108108
@@ -129,8 +129,9 @@ class MemoryMapManager final {
129129 size_t copy_size = std::min (remaining, chunk_size_ - chunk_offset);
130130 TRACE (" copy size: %ld" , copy_size);
131131
132- std::memcpy (reinterpret_cast <char *>(chunk_address) + chunk_offset,
133- reinterpret_cast <const char *>(buffer) + buffer_offset, copy_size);
132+ // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
133+ std::memcpy (static_cast <char *>(chunk_address) + chunk_offset, static_cast <const char *>(buffer) + buffer_offset,
134+ copy_size);
134135
135136 remaining -= copy_size;
136137 tail_ += copy_size;
@@ -154,7 +155,8 @@ class MemoryMapManager final {
154155 void * chunk_address = GetChunk (chunk_number);
155156 size_t first_chunk_size = std::min (buffer_length, chunk_size_ - chunk_offset);
156157
157- if (std::memcmp (reinterpret_cast <char *>(chunk_address) + chunk_offset, buffer, first_chunk_size) != 0 ) {
158+ // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
159+ if (std::memcmp (static_cast <char *>(chunk_address) + chunk_offset, buffer, first_chunk_size) != 0 ) {
158160 return false ;
159161 }
160162
@@ -165,9 +167,10 @@ class MemoryMapManager final {
165167
166168 // handle overflow
167169 void * chunk_address_part2 = GetChunk (chunk_number + 1 );
168- return (std::memcmp (reinterpret_cast <const char *>(chunk_address_part2),
169- reinterpret_cast <const char *>(buffer) + first_chunk_size,
170- buffer_length - first_chunk_size) == 0 );
170+
171+ return (std::memcmp (static_cast <const char *>(chunk_address_part2),
172+ // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
173+ static_cast <const char *>(buffer) + first_chunk_size, buffer_length - first_chunk_size) == 0 );
171174 }
172175
173176 void Write (std::ostream& stream, const size_t end) const {
@@ -195,7 +198,7 @@ class MemoryMapManager final {
195198 size_t bytes_in_chunk = std::min (chunk_size_, remaining);
196199 TRACE (" write chunk %d, with size: %ld, remaining: %ld" , chunk, bytes_in_chunk, remaining);
197200
198- const char * ptr = reinterpret_cast <const char *>(mappings_[chunk].region_ -> get_address ());
201+ const char * ptr = static_cast <const char *>(mappings_[chunk].get_address ());
199202 stream.write (ptr, bytes_in_chunk);
200203
201204 remaining -= bytes_in_chunk;
@@ -212,9 +215,7 @@ class MemoryMapManager final {
212215 void Persist () {
213216 persisted_ = true ;
214217 for (auto & m : mappings_) {
215- m.region_ ->flush ();
216- delete m.region_ ;
217- delete m.mapping_ ;
218+ m.flush ();
218219 }
219220
220221 // truncate last file according to the written buffers
@@ -236,13 +237,8 @@ class MemoryMapManager final {
236237 size_t GetNumberOfChunks () const { return number_of_chunks_; }
237238
238239 private:
239- struct mapping {
240- boost::interprocess::file_mapping* mapping_;
241- boost::interprocess::mapped_region* region_;
242- };
243-
244240 size_t chunk_size_;
245- std::vector<mapping > mappings_;
241+ std::vector<boost::interprocess::mapped_region > mappings_;
246242 boost::filesystem::path directory_;
247243 boost::filesystem::path filename_pattern_;
248244 size_t tail_ = 0 ;
@@ -262,13 +258,11 @@ class MemoryMapManager final {
262258 CreateMapping ();
263259 }
264260
265- return mappings_[chunk_number].region_ -> get_address ();
261+ return mappings_[chunk_number].get_address ();
266262 }
267263
268264 void CreateMapping () {
269265 TRACE (" create new mapping %d" , number_of_chunks_ + 1 );
270- mapping new_mapping;
271-
272266 boost::filesystem::path filename = GetFilenameForChunk (number_of_chunks_);
273267
274268 std::ofstream chunk (filename.string ().c_str (),
@@ -287,16 +281,15 @@ class MemoryMapManager final {
287281 throw memory_map_manager_exception (" failed to create chunk (setting size)" );
288282 }
289283
290- new_mapping.mapping_ =
291- new boost::interprocess::file_mapping (filename.string ().c_str (), boost::interprocess::read_write);
284+ boost::interprocess::file_mapping const mapping (filename.string ().c_str (), boost::interprocess::read_write);
292285
293- new_mapping. region_ =
294- new boost::interprocess::mapped_region (*new_mapping. mapping_ , boost::interprocess::read_write);
286+ boost::interprocess::mapped_region mapped_region (
287+ boost::interprocess::mapped_region (mapping , boost::interprocess::read_write) );
295288
296289 // prevent pre-fetching pages by the OS which does not make sense as values usually fit into few pages
297- new_mapping. region_ -> advise (boost::interprocess::mapped_region::advice_types::advice_random);
290+ mapped_region. advise (boost::interprocess::mapped_region::advice_types::advice_random);
298291
299- mappings_.push_back (new_mapping );
292+ mappings_.push_back (std::move (mapped_region) );
300293 ++number_of_chunks_;
301294 }
302295};
0 commit comments