Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Zolotarev <deathbaba@gmail.com>2011-11-07 06:55:11 +0400
committerAlex Zolotarev <alex@maps.me>2015-09-23 01:27:28 +0300
commit4ca29d9593b4890441dc163999302a870b76162a (patch)
treefc658094c2793082d5b128a8ecbfff1eb690c230 /platform/chunks_download_strategy.cpp
parent2eedf7245c2313e4e237083c672e5a234d44a61b (diff)
[mac] Added chunks download strategy
Diffstat (limited to 'platform/chunks_download_strategy.cpp')
-rw-r--r--platform/chunks_download_strategy.cpp92
1 files changed, 92 insertions, 0 deletions
diff --git a/platform/chunks_download_strategy.cpp b/platform/chunks_download_strategy.cpp
new file mode 100644
index 0000000000..ff22ab3f1b
--- /dev/null
+++ b/platform/chunks_download_strategy.cpp
@@ -0,0 +1,92 @@
+#include "chunks_download_strategy.hpp"
+
+#include "../std/algorithm.hpp"
+
+#define INVALID_CHUNK -1
+
+
+namespace downloader
+{
+
+ChunksDownloadStrategy::RangeT const ChunksDownloadStrategy::INVALID_RANGE = RangeT(-1, -1);
+
+ChunksDownloadStrategy::ChunksDownloadStrategy(vector<string> const & urls, int64_t fileSize, int64_t chunkSize)
+ : m_chunkSize(chunkSize)
+{
+ // init servers list
+ for (size_t i = 0; i < urls.size(); ++i)
+ m_servers.push_back(make_pair(urls[i], INVALID_RANGE));
+
+ // init chunks which should be downloaded
+ // @TODO implement download resume by saving chunks to download for specified file
+ for (int64_t i = 0; i < fileSize; i += chunkSize)
+ {
+ m_chunksToDownload.insert(RangeT(i, min(i + chunkSize - 1,
+ fileSize - 1)));
+ }
+}
+
+void ChunksDownloadStrategy::ChunkFinished(bool successfully, int64_t begRange, int64_t endRange)
+{
+ RangeT const chunk(begRange, endRange);
+ // find server which was downloading this chunk
+ for (ServersT::iterator it = m_servers.begin(); it != m_servers.end(); ++it)
+ {
+ if (it->second == chunk)
+ {
+ if (successfully)
+ it->second = INVALID_RANGE;
+ else
+ {
+ // remove failed server and mark chunk as not downloaded
+ m_servers.erase(it);
+ m_chunksToDownload.insert(chunk);
+ }
+ break;
+ }
+ }
+}
+
+ChunksDownloadStrategy::ResultT ChunksDownloadStrategy::NextChunk(string & outUrl,
+ int64_t & begRange,
+ int64_t & endRange)
+{
+ if (m_servers.empty())
+ return EDownloadFailed;
+
+ if (m_chunksToDownload.empty())
+ {
+ // no more chunks to download
+ bool allChunksAreFinished = true;
+ for (size_t i = 0; i < m_servers.size(); ++i)
+ {
+ if (m_servers[i].second != INVALID_RANGE)
+ allChunksAreFinished = false;
+ }
+ if (allChunksAreFinished)
+ return EDownloadSucceeded;
+ else
+ return ENoFreeServers;
+ }
+ else
+ {
+ RangeT const nextChunk = *m_chunksToDownload.begin();
+ for (size_t i = 0; i < m_servers.size(); ++i)
+ {
+ if (m_servers[i].second == INVALID_RANGE)
+ {
+ // found not used server
+ m_servers[i].second = nextChunk;
+ outUrl = m_servers[i].first;
+ begRange = nextChunk.first;
+ endRange = nextChunk.second;
+ m_chunksToDownload.erase(m_chunksToDownload.begin());
+ return ENextChunk;
+ }
+ }
+ // if we're here, all servers are busy downloading
+ return ENoFreeServers;
+ }
+}
+
+} // namespace downloader