void ChunkManager::recreateMissingFiles()
	{
		createFiles();
		if (tor.isMultiFile())
		{
			// loop over all files and mark all chunks of all missing files as
			// not downloaded
			for (Uint32 i = 0;i < tor.getNumFiles();i++)
			{
				TorrentFile & tf = tor.getFile(i);
				if (!tf.isMissing())
					continue;
				
				for (Uint32 j = tf.getFirstChunk(); j <= tf.getLastChunk();j++)
					resetChunk(j);
				tf.setMissing(false);
			}
		}
		else
		{
			// reset all chunks in case of single file torrent
			for (Uint32 j = 0; j < tor.getNumChunks();j++)
				resetChunk(j);
		}
		d->saveIndexFile();
		d->recalc_chunks_left = true;
		chunksLeft();
	}
Ejemplo n.º 2
0
	void ChunkManager::dataChecked(const BitSet & ok_chunks)
	{
		// go over all chunks at check each of them
		for (Uint32 i = 0;i < chunks.count();i++)
		{
			Chunk* c = chunks[i];
			if (ok_chunks.get(i) && !bitset.get(i))
			{
				// We think we do not hae a chunk, but we do have it
				bitset.set(i,true);
				todo.set(i,false);
				// the chunk must be on disk
				c->setStatus(Chunk::ON_DISK);
				tor.updateFilePercentage(i,bitset); 
			}
			else if (!ok_chunks.get(i) && bitset.get(i))
			{
				Out(SYS_DIO|LOG_IMPORTANT) << "Previously OK chunk " << i << " is corrupt !!!!!" << endl;
				// We think we have a chunk, but we don't
				bitset.set(i,false);
				todo.set(i,!only_seed_chunks.get(i) && !excluded_chunks.get(i));
				if (c->getStatus() == Chunk::ON_DISK)
				{
					c->setStatus(Chunk::NOT_DOWNLOADED);
					tor.updateFilePercentage(i,bitset);
				}
				else if (c->getStatus() == Chunk::MMAPPED || c->getStatus() == Chunk::BUFFERED)
				{
					resetChunk(i);
				}
				else
				{
					tor.updateFilePercentage(i,bitset);
				}
			}
		}
		recalc_chunks_left = true;
		try
		{
			saveIndexFile();
		}
		catch (bt::Error & err)
		{
			Out(SYS_DIO|LOG_DEBUG) << "Failed to save index file : " << err.toString() << endl;
		}
		catch (...)
		{
			Out(SYS_DIO|LOG_DEBUG) << "Failed to save index file : unkown exception" << endl;
		}
		chunksLeft();
		corrupted_count = 0;
	}
Ejemplo n.º 3
0
	Chunk* ChunkManager::grabChunk(unsigned int i)
	{
		if (i >= chunks.size())
			return 0;
		
		Chunk* c = chunks[i];
		if (c->getStatus() == Chunk::NOT_DOWNLOADED || c->isExcluded())
		{
			return 0;
		}
		else if (c->getStatus() == Chunk::ON_DISK)
		{
			// load the chunk if it is on disk
			cache->load(c);
			loaded.insert(i,bt::GetCurrentTime());
			bool check_allowed = (max_chunk_size_for_data_check == 0 || tor.getChunkSize() <= max_chunk_size_for_data_check);
			
			// when no corruptions have been found, only check once every 5 chunks
			if (check_allowed && recheck_counter < 5 && corrupted_count == 0)
				check_allowed = false; 
			 
			if (c->getData() && check_allowed)
			{
				recheck_counter = 0;
				if (!c->checkHash(tor.getHash(i)))
				{
					Out(SYS_DIO|LOG_IMPORTANT) << "Chunk " << i 
							<< " has been found invalid, redownloading" << endl;
				
					resetChunk(i);
					tor.updateFilePercentage(i,bitset);
					saveIndexFile();
					recalc_chunks_left = true;
					corrupted_count++;
					corrupted(i);
					return 0;
				}
			}
			else
			{
				recheck_counter++;
			}
		}
		
		loaded.insert(i,bt::GetCurrentTime());
		return c;
	}
	void ChunkManager::dndMissingFiles()
	{
	//	createFiles(); // create them again
		// loop over all files and mark all chunks of all missing files as
		// not downloaded
		for (Uint32 i = 0;i < tor.getNumFiles();i++)
		{
			TorrentFile & tf = tor.getFile(i);
			if (!tf.isMissing())
				continue;
				
			for (Uint32 j = tf.getFirstChunk(); j <= tf.getLastChunk();j++)
				resetChunk(j);
			tf.setMissing(false);
			tf.setDoNotDownload(true); // set do not download
		}
		d->savePriorityInfo();
		d->saveIndexFile();
		d->recalc_chunks_left = true;
		chunksLeft();
	}
