From 1becd3e0bac788497caf62ecac5a4f99dedc5bb3 Mon Sep 17 00:00:00 2001 From: Konstantin Pastbin Date: Wed, 2 Jul 2025 21:18:29 +0700 Subject: [PATCH] [core] Use dynamic chunk size for downloading maps Signed-off-by: Konstantin Pastbin --- .../DownloadResourcesLegacyActivity.cpp | 2 +- platform/chunks_download_strategy.cpp | 26 ++++++++++++++++++- platform/http_request.cpp | 13 +++------- platform/http_request.hpp | 2 +- 4 files changed, 31 insertions(+), 12 deletions(-) diff --git a/android/app/src/main/cpp/app/organicmaps/DownloadResourcesLegacyActivity.cpp b/android/app/src/main/cpp/app/organicmaps/DownloadResourcesLegacyActivity.cpp index 748368a63..1ac953548 100644 --- a/android/app/src/main/cpp/app/organicmaps/DownloadResourcesLegacyActivity.cpp +++ b/android/app/src/main/cpp/app/organicmaps/DownloadResourcesLegacyActivity.cpp @@ -171,7 +171,7 @@ extern "C" curFile.GetRemoteSize(), std::bind(&DownloadFileFinished, ptr, _1), std::bind(&DownloadFileProgress, ptr, _1), - 512 * 1024, false)); + 0, false)); }); return ERR_FILE_IN_PROGRESS; diff --git a/platform/chunks_download_strategy.cpp b/platform/chunks_download_strategy.cpp index 3e895ec1d..87fdc82f3 100644 --- a/platform/chunks_download_strategy.cpp +++ b/platform/chunks_download_strategy.cpp @@ -40,7 +40,31 @@ ChunksDownloadStrategy::GetChunk(RangeT const & range) void ChunksDownloadStrategy::InitChunks(int64_t fileSize, int64_t chunkSize, ChunkStatusT status) { - m_chunks.reserve(static_cast(fileSize / chunkSize + 2)); + if (chunkSize == 0) + { + int64_t constexpr kMb = 1024 * 1024; + size_t const sizeMb = std::max(fileSize / kMb, static_cast(1)); + + size_t constexpr kTargetCount = 40; + size_t constexpr kMinMb = 1; + size_t constexpr kMaxMb = 16; + size_t const chunkMb = std::min(std::max(sizeMb / kTargetCount, kMinMb), kMaxMb); + + size_t chunksCount = sizeMb / chunkMb; + if (static_cast(kMb * chunkMb * chunksCount) < fileSize) + ++chunksCount; + ASSERT_GREATER_OR_EQUAL(static_cast(kMb * chunkMb * chunksCount), fileSize, ()); + + LOG(LINFO, ("File size", sizeMb, "MB; chunk size", chunkMb, "MB; chunks count", chunksCount)); + + m_chunks.reserve(chunksCount + 1); + chunkSize = chunkMb * kMb; + } + else + { + m_chunks.reserve(static_cast(fileSize / chunkSize + 2)); + } + for (int64_t i = 0; i < fileSize; i += chunkSize) m_chunks.push_back(ChunkT(i, status)); // The last AUX chunk is just used to hold end of the range (eof) for the previous chunk. diff --git a/platform/http_request.cpp b/platform/http_request.cpp index fe675409a..745883ffa 100644 --- a/platform/http_request.cpp +++ b/platform/http_request.cpp @@ -136,7 +136,6 @@ class FileHttpRequest : public HttpRequest, public IHttpThreadCallback string m_filePath; unique_ptr m_writer; - size_t m_goodChunksCount; bool m_doCleanProgressFiles; // Starts a thread per each free/available server. @@ -248,13 +247,9 @@ class FileHttpRequest : public HttpRequest, public IHttpThreadCallback else if (result == ChunksDownloadStrategy::EDownloadSucceeded) m_status = DownloadStatus::Completed; - if (isChunkOk) - { - // save information for download resume - ++m_goodChunksCount; - if (m_status != DownloadStatus::Completed && m_goodChunksCount % 10 == 0) - SaveResumeChunks(); - } + // Save chunks statuses into the resume file. + if (isChunkOk && m_status != DownloadStatus::Completed) + SaveResumeChunks(); if (m_status == DownloadStatus::InProgress) return; @@ -300,7 +295,7 @@ public: int64_t chunkSize, bool doCleanProgressFiles) : HttpRequest(std::move(onFinish), std::move(onProgress)), m_strategy(urls), m_filePath(filePath), - m_goodChunksCount(0), m_doCleanProgressFiles(doCleanProgressFiles) + m_doCleanProgressFiles(doCleanProgressFiles) { ASSERT ( !urls.empty(), () ); diff --git a/platform/http_request.hpp b/platform/http_request.hpp index d09398a90..04e5187df 100644 --- a/platform/http_request.hpp +++ b/platform/http_request.hpp @@ -59,7 +59,7 @@ public: std::string const & filePath, int64_t fileSize, Callback && onFinish, Callback && onProgress = Callback(), - int64_t chunkSize = 512 * 1024, + int64_t chunkSize = 0, // 0 for auto bool doCleanOnCancel = true); }; } // namespace downloader