Files
comaps/storage/storage_tests/fake_map_files_downloader.cpp
Konstantin Pastbin e3e4a1985a Organic Maps sources as of 02.04.2025 (fad26bbf22ac3da75e01e62aa01e5c8e11861005)
To expand with full Organic Maps and Maps.ME commits history run:
  git remote add om-historic [om-historic.git repo url]
  git fetch --tags om-historic
  git replace squashed-history historic-commits
2025-05-08 21:10:51 +07:00

131 lines
3.1 KiB
C++

#include "storage/storage_tests/fake_map_files_downloader.hpp"
#include "storage/storage_tests/task_runner.hpp"
#include "base/assert.hpp"
#include "base/scope_guard.hpp"
#include <algorithm>
#include <functional>
#include <utility>
namespace storage
{
int64_t const FakeMapFilesDownloader::kBlockSize;
FakeMapFilesDownloader::FakeMapFilesDownloader(TaskRunner & taskRunner)
: m_timestamp(0), m_taskRunner(taskRunner)
{
SetServersList({"http://test-url/"});
}
FakeMapFilesDownloader::~FakeMapFilesDownloader() { CHECK_THREAD_CHECKER(m_checker, ()); }
void FakeMapFilesDownloader::Download(QueuedCountry && queuedCountry)
{
CHECK_THREAD_CHECKER(m_checker, ());
m_queue.Append(std::move(queuedCountry));
if (m_queue.Count() == 1)
Download();
}
void FakeMapFilesDownloader::Remove(CountryId const & id)
{
CHECK_THREAD_CHECKER(m_checker, ());
if (m_queue.IsEmpty())
return;
if (m_writer && m_queue.GetFirstId() == id)
m_writer.reset();
m_queue.Remove(id);
++m_timestamp;
}
void FakeMapFilesDownloader::Clear()
{
CHECK_THREAD_CHECKER(m_checker, ());
m_queue.Clear();
m_writer.reset();
++m_timestamp;
}
QueueInterface const & FakeMapFilesDownloader::GetQueue() const
{
CHECK_THREAD_CHECKER(m_checker, ());
return m_queue;
}
void FakeMapFilesDownloader::Download()
{
auto const & queuedCountry = m_queue.GetFirstCountry();
if (!IsDownloadingAllowed())
{
OnFileDownloaded(queuedCountry, downloader::DownloadStatus::Failed);
return;
}
queuedCountry.OnStartDownloading();
++m_timestamp;
m_progress = {};
m_progress.m_bytesTotal = queuedCountry.GetDownloadSize();
m_writer.reset(new FileWriter(queuedCountry.GetFileDownloadPath()));
m_taskRunner.PostTask(std::bind(&FakeMapFilesDownloader::DownloadNextChunk, this, m_timestamp));
}
void FakeMapFilesDownloader::DownloadNextChunk(uint64_t timestamp)
{
CHECK_THREAD_CHECKER(m_checker, ());
static std::string kZeroes(kBlockSize, '\0');
if (timestamp != m_timestamp)
return;
ASSERT_LESS_OR_EQUAL(m_progress.m_bytesDownloaded, m_progress.m_bytesTotal, ());
ASSERT(m_writer, ());
if (m_progress.m_bytesDownloaded == m_progress.m_bytesTotal)
{
OnFileDownloaded(m_queue.GetFirstCountry(), downloader::DownloadStatus::Completed);
return;
}
int64_t const bs = std::min(m_progress.m_bytesTotal - m_progress.m_bytesDownloaded, kBlockSize);
m_progress.m_bytesDownloaded += bs;
m_writer->Write(kZeroes.data(), bs);
m_writer->Flush();
m_taskRunner.PostTask([this, timestamp]()
{
CHECK_THREAD_CHECKER(m_checker, ());
if (timestamp != m_timestamp)
return;
m_queue.GetFirstCountry().OnDownloadProgress(m_progress);
});
m_taskRunner.PostTask(std::bind(&FakeMapFilesDownloader::DownloadNextChunk, this, timestamp));
}
void FakeMapFilesDownloader::OnFileDownloaded(QueuedCountry const & queuedCountry,
downloader::DownloadStatus const & status)
{
auto const country = queuedCountry;
m_queue.PopFront();
m_taskRunner.PostTask([country, status]() { country.OnDownloadFinished(status); });
if (!m_queue.IsEmpty())
Download();
}
} // namespace storage