⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 storage.cpp

📁 这是一个嵌入式linux系统下的BT下载工具包
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	if(_bitSet.isSet(pieceIndex))	{		return;	}		if(_banedBitSet.isSet(pieceIndex))	{		return;	}		if(pieceIndex > _task->getTorrentFile()->getPieceCount()-1)	{		return;	}		if(_writeCache.find(pieceIndex) != _writeCache.end())	{		return;	}		_writeCache[pieceIndex] = data;	if(_writeCache.size() > getWriteCacheSizeMax())	{		saveWriteCacheToDisk();	}			_bitSet.set(pieceIndex, true);	_finishedPiece++;		if(_bitSet.getSize() - _banedBitSet.getSetedCount() == _finishedPiece)	{		_task->getPeerManager()->onDownloadComplete();		saveWriteCacheToDisk();	}	}void  CStorage::saveWriteCacheToDisk(){	//LOG_DEBUG("********* saveWriteCacheToDisk");	TPieceMap::iterator iter = _writeCache.begin();	for(; iter!=_writeCache.end(); ++iter)	{		writePieceD(iter->first, iter->second);	}		_writeCache.clear();		saveBitset();}void CStorage::writePieceD(unsigned int pieceIndex,std::string& data){	if(pieceIndex > _task->getTorrentFile()->getPieceCount()-1)	{		return;	}		int left = data.size();		off64_t globalOffet = (off64_t)pieceIndex*(off64_t)_task->getTorrentFile()->getPieceLength();	for(;left > 0;)	{		TStorageFileInfo sFileInfo = getFileInfoByOffset(globalOffet);				if(sFileInfo.baned)		{			left -= (sFileInfo.fileInfo.offset + sFileInfo.fileInfo.size - globalOffet);			globalOffet = sFileInfo.fileInfo.offset + sFileInfo.fileInfo.size;			continue;		}						if(sFileInfo.handle == -1)		{			return;		}				off64_t fileOffset = globalOffet-sFileInfo.fileInfo.offset;		int writelen = left;		if(writelen > sFileInfo.fileInfo.size - fileOffset)		{			writelen = sFileInfo.fileInfo.size - fileOffset;		}				lseek64(sFileInfo.handle, fileOffset, SEEK_SET);		writelen = write(sFileInfo.handle, data.data()+ data.size()-left, writelen);				left -= writelen;		globalOffet += writelen;	}}std::string CStorage::readData(unsigned int pieceIndex, unsigned int offset, unsigned int len){	//LOG_DEBUG("readData pieceIndex="<<pieceIndex<<" offset="<<offset<<" len="<<len);	if(pieceIndex > _task->getTorrentFile()->getPieceCount()-1)	{		return "";	}	if(len > _task->getTorrentFile()->getPieceLength()-offset)	{		return "";	}		std::string pieceData;	bool inReadCache = false;			//ReadCache	TReadPieceMap::iterator iter = _readCache.find(pieceIndex);	if(iter != _readCache.end())	{		//LOG_DEBUG("命中_readCache");		pieceData = iter->second.data;		iter->second.lastAccessTick = GetTickCount();		inReadCache = true;	}		if(pieceData.size() == 0)	{		//WriteCache		TPieceMap::iterator iter2 = _writeCache.find(pieceIndex);		if(iter2 != _writeCache.end())		{			//LOG_DEBUG("命中_writeCache");			pieceData = iter2->second;		}		}		//Disk	if(pieceData.size() == 0)	{		//LOG_DEBUG("cache中无数据,直接读取磁盘");		pieceData = readDataD(pieceIndex, 0, getPieceLength(pieceIndex));	}		if(pieceData.size() < offset+len)	{		return "";	}		if(!inReadCache)	{		TPieceCahce cache;		cache.data = pieceData;		cache.lastAccessTick = GetTickCount();				_readCache[pieceIndex] = cache;				for(; _readCache.size() > getReadCacheSizeMax();)		{			TReadPieceMap::iterator iter = _readCache.begin();			TReadPieceMap::iterator removeIter = iter;			for(; iter!= _readCache.end(); ++iter)			{				if(removeIter->second.lastAccessTick > iter->second.lastAccessTick)				{					removeIter = iter;				}			}					//LOG_DEBUG("从_readCache中删除 "<<removeIter->first);			_readCache.erase(removeIter);		}	}		return pieceData.substr(offset, len);}std::string CStorage::readDataD(unsigned int pieceIndex, off64_t offset, unsigned int len){	if(pieceIndex > _task->getTorrentFile()->getPieceCount()-1)	{		return "";	}	if(len > _task->getTorrentFile()->getPieceLength()-offset)	{		return "";	}		char* buf = new char[len];		int left = len;		off64_t globalOffet = (off64_t)pieceIndex*(off64_t)_task->getTorrentFile()->getPieceLength() + offset;	for(;left > 0;)	{		TStorageFileInfo sFileInfo = getFileInfoByOffset(globalOffet);		if(sFileInfo.handle == -1)		{			delete[] buf;			return "";		}				off64_t fileOffset = globalOffet-sFileInfo.fileInfo.offset;		int readlen = left;		if(readlen > sFileInfo.fileInfo.size - fileOffset)		{			readlen = sFileInfo.fileInfo.size - fileOffset;		}				lseek64(sFileInfo.handle, fileOffset, SEEK_SET);		readlen = read(sFileInfo.handle, buf+len-left, readlen);		left -= readlen;				globalOffet += readlen;	}			std::string result;	result.append((const char*)buf, len);	delete[] buf;		return result;}std::string CStorage::readPiece(unsigned int pieceIndex){	return readData(pieceIndex, 0, getPieceLength(pieceIndex));}bool CStorage::openFile(unsigned int index, TFileInfo fileInfo){	bool baned = false;	TStorageFileInfo sFileInfo;	std::string filePath;	if(_task->getTorrentFile()->IsUTF8Valid())	{		filePath = _destDir + fileInfo.pathUTF8;		filePath = filename_from_utf8(filePath.c_str());	}	else	{		filePath = _destDir + fileInfo.path;	}	TBanedFileList::iterator iter = _bandFileList.begin();	for(; iter!= _bandFileList.end(); ++iter)	{		if(*iter == index)		{			baned = true;			break;		}				}			sFileInfo.fileInfo = fileInfo;		if(!baned)	{		createDir(filePath.c_str());		int handle = open(filePath.c_str(), O_RDWR | O_CREAT | O_LARGEFILE, S_IRUSR | S_IWUSR | S_IRWXG | S_IRWXO);		if(handle == -1)		{			LOG_INFO("can not open file : "<<filePath);			return false;		}				struct stat64 st;		fstat64(handle, & st);				if(st.st_size != 0)		{			_newTask = false;		}		if(st.st_size != fileInfo.size)		{			ftruncate64(handle, fileInfo.size);		}							sFileInfo.handle = handle;		sFileInfo.mtime = st.st_mtime;		sFileInfo.baned = false;	}	else	{		sFileInfo.handle = -1;		sFileInfo.mtime = 0;		sFileInfo.baned = true;						_banedSize += fileInfo.size;	}		_fileHandleList.push_back(sFileInfo);		return true;}TStorageFileInfo CStorage::getFileInfoByOffset(off64_t offset){	TFileHandleList::iterator iter = _fileHandleList.begin();	TFileHandleList::iterator iter2;	for(; iter!=_fileHandleList.end(); ++iter)	{		if(iter->fileInfo.size == 0)		{			continue;		}				if(iter->fileInfo.offset <= offset			&& (iter->fileInfo.offset + iter->fileInfo.size) > offset)		{			return *iter;		}	}		//not found	TStorageFileInfo result;	result.handle = -1;	return result;}float CStorage::getFinishedPercent(){	int64_t total = _bitSet.getSize()-_banedBitSet.getSetedCount();	if(total == 0)	{		return 1.0f;	}		return ((double)_finishedPiece)/((double)total);}int64_t CStorage::getLeftCount(){	return (_bitSet.getSize() - _banedBitSet.getSetedCount() - _finishedPiece)*(int64_t)_task->getTorrentFile()->getPieceLength();}int64_t CStorage::getSelectedCount(){	return _task->getTorrentFile()->getTotalSize() - _banedSize;}int64_t CStorage::getBanedCount(){	return _banedSize;}unsigned int CStorage::getReadCacheSizeMax(){	unsigned int cachedPieceCount = _task->getCacheSize() / _task->getTorrentFile()->getPieceLength();		if(finished())	{		return cachedPieceCount;	}	return 2*cachedPieceCount/5;}unsigned int CStorage::getWriteCacheSizeMax(){	unsigned int cachedPieceCount = _task->getCacheSize() / _task->getTorrentFile()->getPieceLength();	if(finished())	{		return 0;	}	return 3*cachedPieceCount/5;	}void CStorage::genBanedBitSet(){	_banedBitSet.alloc(_task->getTorrentFile()->getPieceCount());		TFileHandleList::iterator iter = _fileHandleList.begin();	for(; iter!=_fileHandleList.end(); ++iter)	{		if(iter->fileInfo.size == 0)		{			continue;		}				if(!iter->baned)		{			continue;		}				unsigned int beginIndex = getPieceIndexByOffset(iter->fileInfo.offset);				unsigned int endOffset = getPieceIndexByOffset(iter->fileInfo.offset + iter->fileInfo.size -1);				for(unsigned int i = beginIndex; i<=endOffset; ++i)		{			_banedBitSet.set(i, true);		}	}		iter = _fileHandleList.begin();	for(; iter!=_fileHandleList.end(); ++iter)	{		if(iter->fileInfo.size == 0)		{			continue;		}				if(iter->baned)		{			continue;		}				unsigned int beginIndex = getPieceIndexByOffset(iter->fileInfo.offset);			_banedBitSet.set(beginIndex, false);					unsigned int endOffset = getPieceIndexByOffset(iter->fileInfo.offset + iter->fileInfo.size -1);		_banedBitSet.set(endOffset, false);	}	}unsigned int CStorage::getPieceIndexByOffset(off64_t offset){	return offset / _task->getTorrentFile()->getPieceLength();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -