diff --git a/src/sha1_ngcft1.cpp b/src/sha1_ngcft1.cpp index aa364cd..94ee72a 100644 --- a/src/sha1_ngcft1.cpp +++ b/src/sha1_ngcft1.cpp @@ -335,21 +335,39 @@ void SHA1_NGCFT1::iterate(float delta) { auto chunk_idx_opt = ce.get().chunkIndex(chunk_hash); if (chunk_idx_opt.has_value()) { - const auto& info = ce.get(); - uint8_t transfer_id {0}; - if (_nft.NGC_FT1_send_init_private( - group_number, peer_number, - static_cast(NGCFT1_file_kind::HASH_SHA1_CHUNK), - chunk_hash.data.data(), chunk_hash.size(), - chunkSize(info, chunk_idx_opt.value()), - &transfer_id - )) { - _sending_transfers - [combineIds(group_number, peer_number)] - [transfer_id] // TODO: also save index? - .v = SendingTransfer::Chunk{ce, chunk_idx_opt.value() * info.chunk_size}; + // check if already sending + bool already_sending_to_this_peer = false; + if (_sending_transfers.count(combineIds(group_number, peer_number))) { + for (const auto& [_2, t] : _sending_transfers.at(combineIds(group_number, peer_number))) { + if (std::holds_alternative(t.v)) { + const auto& v = std::get(t.v); + if (v.content == ce && v.chunk_index == chunk_idx_opt.value()) { + // already sending + already_sending_to_this_peer = true; + break; + } + } + } } + + if (!already_sending_to_this_peer) { + const auto& info = ce.get(); + + uint8_t transfer_id {0}; + if (_nft.NGC_FT1_send_init_private( + group_number, peer_number, + static_cast(NGCFT1_file_kind::HASH_SHA1_CHUNK), + chunk_hash.data.data(), chunk_hash.size(), + chunkSize(info, chunk_idx_opt.value()), + &transfer_id + )) { + _sending_transfers + [combineIds(group_number, peer_number)] + [transfer_id] // TODO: also save index? + .v = SendingTransfer::Chunk{ce, chunk_idx_opt.value()}; + } + } // else just remove from queue } // remove from queue regardless _queue_requested_chunk.pop_front(); @@ -640,14 +658,14 @@ bool SHA1_NGCFT1::onEvent(const Events::NGCFT1_recv_init& e) { assert(idx_opt.has_value()); const auto& info = ce.get(); - uint64_t offset_into_file = uint64_t(info.chunk_size) * idx_opt.value(); // TODO: check e.file_size + assert(e.file_size == info.chunkSize(idx_opt.value())); _receiving_transfers [combineIds(e.group_number, e.peer_number)] [e.transfer_id] - .v = ReceivingTransfer::Chunk{ce, offset_into_file}; + .v = ReceivingTransfer::Chunk{ce, idx_opt.value()}; e.accept = true; @@ -676,8 +694,8 @@ bool SHA1_NGCFT1::onEvent(const Events::NGCFT1_recv_data& e) { info_data[i+e.data_offset] = e.data[i]; } } else if (std::holds_alternative(tv)) { - const auto offset_into_file = std::get(tv).offset_into_file; auto ce = std::get(tv).content; + const auto offset_into_file = std::get(tv).chunk_index * ce.get().chunk_size; assert(ce.all_of()); auto* file = ce.get().get(); @@ -717,8 +735,9 @@ bool SHA1_NGCFT1::onEvent(const Events::NGCFT1_send_data& e) { } } else if (std::holds_alternative(transfer.v)) { auto& chunk_transfer = std::get(transfer.v); + const auto& info = chunk_transfer.content.get(); // TODO: should we really use file? - const auto data = chunk_transfer.content.get()->read(chunk_transfer.offset_into_file + e.data_offset, e.data_size); + const auto data = chunk_transfer.content.get()->read((chunk_transfer.chunk_index * info.chunk_size) + e.data_offset, e.data_size); // TODO: optimize for (size_t i = 0; i < e.data_size && i < data.size(); i++) { @@ -796,12 +815,12 @@ bool SHA1_NGCFT1::onEvent(const Events::NGCFT1_recv_done& e) { updateMessages(ce); } else if (std::holds_alternative(tv)) { - const auto offset_into_file = std::get(tv).offset_into_file; auto ce = std::get(tv).content; const auto& info = ce.get(); auto& cc = ce.get(); + const auto chunk_index = std::get(tv).chunk_index; + const auto offset_into_file = chunk_index * info.chunk_size; - const auto chunk_index = offset_into_file/info.chunk_size; assert(chunk_index < info.chunks.size()); const auto chunk_size = info.chunkSize(chunk_index); assert(offset_into_file+chunk_size <= info.file_size); diff --git a/src/sha1_ngcft1.hpp b/src/sha1_ngcft1.hpp index bfd74c9..74eb555 100644 --- a/src/sha1_ngcft1.hpp +++ b/src/sha1_ngcft1.hpp @@ -53,7 +53,8 @@ class SHA1_NGCFT1 : public RegistryMessageModelEventI, public NGCFT1EventI { struct Chunk { ContentHandle content; - uint64_t offset_into_file; + size_t chunk_index; // <.< remove offset_into_file + //uint64_t offset_into_file; // or data? // if memmapped, this would be just a pointer }; @@ -75,7 +76,8 @@ class SHA1_NGCFT1 : public RegistryMessageModelEventI, public NGCFT1EventI { struct Chunk { ContentHandle content; - uint64_t offset_into_file; + size_t chunk_index; + //uint64_t offset_into_file; // or data? // if memmapped, this would be just a pointer };