54 _data_file_path(
bfs::absolute(dir/
"shared_memory.bin")),
55 _database_name(dir.filename().string()),
58 if(shared_file_size % _db_size_multiple_requirement) {
59 std::string what_str(
"Database must be mulitple of " + std::to_string(_db_size_multiple_requirement) +
" bytes");
66 if(!_writable && !bfs::exists(_data_file_path)){
67 std::string what_str(
"database file not found at " + _data_file_path.string());
71 bfs::create_directories(dir);
73 if(bfs::exists(_data_file_path)) {
75 std::ifstream hs(_data_file_path.generic_string(), std::ifstream::binary);
82 std::string what_str(
"\"" + _database_name +
"\" database format not compatible with this version of chainbase.");
85 if(!allow_dirty && dbheader->
dirty) {
86 std::string what_str(
"\"" + _database_name +
"\" database dirty flag set");
90 std::cerr <<
"CHAINBASE: \"" << _database_name <<
"\" database was created with a chainbase from a different environment" << std::endl;
91 std::cerr <<
"Current compiler environment:" << std::endl;
93 std::cerr <<
"DB created with compiler environment:" << std::endl;
100 if(!bfs::exists(_data_file_path)) {
101 std::ofstream ofs(_data_file_path.generic_string(), std::ofstream::trunc);
104 bfs::resize_file(_data_file_path, shared_file_size);
105 _file_mapping = bip::file_mapping(_data_file_path.generic_string().c_str(), bip::read_write);
106 _file_mapped_region = bip::mapped_region(_file_mapping, bip::read_write);
108 new (_file_mapped_region.get_address())
db_header;
111 auto existing_file_size = bfs::file_size(_data_file_path);
113 if(shared_file_size > existing_file_size) {
114 grow = shared_file_size - existing_file_size;
115 bfs::resize_file(_data_file_path, shared_file_size);
117 else if(shared_file_size < existing_file_size) {
118 std::cerr <<
"CHAINBASE: \"" << _database_name <<
"\" requested size of " << shared_file_size <<
" is less than "
119 "existing size of " << existing_file_size <<
". This database will not be shrunk and will "
120 "remain at " << existing_file_size << std::endl;
122 _file_mapping = bip::file_mapping(_data_file_path.generic_string().c_str(), bip::read_write);
123 _file_mapped_region = bip::mapped_region(_file_mapping, bip::read_write);
126 file_mapped_segment_manager->grow(grow);
129 _file_mapping = bip::file_mapping(_data_file_path.generic_string().c_str(), bip::read_only);
130 _file_mapped_region = bip::mapped_region(_file_mapping, bip::read_only);
136 boost::system::error_code ec;
137 bfs::remove(bfs::absolute(dir/
"shared_memory.meta"), ec);
139 _mapped_file_lock = bip::file_lock(_data_file_path.generic_string().c_str());
140 if(!_mapped_file_lock.try_lock())
143 set_mapped_file_db_dirty(
true);
147 _segment_manager = file_mapped_segment_manager;
150 boost::asio::io_service sig_ios;
151 boost::asio::signal_set sig_set(sig_ios, SIGINT, SIGTERM);
153 sig_set.add(SIGPIPE);
155 sig_set.async_wait([](
const boost::system::error_code&,
int) {
160 setup_non_file_mapping();
161 load_database_file(sig_ios);
165 if(mlock(_non_file_mapped_mapping, _non_file_mapped_mapping_size)) {
166 std::string what_str(
"Failed to mlock database \"" + _database_name +
"\"");
169 std::cerr <<
"CHAINBASE: Database \"" << _database_name <<
"\" has been successfully locked in memory" << std::endl;
173 _file_mapped_region = bip::mapped_region();
177 set_mapped_file_db_dirty(
false);