Ejemplo n.º 5
0
	void ChunkManager::downloadStatusChanged(TorrentFile* tf,bool download)
	{
		Uint32 first = tf->getFirstChunk();
		Uint32 last = tf->getLastChunk();
		if (download)
		{
			// include the chunks 
			include(first,last);
			
			// if it is a multimedia file, prioritise first and last chunks of file
			if (tf->isMultimedia())
			{
				Uint32 chunkOffset;
				chunkOffset = ((last - first) / 100) + 1;

				prioritise(first,first+chunkOffset,PREVIEW_PRIORITY);
				if (last - first > 2)
				{
					prioritise(last - chunkOffset, last, PREVIEW_PRIORITY);
					//prioritise(last -1,last, PREVIEW_PRIORITY);
				}
			}
		}
		else
		{
		//	Out(SYS_DIO|LOG_DEBUG) << "Excluding chunks " << first << " to " << last << endl;
			// first and last chunk may be part of multiple files
			// so we can't just exclude them
			QValueList<Uint32> files,last_files;

			// get list of files where first chunk lies in
			tor.calcChunkPos(first,files);
			tor.calcChunkPos(last,last_files);
			// check for exceptional case which causes very long loops
			if (first == last && files.count() > 1)
			{
				cache->downloadStatusChanged(tf,download);
				savePriorityInfo();
				return;
			}
			
			// go over all chunks from first to last and mark them as not downloaded 
			// (first and last not included)
			for (Uint32 i = first + 1;i < last;i++)
				resetChunk(i);
			
			// if the first chunk only lies in one file, reset it
			if (files.count() == 1 && first != 0) 
			{
		//		Out(SYS_DIO|LOG_DEBUG) << "Resetting first " << first << endl;
				resetChunk(first);
			}
			
			// if the last chunk only lies in one file reset it
			if (last != first && last_files.count() == 1)
			{
		//		Out(SYS_DIO|LOG_DEBUG) << "Resetting last " << last << endl;
				resetChunk(last);
			}
			
			Priority maxp = ONLY_SEED_PRIORITY;
			bool reprioritise_border_chunk = false;
			bool modified = false;
			
			// if one file in the list needs to be downloaded,increment first
			for (QValueList<Uint32>::iterator i = files.begin();i != files.end();i++)
			{
				if (*i == tf->getIndex())
					continue;
				
				const TorrentFile & other = tor.getFile(*i);
				if (!other.doNotDownload())
				{
					if (first != last && !modified)
					{
						first++;
						reprioritise_border_chunk = true;
						modified = true;
					}
					
					if (other.getPriority() > maxp)
						maxp = other.getPriority();
				}
			}
			
			// in case we have incremented first, we better reprioritise the border chunk
			if (reprioritise_border_chunk)
				prioritise(first-1,first-1,maxp);
			
			maxp = ONLY_SEED_PRIORITY;
			reprioritise_border_chunk = false;
			modified = false;
			
			// if one file in the list needs to be downloaded,decrement last
			for (QValueList<Uint32>::iterator i = last_files.begin();i != last_files.end();i++)
			{
				if (*i == tf->getIndex())
					continue;
				
				const TorrentFile & other = tor.getFile(*i);
				if (!other.doNotDownload())
				{
					if (first != last && last > 0 && !modified)
					{
						last--;
						reprioritise_border_chunk = true;
						modified = true;
					}
					
					if (other.getPriority() > maxp)
						maxp = other.getPriority();
				}
			}
			
			if (reprioritise_border_chunk)
				prioritise(last+1,last+1,maxp);

			// last smaller then first is not normal, so just return
			if (last < first)
			{
				cache->downloadStatusChanged(tf,download);
				savePriorityInfo();
				return;
			}
			
		//	Out(SYS_DIO|LOG_DEBUG) << "exclude " << first << " to " << last << endl;
			exclude(first,last);
		}
		// alert the cache but first put things in critical operation mode
		cache->downloadStatusChanged(tf,download);
		savePriorityInfo();
	}