Inline FileDownloader::init.
This commit is contained in:
parent
cd33aa82cc
commit
6564c43d58
@ -51,75 +51,6 @@ FileDownloader::FileDownloader(const FullRemoteFileLocation &remote, const Local
|
||||
}
|
||||
}
|
||||
|
||||
Result<FileDownloader::FileInfo> FileDownloader::init() {
|
||||
SCOPE_EXIT {
|
||||
try_release_fd();
|
||||
};
|
||||
if (local_.type() == LocalFileLocation::Type::Full) {
|
||||
return Status::Error("File is already downloaded");
|
||||
}
|
||||
if (encryption_key_.is_secure() && !encryption_key_.has_value_hash()) {
|
||||
LOG(ERROR) << "Can't download Secure file with unknown value_hash";
|
||||
}
|
||||
if (remote_.file_type_ == FileType::SecureEncrypted) {
|
||||
size_ = 0;
|
||||
}
|
||||
int32 part_size = 0;
|
||||
Bitmask bitmask{Bitmask::Ones{}, 0};
|
||||
if (local_.type() == LocalFileLocation::Type::Partial) {
|
||||
const auto &partial = local_.partial();
|
||||
path_ = partial.path_;
|
||||
auto result_fd = FileFd::open(path_, FileFd::Write | FileFd::Read);
|
||||
// TODO: check timestamps..
|
||||
if (result_fd.is_ok()) {
|
||||
if ((!encryption_key_.is_secret() || partial.iv_.size() == 32) && partial.part_size_ >= 0 &&
|
||||
partial.part_size_ <= (1 << 20) && (partial.part_size_ & (partial.part_size_ - 1)) == 0) {
|
||||
bitmask = Bitmask(Bitmask::Decode{}, partial.ready_bitmask_);
|
||||
if (encryption_key_.is_secret()) {
|
||||
encryption_key_.mutable_iv() = as<UInt256>(partial.iv_.data());
|
||||
next_part_ = narrow_cast<int32>(bitmask.get_ready_parts(0));
|
||||
}
|
||||
fd_ = result_fd.move_as_ok();
|
||||
part_size = static_cast<int32>(partial.part_size_);
|
||||
} else {
|
||||
LOG(ERROR) << "Have invalid " << partial;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (need_search_file_ && fd_.empty() && size_ > 0 && encryption_key_.empty() && !remote_.is_web()) {
|
||||
auto r_path = search_file(remote_.file_type_, name_, size_);
|
||||
if (r_path.is_ok()) {
|
||||
auto r_fd = FileFd::open(r_path.ok(), FileFd::Read);
|
||||
if (r_fd.is_ok()) {
|
||||
path_ = r_path.move_as_ok();
|
||||
fd_ = r_fd.move_as_ok();
|
||||
need_check_ = true;
|
||||
only_check_ = true;
|
||||
part_size = 128 * (1 << 10);
|
||||
bitmask = Bitmask{Bitmask::Ones{}, (size_ + part_size - 1) / part_size};
|
||||
LOG(INFO) << "Check hash of local file " << path_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FileInfo res;
|
||||
res.size = size_;
|
||||
res.is_size_final = true;
|
||||
res.part_size = part_size;
|
||||
res.ready_parts = bitmask.as_vector();
|
||||
res.use_part_count_limit = false;
|
||||
res.only_check = only_check_;
|
||||
auto file_type = get_main_file_type(remote_.file_type_);
|
||||
res.need_delay =
|
||||
!is_small_ &&
|
||||
(file_type == FileType::VideoNote || file_type == FileType::Document || file_type == FileType::VoiceNote ||
|
||||
file_type == FileType::Audio || file_type == FileType::Video || file_type == FileType::Animation ||
|
||||
file_type == FileType::VideoStory || (file_type == FileType::Encrypted && size_ > (1 << 20)));
|
||||
res.offset = offset_;
|
||||
res.limit = limit_;
|
||||
return res;
|
||||
}
|
||||
|
||||
void FileDownloader::on_error(Status status) {
|
||||
fd_.close();
|
||||
callback_->on_error(std::move(status));
|
||||
@ -546,38 +477,77 @@ void FileDownloader::update_downloaded_part(int64 offset, int64 limit, int64 max
|
||||
}
|
||||
|
||||
void FileDownloader::start_up() {
|
||||
auto r_file_info = init();
|
||||
if (r_file_info.is_error()) {
|
||||
on_error(r_file_info.move_as_error());
|
||||
if (local_.type() == LocalFileLocation::Type::Full) {
|
||||
on_error(Status::Error("File is already downloaded"));
|
||||
stop_flag_ = true;
|
||||
return;
|
||||
}
|
||||
auto file_info = r_file_info.ok();
|
||||
auto size = file_info.size;
|
||||
auto expected_size = max(size, file_info.expected_size);
|
||||
bool is_size_final = file_info.is_size_final;
|
||||
auto part_size = file_info.part_size;
|
||||
auto &ready_parts = file_info.ready_parts;
|
||||
auto use_part_count_limit = file_info.use_part_count_limit;
|
||||
if (encryption_key_.is_secure() && !encryption_key_.has_value_hash()) {
|
||||
LOG(ERROR) << "Can't download Secure file with unknown value_hash";
|
||||
}
|
||||
if (remote_.file_type_ == FileType::SecureEncrypted) {
|
||||
size_ = 0;
|
||||
}
|
||||
int32 part_size = 0;
|
||||
Bitmask bitmask{Bitmask::Ones{}, 0};
|
||||
if (local_.type() == LocalFileLocation::Type::Partial) {
|
||||
const auto &partial = local_.partial();
|
||||
path_ = partial.path_;
|
||||
auto result_fd = FileFd::open(path_, FileFd::Write | FileFd::Read);
|
||||
// TODO: check timestamps..
|
||||
if (result_fd.is_ok()) {
|
||||
if ((!encryption_key_.is_secret() || partial.iv_.size() == 32) && partial.part_size_ >= 0 &&
|
||||
partial.part_size_ <= (1 << 20) && (partial.part_size_ & (partial.part_size_ - 1)) == 0) {
|
||||
bitmask = Bitmask(Bitmask::Decode{}, partial.ready_bitmask_);
|
||||
if (encryption_key_.is_secret()) {
|
||||
encryption_key_.mutable_iv() = as<UInt256>(partial.iv_.data());
|
||||
next_part_ = narrow_cast<int32>(bitmask.get_ready_parts(0));
|
||||
}
|
||||
fd_ = result_fd.move_as_ok();
|
||||
part_size = static_cast<int32>(partial.part_size_);
|
||||
} else {
|
||||
LOG(ERROR) << "Have invalid " << partial;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (need_search_file_ && fd_.empty() && size_ > 0 && encryption_key_.empty() && !remote_.is_web()) {
|
||||
auto r_path = search_file(remote_.file_type_, name_, size_);
|
||||
if (r_path.is_ok()) {
|
||||
auto r_fd = FileFd::open(r_path.ok(), FileFd::Read);
|
||||
if (r_fd.is_ok()) {
|
||||
path_ = r_path.move_as_ok();
|
||||
fd_ = r_fd.move_as_ok();
|
||||
need_check_ = true;
|
||||
only_check_ = true;
|
||||
part_size = 128 * (1 << 10);
|
||||
bitmask = Bitmask{Bitmask::Ones{}, (size_ + part_size - 1) / part_size};
|
||||
LOG(INFO) << "Check hash of local file " << path_;
|
||||
}
|
||||
}
|
||||
}
|
||||
try_release_fd();
|
||||
|
||||
auto status =
|
||||
parts_manager_.init(size, expected_size, is_size_final, part_size, ready_parts, use_part_count_limit, false);
|
||||
LOG(DEBUG) << "Start downloading a file of size " << size << " with expected "
|
||||
<< (is_size_final ? "exact" : "approximate") << " size " << expected_size << ", part size " << part_size
|
||||
<< " and " << ready_parts.size() << " ready parts: " << status;
|
||||
auto ready_parts = bitmask.as_vector();
|
||||
auto status = parts_manager_.init(size_, size_, true, part_size, ready_parts, false, false);
|
||||
LOG(DEBUG) << "Start downloading a file of size " << size_ << ", part size " << part_size << " and "
|
||||
<< ready_parts.size() << " ready parts: " << status;
|
||||
if (status.is_error()) {
|
||||
on_error(std::move(status));
|
||||
stop_flag_ = true;
|
||||
return;
|
||||
}
|
||||
if (file_info.only_check) {
|
||||
if (only_check_) {
|
||||
parts_manager_.set_checked_prefix_size(0);
|
||||
}
|
||||
parts_manager_.set_streaming_offset(file_info.offset, file_info.limit);
|
||||
parts_manager_.set_streaming_offset(offset_, limit_);
|
||||
if (ordered_flag_) {
|
||||
ordered_parts_ = OrderedEventsProcessor<std::pair<Part, NetQueryPtr>>(parts_manager_.get_ready_prefix_count());
|
||||
}
|
||||
if (file_info.need_delay) {
|
||||
auto file_type = get_main_file_type(remote_.file_type_);
|
||||
if (!is_small_ &&
|
||||
(file_type == FileType::VideoNote || file_type == FileType::Document || file_type == FileType::VoiceNote ||
|
||||
file_type == FileType::Audio || file_type == FileType::Video || file_type == FileType::Animation ||
|
||||
file_type == FileType::VideoStory || (file_type == FileType::Encrypted && size_ > (1 << 20)))) {
|
||||
delay_dispatcher_ = create_actor<DelayDispatcher>("DelayDispatcher", 0.003, actor_shared(this, 1));
|
||||
next_delay_ = 0.05;
|
||||
}
|
||||
|
@ -119,21 +119,6 @@ class FileDownloader final : public FileLoaderActor {
|
||||
|
||||
Status check_loop(int64 checked_prefix_size, int64 ready_prefix_size, bool is_ready);
|
||||
|
||||
struct FileInfo {
|
||||
int64 size{0};
|
||||
int64 expected_size{0};
|
||||
bool is_size_final{false};
|
||||
int32 part_size{0};
|
||||
std::vector<int> ready_parts;
|
||||
bool use_part_count_limit{true};
|
||||
bool only_check{false};
|
||||
bool need_delay{false};
|
||||
int64 offset{0};
|
||||
int64 limit{0};
|
||||
bool is_upload{false};
|
||||
};
|
||||
Result<FileInfo> init() TD_WARN_UNUSED_RESULT;
|
||||
|
||||
Result<NetQueryPtr> start_part(Part part, int32 part_count, int64 streaming_offset) TD_WARN_UNUSED_RESULT;
|
||||
|
||||
Result<size_t> process_part(Part part, NetQueryPtr net_query) TD_WARN_UNUSED_RESULT;
|
||||
|
Loading…
Reference in New Issue
Block a user