#include "./chunk_picker_systems.hpp" #include #include "./components.hpp" #include "./chunk_picker.hpp" #include "./contact_components.hpp" #include #include namespace Systems { void chunk_picker_updates( Contact3Registry& cr, ObjectRegistry& os_reg, const entt::dense_map& peer_open_requests, const ReceivingTransfers& receiving_transfers, NGCFT1& nft, // TODO: remove this somehow const float delta ) { std::vector cp_to_remove; // first, update timers cr.view().each([&cr, delta](const Contact3 cv, ChunkPickerTimer& cpt) { cpt.timer -= delta; if (cpt.timer <= 0.f) { cr.emplace_or_replace(cv); } }); //std::cout << "number of chunkpickers: " << _cr.storage().size() << ", of which " << _cr.storage().size() << " need updating\n"; // now check for potentially missing cp auto cput_view = cr.view(); cput_view.each([&cr, &cp_to_remove](const Contact3 cv) { Contact3Handle c{cr, cv}; //std::cout << "cput :)\n"; if (!c.any_of()) { std::cout << "cput uh nuh :(\n"; cp_to_remove.push_back(c); return; } if (!c.all_of()) { std::cout << "creating new cp!!\n"; c.emplace(); c.emplace_or_replace(); } }); // now update all cp that are tagged cr.view().each([&cr, &os_reg, &peer_open_requests, &receiving_transfers, &nft, &cp_to_remove](const Contact3 cv, ChunkPicker& cp) { Contact3Handle c{cr, cv}; if (!c.all_of()) { cp_to_remove.push_back(c); return; } //std::cout << "cpu :)\n"; // HACK: expensive, dont do every tick, only on events // do verification in debug instead? //cp.validateParticipation(c, _os.registry()); size_t peer_open_request = 0; if (peer_open_requests.contains(c)) { peer_open_request += peer_open_requests.at(c); } auto new_requests = cp.updateChunkRequests( c, os_reg, receiving_transfers, peer_open_request ); if (new_requests.empty()) { // updateChunkRequests updates the unfinished // TODO: pull out and check there? if (cp.participating_unfinished.empty()) { std::cout << "destroying empty useless cp\n"; cp_to_remove.push_back(c); } else { // most likely will have something soon // TODO: mark dirty on have instead? c.get_or_emplace().timer = 10.f; } return; } assert(c.all_of()); const auto [group_number, peer_number] = c.get(); for (const auto [r_o, r_idx] : new_requests) { auto& cc = r_o.get(); const auto& info = r_o.get(); // request chunk_idx nft.NGC_FT1_send_request_private( group_number, peer_number, static_cast(NGCFT1_file_kind::HASH_SHA1_CHUNK), info.chunks.at(r_idx).data.data(), info.chunks.at(r_idx).size() ); std::cout << "SHA1_NGCFT1: requesting chunk [" << info.chunks.at(r_idx) << "] from " << group_number << ":" << peer_number << "\n"; } // force update every minute // TODO: add small random bias to spread load c.get_or_emplace().timer = 60.f; }); // unmark all marked cr.clear(); assert(cr.storage().empty()); for (const auto& c : cp_to_remove) { c.remove(); } } } // Systems