[Maella -Enhanced Chunk Selection- (based on jicxicmic)]
| 1974 | |
| 1975 | // [Maella -Enhanced Chunk Selection- (based on jicxicmic)] |
| 1976 | bool CPartFile::GetNextRequestedBlock(CUpDownClient* sender, |
| 1977 | std::vector<Requested_Block_Struct*>& toadd, uint16& count) |
| 1978 | { |
| 1979 | |
| 1980 | // The purpose of this function is to return a list of blocks (~180KB) to |
| 1981 | // download. To avoid a prematurely stop of the downloading, all blocks that |
| 1982 | // are requested from the same source must be located within the same |
| 1983 | // chunk (=> part ~9MB). |
| 1984 | // |
| 1985 | // The selection of the chunk to download is one of the CRITICAL parts of the |
| 1986 | // edonkey network. The selection algorithm must insure the best spreading |
| 1987 | // of files. |
| 1988 | // |
| 1989 | // The selection is based on 4 criteria: |
| 1990 | // 1. Frequency of the chunk (availability), very rare chunks must be downloaded |
| 1991 | // as quickly as possible to become a new available source. |
| 1992 | // 2. Parts used for preview (first + last chunk), preview or check a |
| 1993 | // file (e.g. movie, mp3) |
| 1994 | // 3. Request state (downloading in process), try to ask each source for another |
| 1995 | // chunk. Spread the requests between all sources. |
| 1996 | // 4. Completion (shortest-to-complete), partially retrieved chunks should be |
| 1997 | // completed before starting to download other one. |
| 1998 | // |
| 1999 | // The frequency criterion defines three zones: very rare (<10%), rare (<50%) |
| 2000 | // and common (>30%). Inside each zone, the criteria have a specific weight, used |
| 2001 | // to calculate the priority of chunks. The chunk(s) with the highest |
| 2002 | // priority (highest=0, lowest=0xffff) is/are selected first. |
| 2003 | // |
| 2004 | // very rare (preview) rare common |
| 2005 | // 0% <---- +0 pt ----> 10% <----- +10000 pt -----> 50% <---- +20000 pt ----> 100% |
| 2006 | // 1. <------- frequency: +25*frequency pt -----------> |
| 2007 | // 2. <- preview: +1 pt --><-------------- preview: set to 10000 pt -------------> |
| 2008 | // 3. <------ request: download in progress +20000 pt ------> |
| 2009 | // 4a. <- completion: 0% +100, 25% +75 .. 100% +0 pt --><-- !req => completion ---> |
| 2010 | // 4b. <--- req => !completion --> |
| 2011 | // |
| 2012 | // Unrolled, the priority scale is: |
| 2013 | // |
| 2014 | // 0..xxxx unrequested and requested very rare chunks |
| 2015 | // 10000..1xxxx unrequested rare chunks + unrequested preview chunks |
| 2016 | // 20000..2xxxx unrequested common chunks (priority to the most complete) |
| 2017 | // 30000..3xxxx requested rare chunks + requested preview chunks |
| 2018 | // 40000..4xxxx requested common chunks (priority to the least complete) |
| 2019 | // |
| 2020 | // This algorithm usually selects first the rarest chunk(s). However, partially |
| 2021 | // complete chunk(s) that is/are close to completion may overtake the priority |
| 2022 | // (priority inversion). |
| 2023 | // For the common chunks, the algorithm tries to spread the download between |
| 2024 | // the sources |
| 2025 | // |
| 2026 | |
| 2027 | // Check input parameters |
| 2028 | if ( sender->GetPartStatus().empty() ) { |
| 2029 | return false; |
| 2030 | } |
| 2031 | // Define and create the list of the chunks to download |
| 2032 | const uint16 partCount = GetPartCount(); |
| 2033 | ChunkList chunksList; |
no test coverage detected