void ChunkManager::Private::saveIndexFile()
	{
		File fptr;
		if (!fptr.open(index_file,"wb"))
			throw Error(i18n("Cannot open index file %1: %2",index_file,fptr.errorString()));
		
		for (unsigned int i = 0;i < p->getNumChunks();i++)
		{
			Chunk* c = p->getChunk(i);
			if (c->getStatus() != Chunk::NOT_DOWNLOADED)
			{
				NewChunkHeader hdr;
				hdr.index = i;
				fptr.write(&hdr,sizeof(NewChunkHeader));
			}
		}
		savePriorityInfo();
	}
예제 #2
0
	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
		}
		savePriorityInfo();
		saveIndexFile();
		recalc_chunks_left = true;
		chunksLeft();
	}
예제 #3
0
	void ChunkManager::downloadPriorityChanged(TorrentFile* tf,Priority newpriority,Priority oldpriority)
	{
		if (newpriority == EXCLUDED)
		{
			downloadStatusChanged(tf, false);
			return;
		}
		if (oldpriority == EXCLUDED)
		{
			downloadStatusChanged(tf, true);
			return;
		}

		savePriorityInfo();
		
		Uint32 first = tf->getFirstChunk();
		Uint32 last = tf->getLastChunk();
		
		// first and last chunk may be part of multiple files
		// so we can't just exclude them
		QValueList<Uint32> files;

		// get list of files where first chunk lies in
		tor.calcChunkPos(first,files);
		
		Chunk* c = chunks[first];
		// if one file in the list needs to be downloaded,increment first
		for (QValueList<Uint32>::iterator i = files.begin();i != files.end();i++)
		{
			Priority np = tor.getFile(*i).getPriority();
			if (np > newpriority && *i != tf->getIndex())
			{
				// make sure we don't go past last
				if (first == last)
					return;
					
				first++;
				break;
			}
		}
		
		files.clear();
		// get list of files where last chunk lies in
		tor.calcChunkPos(last,files);
		c = chunks[last];
		// if one file in the list needs to be downloaded,decrement last
		for (QValueList<Uint32>::iterator i = files.begin();i != files.end();i++)
		{
			Priority np = tor.getFile(*i).getPriority();
			if (np > newpriority && *i != tf->getIndex())
			{
				// make sure we don't wrap around
				if (last == 0 || last == first)
					return;
					
				last--;
				break;
			}
		}
		
		// last smaller then first is not normal, so just return
		if (last < first)
		{
			return;
		}
		

		prioritise(first,last,newpriority);
		if (newpriority == ONLY_SEED_PRIORITY)
			excluded(first,last);
	}
예제 #4
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();
	}