#pragma once #include #include #include #include #include #include #include "../Aircraft/Aircraft.h" #include "../Aircraft/Flight_VTO.h" #include "../External_Database/export.h" #include "Base_Station.h" #include "Local_Server/server/With_Loop_Coro.h" template < typename Key_Type, typename Value_Type, size_t Shard_Count = 64 > struct Data_Map { using Ptr = std::shared_ptr; size_t size() const { size_t ret = 0; for (const auto& shard : shards) { std::shared_lock g(shard.mtx); ret += shard.map.size(); } return ret; } Ptr get(const Key_Type& key) const { const auto& shard = get_shard(key); std::shared_lock g(shard.mtx); auto iter = shard.map.find(key); if (iter == shard.map.end()) { return nullptr; } return iter->second; } Ptr create(const Key_Type& key) { auto& shard = get_shard(key); { std::shared_lock g(shard.mtx); auto iter = shard.map.find(key); if (iter != shard.map.end()) { return iter->second; } } // 构造对象放锁外,避免构造期间占锁 auto new_value = std::make_shared(key); { std::unique_lock g(shard.mtx); auto [iter, inserted] = shard.map.emplace(key, new_value); // 如果别的线程已经创建了,返回已有对象 return iter->second; } } void remove(const Key_Type& key) { auto& shard = get_shard(key); std::unique_lock g(shard.mtx); shard.map.erase(key); } std::vector values() const { std::vector ret; for (const auto& shard : shards) { std::shared_lock g(shard.mtx); for (const auto& [key, val] : shard.map) { ret.push_back(val); } } return ret; } template std::vector get_cond(Cond&& cond) const { std::vector ret; for (const auto& shard : shards) { std::vector snapshot; { std::shared_lock g(shard.mtx); snapshot.reserve(shard.map.size()); for (const auto& [key, val] : shard.map) { snapshot.push_back(val); } } // cond 放锁外执行 for (const auto& val : snapshot) { if (cond(val)) { ret.push_back(val); } } } return ret; } template void remove_cond(Cond&& cond) { for (auto& shard : shards) { std::vector> snapshot; { std::shared_lock g(shard.mtx); snapshot.reserve(shard.map.size()); for (const auto& [key, val] : shard.map) { snapshot.emplace_back(key, val); } } std::vector> need_remove; // cond 放锁外执行 for (const auto& [key, val] : snapshot) { if (cond(val)) { need_remove.emplace_back(key, val); } } if (need_remove.empty()) { continue; } { std::unique_lock g(shard.mtx); for (const auto& [key, old_val] : need_remove) { auto iter = shard.map.find(key); if (iter == shard.map.end()) { continue; } // 防止同 key 已经被换成新对象,误删 if (iter->second == old_val) { shard.map.erase(iter); } } } } } void delete_all() { for (auto& shard : shards) { std::unique_lock g(shard.mtx); shard.map.clear(); } } protected: struct Shard { mutable std::shared_mutex mtx; std::unordered_map map; }; Shard& get_shard(const Key_Type& key) { const size_t index = hasher(key) % Shard_Count; return shards[index]; } const Shard& get_shard(const Key_Type& key) const { const size_t index = hasher(key) % Shard_Count; return shards[index]; } protected: std::hash hasher; Shard shards[Shard_Count]; }; class DataBase : public SSR::Data_Source_Interface, public With_Loop_Coro { public: std::shared_ptr get_aircraft(std::string_view icao) override; std::shared_ptr create_aircraft(std::string_view icao) override; Psc::JSON get_aircraftlist(); Psc::JSON get_aircraftlist(int limit_msg_num); Base_Station base_station; void delete_timeout_aircraft(); std::string get_key() override { return key; } std::atomic have_pos_aircraft_num{}; Psc::JSON get_all_aircraft_json(); std::vector> get_visible_aircraft_snapshot(); std::uint64_t aircraft_change_version(SSR::Aircraft_Info* info); Psc::JSON aircraft_change_item_json(SSR::Aircraft_Info* info); Psc::JSON get_aircraft_change_update_json(std::unordered_map& client_versions); Psc::JSON get_aircraft_list_after(time_t timestamp); #ifdef Cache_Some_Mode_S Psc::JSON get_limit_mode_s_msg_info(); #endif size_t get_aircraft_num(); void clear_aircraft() { aircraft_map.delete_all(); } ~DataBase() override { aircraft_map.delete_all(); } protected: Data_Map aircraft_map; }; struct Mode_S_Msg; void database_server(Global* g);