1 /* 2 * This code is (c) 2012 Johannes Thoma 3 * 4 * modified 2018 by D. Mitch Bailey 5 * 6 * This file is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU Lesser General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * This file is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this file. If not, see <http://www.gnu.org/licenses/>. 18 * 19 * You can download original source from https://github.com/johannesthoma/mmap_allocator.git 20 */ 21 22 #ifndef _MMAP_ALLOCATOR_H 23 #define _MMAP_ALLOCATOR_H 24 25 #include <memory> 26 #include <string> 27 #include <stdio.h> 28 #include <vector> 29 #include "mmap_access_mode.h" 30 #include "mmap_exception.h" 31 #include "mmap_file_pool.h" 32 33 namespace mmap_allocator_namespace 34 { 35 template <typename T> 36 class mmap_allocator; // required forward declaration for following default 37 template <typename T, typename A = mmap_allocator<T> > 38 class mmappable_vector; 39 40 template <typename T> 41 class mmap_allocator: public std::allocator<T> 42 { 43 public: 44 typedef size_t size_type; 45 typedef off_t offset_type; 46 typedef T* pointer; 47 typedef const T* const_pointer; 48 49 template<typename _Tp1> 50 struct rebind 51 { 52 typedef mmap_allocator<_Tp1> other; 53 }; 54 55 pointer allocate(size_type n, const void *hint=0) 56 { 57 void *the_pointer; 58 if (get_verbosity() > 0) { 59 fprintf(stderr, "Alloc %zd bytes.\n", n*sizeof(T)); 60 } 61 if (access_mode == DEFAULT_STL_ALLOCATOR) { 62 return std::allocator<T>::allocate(n, hint); 63 } else { 64 if (n == 0) { 65 return NULL; 66 } 67 if (bypass_file_pool) { 68 the_pointer = private_file.open_and_mmap_file(filename, access_mode, offset, n*sizeof(T), map_whole_file, allow_remap); 69 } else { 70 the_pointer = the_pool.mmap_file(filename, access_mode, offset, n*sizeof(T), map_whole_file, allow_remap); 71 } 72 if (the_pointer == NULL) { 73 throw(mmap_allocator_exception("Couldn't mmap file, mmap_file returned NULL")); 74 } 75 if (get_verbosity() > 0) { 76 fprintf(stderr, "pointer = %p\n", the_pointer); 77 } 78 79 return (pointer)the_pointer; 80 } 81 } 82 deallocate(pointer p,size_type n)83 void deallocate(pointer p, size_type n) 84 { 85 if (get_verbosity() > 0) { 86 fprintf(stderr, "Dealloc %zd bytes (%p).\n", n*sizeof(T), p); 87 } 88 if (access_mode == DEFAULT_STL_ALLOCATOR) { 89 std::allocator<T>::deallocate(p, n); 90 } else { 91 if (n == 0) { 92 return; 93 } 94 if (bypass_file_pool) { 95 private_file.munmap_and_close_file(); 96 } else { 97 if (!keep_forever) { 98 the_pool.munmap_file(filename, access_mode, offset, n*sizeof(T)); 99 } 100 } 101 } 102 } 103 throw()104 mmap_allocator() throw(): 105 std::allocator<T>(), 106 filename(""), 107 offset(0), 108 access_mode(DEFAULT_STL_ALLOCATOR), 109 map_whole_file(false), 110 allow_remap(false), 111 bypass_file_pool(false), 112 private_file(), 113 keep_forever(false) 114 { } 115 throw()116 mmap_allocator(const std::allocator<T> &a) throw(): 117 std::allocator<T>(a), 118 filename(""), 119 offset(0), 120 access_mode(DEFAULT_STL_ALLOCATOR), 121 map_whole_file(false), 122 allow_remap(false), 123 bypass_file_pool(false), 124 private_file(), 125 keep_forever(false) 126 { } 127 throw()128 mmap_allocator(const mmap_allocator &a) throw(): 129 std::allocator<T>(a), 130 filename(a.filename), 131 offset(a.offset), 132 access_mode(a.access_mode), 133 map_whole_file(a.map_whole_file), 134 allow_remap(a.allow_remap), 135 bypass_file_pool(a.bypass_file_pool), 136 private_file(a.private_file), 137 keep_forever(a.keep_forever) 138 { } throw()139 mmap_allocator(const std::string filename_param, enum access_mode access_mode_param = READ_ONLY, offset_type offset_param = 0, int flags = 0) throw(): 140 std::allocator<T>(), 141 filename(filename_param), 142 offset(offset_param), 143 access_mode(access_mode_param), 144 map_whole_file((flags & MAP_WHOLE_FILE) != 0), 145 allow_remap((flags & ALLOW_REMAP) != 0), 146 bypass_file_pool((flags & BYPASS_FILE_POOL) != 0), 147 private_file(), 148 keep_forever((flags & KEEP_FOREVER) != 0) 149 { 150 } 151 throw()152 ~mmap_allocator() throw() { } 153 154 private: 155 friend class mmappable_vector<T, mmap_allocator<T> >; 156 157 std::string filename; 158 offset_type offset; 159 enum access_mode access_mode; 160 bool map_whole_file; 161 bool allow_remap; 162 bool bypass_file_pool; 163 mmapped_file private_file; /* used if bypass is set */ 164 bool keep_forever; 165 }; 166 } 167 168 #endif /* _MMAP_ALLOCATOR_H */ 169