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

chunks_download_strategy.cpp « platform - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 88ead660a8dc24f1a796b32bf1cacc57c6da9fb2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#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
  for (int64_t i = 0; i < fileSize; i += chunkSize)
    m_chunksToDownload.insert(RangeT(i, min(i + chunkSize - 1, fileSize - 1)));
}

void ChunksDownloadStrategy::SetChunksToDownload(RangesContainerT & chunks)
{
  m_chunksToDownload.swap(chunks);
}

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