diff --git a/CMakeLists.txt b/CMakeLists.txt index 60c0fe6..ddf7192 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,5 +65,6 @@ target_link_libraries(solanaceae_sha1_ngcft1 PUBLIC sha1::sha1 solanaceae_tox_contacts solanaceae_message3 + solanaceae_object_store ) diff --git a/solanaceae/ngc_ft1_sha1/sha1_ngcft1.cpp b/solanaceae/ngc_ft1_sha1/sha1_ngcft1.cpp index 5e7b070..6adad5c 100644 --- a/solanaceae/ngc_ft1_sha1/sha1_ngcft1.cpp +++ b/solanaceae/ngc_ft1_sha1/sha1_ngcft1.cpp @@ -26,11 +26,11 @@ namespace Message::Components { - using Content = ContentHandle; + using Content = ObjectHandle; } // Message::Components -// TODO: rename to content components +// TODO: rename to object components namespace Components { struct Messages { @@ -112,7 +112,7 @@ static size_t chunkSize(const FT1InfoSHA1& sha1_info, size_t chunk_index) { } } -void SHA1_NGCFT1::queueUpRequestChunk(uint32_t group_number, uint32_t peer_number, ContentHandle content, const SHA1Digest& hash) { +void SHA1_NGCFT1::queueUpRequestChunk(uint32_t group_number, uint32_t peer_number, ObjectHandle content, const SHA1Digest& hash) { for (auto& [i_g, i_p, i_m, i_h, i_t] : _queue_requested_chunk) { // if already in queue if (i_g == group_number && i_p == peer_number && i_h == hash) { @@ -156,7 +156,7 @@ uint64_t SHA1_NGCFT1::combineIds(const uint32_t group_number, const uint32_t pee return (uint64_t(group_number) << 32) | peer_number; } -void SHA1_NGCFT1::updateMessages(ContentHandle ce) { +void SHA1_NGCFT1::updateMessages(ObjectHandle ce) { assert(ce.all_of()); for (auto msg : ce.get().messages) { @@ -185,7 +185,7 @@ void SHA1_NGCFT1::updateMessages(ContentHandle ce) { } } -std::optional> SHA1_NGCFT1::selectPeerForRequest(ContentHandle ce) { +std::optional> SHA1_NGCFT1::selectPeerForRequest(ObjectHandle ce) { // get a list of peers we can request this file from // TODO: randomly request from non SuspectedParticipants std::vector> tox_peers; @@ -248,11 +248,13 @@ std::optional> SHA1_NGCFT1::selectPeerForRequest(C } SHA1_NGCFT1::SHA1_NGCFT1( + ObjectStore2& os, Contact3Registry& cr, RegistryMessageModel& rmm, NGCFT1& nft, ToxContactModel2& tcm ) : + _os(os), _cr(cr), _rmm(rmm), _nft(nft), @@ -350,8 +352,8 @@ void SHA1_NGCFT1::iterate(float delta) { } { // requested info timers - std::vector timed_out; - _contentr.view().each([delta, &timed_out](Content e, Components::ReRequestInfoTimer& rrit) { + std::vector timed_out; + _os.registry().view().each([delta, &timed_out](Object e, Components::ReRequestInfoTimer& rrit) { rrit.timer += delta; // 15sec, TODO: config @@ -361,12 +363,13 @@ void SHA1_NGCFT1::iterate(float delta) { }); for (const auto e : timed_out) { // TODO: avoid dups - _queue_content_want_info.push_back({_contentr, e}); - _contentr.remove(e); + _queue_content_want_info.push_back(_os.objectHandle(e)); + _os.registry().remove(e); + // TODO: throw update? } } { // requested chunk timers - _contentr.view().each([delta](Components::FT1ChunkSHA1Requested& ftchunk_requested) { + _os.registry().view().each([delta](Components::FT1ChunkSHA1Requested& ftchunk_requested) { for (auto it = ftchunk_requested.chunks.begin(); it != ftchunk_requested.chunks.end();) { it->second += delta; @@ -1087,12 +1090,13 @@ bool SHA1_NGCFT1::onEvent(const Events::NGCFT1_recv_message& e) { // check if content exists const auto sha1_info_hash = std::vector{e.file_id, e.file_id+e.file_id_size}; - ContentHandle ce; + ObjectHandle ce; if (_info_to_content.count(sha1_info_hash)) { ce = _info_to_content.at(sha1_info_hash); std::cout << "SHA1_NGCFT1: new message has existing content\n"; } else { - ce = {_contentr, _contentr.create()}; + // TODO: backend + ce = {_os.registry(), _os.registry().create()}; _info_to_content[sha1_info_hash] = ce; std::cout << "SHA1_NGCFT1: new message has new content\n"; @@ -1249,7 +1253,7 @@ bool SHA1_NGCFT1::sendFilePath(const Contact3 c, std::string_view file_name, std std::cout << "SHA1_NGCFT1 sha1_info_hash: " << bin2hex(sha1_info_hash) << "\n"; // check if content exists - ContentHandle ce; + ObjectHandle ce; if (self->_info_to_content.count(sha1_info_hash)) { ce = self->_info_to_content.at(sha1_info_hash); @@ -1318,7 +1322,8 @@ bool SHA1_NGCFT1::sendFilePath(const Contact3 c, std::string_view file_name, std it = self->_queue_content_want_chunk.erase(it); } } else { - ce = {self->_contentr, self->_contentr.create()}; + // TODO: backend + ce = {self->_os.registry(), self->_os.registry().create()}; self->_info_to_content[sha1_info_hash] = ce; ce.emplace(sha1_info); diff --git a/solanaceae/ngc_ft1_sha1/sha1_ngcft1.hpp b/solanaceae/ngc_ft1_sha1/sha1_ngcft1.hpp index 0e725bb..87f058c 100644 --- a/solanaceae/ngc_ft1_sha1/sha1_ngcft1.hpp +++ b/solanaceae/ngc_ft1_sha1/sha1_ngcft1.hpp @@ -2,6 +2,7 @@ // solanaceae port of sha1 fts for NGCFT1 +#include #include #include #include @@ -20,11 +21,9 @@ #include #include -enum class Content : uint32_t {}; -using ContentRegistry = entt::basic_registry; -using ContentHandle = entt::basic_handle; - class SHA1_NGCFT1 : public RegistryMessageModelEventI, public NGCFT1EventI { + ObjectStore2& _os; + // TODO: backend abstraction Contact3Registry& _cr; RegistryMessageModel& _rmm; NGCFT1& _nft; @@ -32,21 +31,18 @@ class SHA1_NGCFT1 : public RegistryMessageModelEventI, public NGCFT1EventI { std::minstd_rand _rng {1337*11}; - // registry per group? - ContentRegistry _contentr; - // limit this to each group? - entt::dense_map _info_to_content; + entt::dense_map _info_to_content; // sha1 chunk index // TODO: optimize lookup // TODO: multiple contents. hashes might be unique, but data is not - entt::dense_map _chunks; + entt::dense_map _chunks; // group_number, peer_number, content, chunk_hash, timer - std::deque> _queue_requested_chunk; + std::deque> _queue_requested_chunk; //void queueUpRequestInfo(uint32_t group_number, uint32_t peer_number, const SHA1Digest& hash); - void queueUpRequestChunk(uint32_t group_number, uint32_t peer_number, ContentHandle content, const SHA1Digest& hash); + void queueUpRequestChunk(uint32_t group_number, uint32_t peer_number, ObjectHandle content, const SHA1Digest& hash); struct SendingTransfer { struct Info { @@ -56,7 +52,7 @@ class SHA1_NGCFT1 : public RegistryMessageModelEventI, public NGCFT1EventI { }; struct Chunk { - ContentHandle content; + ObjectHandle content; size_t chunk_index; // <.< remove offset_into_file //uint64_t offset_into_file; // or data? @@ -72,14 +68,14 @@ class SHA1_NGCFT1 : public RegistryMessageModelEventI, public NGCFT1EventI { struct ReceivingTransfer { struct Info { - ContentHandle content; + ObjectHandle content; // copy of info data // too large? std::vector info_data; }; struct Chunk { - ContentHandle content; + ObjectHandle content; std::vector chunk_indices; // or data? // if memmapped, this would be just a pointer @@ -93,8 +89,8 @@ class SHA1_NGCFT1 : public RegistryMessageModelEventI, public NGCFT1EventI { entt::dense_map> _receiving_transfers; // makes request rotate around open content - std::deque _queue_content_want_info; - std::deque _queue_content_want_chunk; + std::deque _queue_content_want_info; + std::deque _queue_content_want_chunk; std::atomic_bool _info_builder_dirty {false}; std::mutex _info_builder_queue_mutex; @@ -108,9 +104,9 @@ class SHA1_NGCFT1 : public RegistryMessageModelEventI, public NGCFT1EventI { static uint64_t combineIds(const uint32_t group_number, const uint32_t peer_number); - void updateMessages(ContentHandle ce); + void updateMessages(ObjectHandle ce); - std::optional> selectPeerForRequest(ContentHandle ce); + std::optional> selectPeerForRequest(ObjectHandle ce); public: // TODO: config bool _udp_only {false}; @@ -122,6 +118,7 @@ class SHA1_NGCFT1 : public RegistryMessageModelEventI, public NGCFT1EventI { public: SHA1_NGCFT1( + ObjectStore2& os, Contact3Registry& cr, RegistryMessageModel& rmm, NGCFT1& nft,