diff --git a/src/Main.cc b/src/Main.cc index bd6df78e..e1843d7b 100644 --- a/src/Main.cc +++ b/src/Main.cc @@ -2212,7 +2212,7 @@ Action a_find_rare_enemy_seeds( } else if (version == Version::PC_V2) { s->load_patch_indexes(false); } else { - s->clear_map_file_caches(); + s->clear_file_caches(false); } shared_ptr rare_rates; @@ -2281,7 +2281,7 @@ Action a_load_maps_test( using SDT = SetDataTable; auto s = make_shared(get_config_filename(args)); s->load_config_early(); - s->clear_map_file_caches(); + s->clear_file_caches(false); s->load_patch_indexes(false); s->load_set_data_tables(false); s->load_quest_index(false); diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index febef5e7..0e3f8df3 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -3027,8 +3027,8 @@ static void on_D7_GC(shared_ptr c, uint16_t, uint32_t, string& data) { send_command(c, 0xD7, 0x00); } else { try { - static FileContentsCache gba_file_cache(300 * 1000 * 1000); - auto f = gba_file_cache.get_or_load("system/gba/" + filename).file; + auto s = c->require_server_state(); + auto f = s->gba_files_cache->get_or_load("system/gba/" + filename).file; send_open_quest_file(c, "", filename, "", 0, QuestFileType::GBA_DEMO, f->data); } catch (const out_of_range&) { send_command(c, 0xD7, 0x00); diff --git a/src/SendCommands.cc b/src/SendCommands.cc index 3e7c61af..ef6786c5 100644 --- a/src/SendCommands.cc +++ b/src/SendCommands.cc @@ -670,22 +670,15 @@ static const vector stream_file_entries = { "BattleParamEntry_ep4_on.dat", "PlyLevelTbl.prs", }; -static FileContentsCache bb_stream_files_cache(3600000000ULL); void send_stream_file_index_bb(shared_ptr c) { - - struct S_StreamFileIndexEntry_BB_01EB { - le_uint32_t size; - le_uint32_t checksum; // crc32 of file data - le_uint32_t offset; // offset in stream (== sum of all previous files' sizes) - pstring filename; - }; + auto s = c->require_server_state(); vector entries; size_t offset = 0; for (const string& filename : stream_file_entries) { string key = "system/blueburst/" + filename; - auto cache_res = bb_stream_files_cache.get_or_load(key); + auto cache_res = s->bb_stream_files_cache->get_or_load(key); auto& e = entries.emplace_back(); e.size = cache_res.file->data->size(); // Computing the checksum can be slow, so we cache it along with the file @@ -693,12 +686,12 @@ void send_stream_file_index_bb(shared_ptr c) { // so we always recompute the checksum in that case. if (cache_res.generate_called) { e.checksum = crc32(cache_res.file->data->data(), e.size); - bb_stream_files_cache.replace_obj(key + ".crc32", e.checksum); + s->bb_stream_files_cache->replace_obj(key + ".crc32", e.checksum); } else { auto compute_checksum = [&](const string&) -> uint32_t { return crc32(cache_res.file->data->data(), e.size); }; - e.checksum = bb_stream_files_cache.get_obj(key + ".crc32", compute_checksum).obj; + e.checksum = s->bb_stream_files_cache->get_obj(key + ".crc32", compute_checksum).obj; } e.offset = offset; e.filename.encode(filename); @@ -708,17 +701,19 @@ void send_stream_file_index_bb(shared_ptr c) { } void send_stream_file_chunk_bb(shared_ptr c, uint32_t chunk_index) { - auto cache_result = bb_stream_files_cache.get( - "", +[](const string&) -> string { + auto s = c->require_server_state(); + + auto cache_result = s->bb_stream_files_cache->get( + "", [&](const string&) -> string { size_t bytes = 0; for (const auto& name : stream_file_entries) { - bytes += bb_stream_files_cache.get_or_load("system/blueburst/" + name).file->data->size(); + bytes += s->bb_stream_files_cache->get_or_load("system/blueburst/" + name).file->data->size(); } string ret; ret.reserve(bytes); for (const auto& name : stream_file_entries) { - ret += *bb_stream_files_cache.get_or_load("system/blueburst/" + name).file->data; + ret += *s->bb_stream_files_cache->get_or_load("system/blueburst/" + name).file->data; } return ret; }); diff --git a/src/ServerShell.cc b/src/ServerShell.cc index 5a1768c4..6bd32d3a 100644 --- a/src/ServerShell.cc +++ b/src/ServerShell.cc @@ -214,6 +214,7 @@ CommandDefinition c_reload( accounts - reindex user accounts\n\ battle-params - reload the BB enemy stats files\n\ bb-keys - reload BB private keys\n\ + caches - clear all cached files\n\ config - reload most fields from config.json\n\ dol-files - reindex all DOL files\n\ drop-tables - reload drop tables\n\ @@ -244,6 +245,8 @@ CommandDefinition c_reload( args.s->load_bb_private_keys(true); } else if (type == "accounts") { args.s->load_accounts(true); + } else if (type == "caches") { + args.s->clear_file_caches(true); } else if (type == "patch-files") { args.s->load_patch_indexes(true); } else if (type == "ep3-cards") { diff --git a/src/ServerState.cc b/src/ServerState.cc index 67c532d3..39442aa8 100644 --- a/src/ServerState.cc +++ b/src/ServerState.cc @@ -44,6 +44,9 @@ ServerState::ServerState(shared_ptr base, const string& confi base(base), config_filename(config_filename), is_replay(is_replay), + bb_stream_files_cache(new FileContentsCache(3600000000ULL)), + bb_system_cache(new FileContentsCache(3600000000ULL)), + gba_files_cache(new FileContentsCache(3600000000ULL)), player_files_manager(this->base ? make_shared(base) : nullptr), destroy_lobbies_event(this->base ? event_new(base.get(), -1, EV_TIMEOUT, &ServerState::dispatch_destroy_lobbies, this) : nullptr, event_free) {} @@ -523,9 +526,8 @@ shared_ptr ServerState::load_bb_file( // Finally, look in system/blueburst const string& effective_bb_directory_filename = bb_directory_filename.empty() ? patch_index_filename : bb_directory_filename; - static FileContentsCache cache(10 * 60 * 1000 * 1000); // 10 minutes try { - auto ret = cache.get_or_load("system/blueburst/" + effective_bb_directory_filename); + auto ret = this->bb_system_cache->get_or_load("system/blueburst/" + effective_bb_directory_filename); return ret.file->data; } catch (const exception& e) { throw phosg::cannot_open_file(patch_index_filename); @@ -1465,11 +1467,20 @@ void ServerState::load_patch_indexes(bool from_non_event_thread) { this->forward_or_call(from_non_event_thread, std::move(set)); } -void ServerState::clear_map_file_caches() { - config_log.info("Clearing map file caches"); - for (auto& cache : this->map_file_caches) { - cache = make_shared(); - } +void ServerState::clear_file_caches(bool from_non_event_thread) { + auto set = [s = this->shared_from_this()]() { + config_log.info("Clearing map file caches"); + for (auto& cache : s->map_file_caches) { + cache = make_shared(); + } + config_log.info("Clearing BB stream file cache"); + s->bb_stream_files_cache.reset(new FileContentsCache(3600000000ULL)); + config_log.info("Clearing BB system cache"); + s->bb_system_cache.reset(new FileContentsCache(3600000000ULL)); + config_log.info("Clearing GBA file cache"); + s->gba_files_cache.reset(new FileContentsCache(300 * 1000 * 1000)); + }; + this->forward_or_call(from_non_event_thread, std::move(set)); } void ServerState::load_set_data_tables(bool from_non_event_thread) { @@ -1956,7 +1967,7 @@ void ServerState::load_all() { this->load_bb_private_keys(false); this->load_bb_system_defaults(false); this->load_accounts(false); - this->clear_map_file_caches(); + this->clear_file_caches(false); this->load_patch_indexes(false); this->load_ep3_cards(false); this->load_ep3_maps(false); diff --git a/src/ServerState.hh b/src/ServerState.hh index 218c93fd..5b3ff91c 100644 --- a/src/ServerState.hh +++ b/src/ServerState.hh @@ -151,6 +151,9 @@ struct ServerState : public std::enable_shared_from_this { std::shared_ptr pc_patch_file_index; std::shared_ptr bb_patch_file_index; std::array, NUM_VERSIONS> map_file_caches; + std::shared_ptr bb_stream_files_cache; + std::shared_ptr bb_system_cache; + std::shared_ptr gba_files_cache; std::shared_ptr dol_file_index; std::shared_ptr ep3_card_index; std::shared_ptr ep3_card_index_trial; @@ -386,7 +389,7 @@ struct ServerState : public std::enable_shared_from_this { void load_accounts(bool from_non_event_thread); void load_teams(bool from_non_event_thread); void load_patch_indexes(bool from_non_event_thread); - void clear_map_file_caches(); + void clear_file_caches(bool from_non_event_thread); void load_battle_params(bool from_non_event_thread); void load_level_tables(bool from_non_event_thread); void load_text_index(bool from_non_event_thread);