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

📄 searchmanager.cpp

📁 电驴下载工具eMule0.47aVeryCD的源代码,可作分析测试也可用于P2P软件的开发研究.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
void CSearchManager::GetWords(LPCTSTR sz, WordList *plistWords)
{
	LPCTSTR szS = sz;
	size_t uChars = 0;
	size_t uBytes = 0;
	CStringW sWord;
	while (_tcslen(szS) > 0)
	{
		uChars = _tcscspn(szS, _aszInvKadKeywordChars);
		sWord = szS;
		sWord.Truncate(uChars);
		// TODO: We'd need a safe way to determine if a sequence which contains only 3 chars is a real word.
		// Currently we do this by evaluating the UTF-8 byte count. This will work well for Western locales,
		// AS LONG AS the min. byte count is 3(!). If the byte count is once changed to 2, this will not
		// work properly any longer because there are a lot of Western characters which need 2 bytes in UTF-8.
		// Maybe we need to evaluate the Unicode character values itself whether the characters are located
		// in code ranges where single characters are known to represent words.
		uBytes = KadGetKeywordBytes(sWord).GetLength();
		if (uBytes >= 3)
		{
			KadTagStrMakeLower(sWord);
			plistWords->remove
			(sWord);
			plistWords->push_back(sWord);
		}
		szS += uChars;
		if (uChars < _tcslen(szS))
			szS++;
	}

	// if the last word we have added, contains 3 chars (and 3 bytes), it's in almost all cases a file's extension.
	if (plistWords->size() > 1 && (uChars == 3 && uBytes == 3))
		plistWords->pop_back();
}

void CSearchManager::JumpStart()
{
	// Find any searches that has stalled and jumpstart them.
	// This will also prune all searches.
	time_t tNow = time(NULL);
	for (SearchMap::iterator itSearchMap = m_mapSearches.begin(); itSearchMap != m_mapSearches.end(); ++itSearchMap)
	{
		// Each type has it's own criteria for being deleted or jumpstarted.
		switch(itSearchMap->second->GetSearchTypes())
		{
			case CSearch::FILE:
				{
					if (itSearchMap->second->m_tCreated + SEARCHFILE_LIFETIME < tNow)
					{
						delete itSearchMap->second;
						itSearchMap = m_mapSearches.erase(itSearchMap);
					}
					else if (itSearchMap->second->GetAnswers() >= SEARCHFILE_TOTAL || itSearchMap->second->m_tCreated + SEARCHFILE_LIFETIME - SEC(20) < tNow)
						itSearchMap->second->PrepareToStop();
					else
						itSearchMap->second->JumpStart();
					break;
				}
			case CSearch::KEYWORD:
				{
					if (itSearchMap->second->m_tCreated + SEARCHKEYWORD_LIFETIME < tNow)
					{
						// Tell GUI that search ended
						if (theApp.emuledlg && theApp.emuledlg->searchwnd)
							theApp.emuledlg->searchwnd->CancelKadSearch(itSearchMap->second->GetSearchID());
						delete itSearchMap->second;
						itSearchMap = m_mapSearches.erase(itSearchMap);
					}
					else if (itSearchMap->second->GetAnswers() >= SEARCHKEYWORD_TOTAL || itSearchMap->second->m_tCreated + SEARCHKEYWORD_LIFETIME - SEC(20) < tNow)
						itSearchMap->second->PrepareToStop();
					else
						itSearchMap->second->JumpStart();
					break;
				}
			case CSearch::NOTES:
				{
					if (itSearchMap->second->m_tCreated + SEARCHNOTES_LIFETIME < tNow)
					{
						delete itSearchMap->second;
						itSearchMap = m_mapSearches.erase(itSearchMap);
					}
					else if (itSearchMap->second->GetAnswers() >= SEARCHNOTES_TOTAL || itSearchMap->second->m_tCreated + SEARCHNOTES_LIFETIME - SEC(20) < tNow)
						itSearchMap->second->PrepareToStop();
					else
						itSearchMap->second->JumpStart();
					break;
				}
			case CSearch::FINDBUDDY:
				{
					if (itSearchMap->second->m_tCreated + SEARCHFINDBUDDY_LIFETIME < tNow)
					{
						delete itSearchMap->second;
						itSearchMap = m_mapSearches.erase(itSearchMap);
					}
					else if (itSearchMap->second->GetAnswers() >= SEARCHFINDBUDDY_TOTAL || itSearchMap->second->m_tCreated + SEARCHFINDBUDDY_LIFETIME - SEC(20) < tNow)
						itSearchMap->second->PrepareToStop();
					else
						itSearchMap->second->JumpStart();
					break;
				}
			case CSearch::FINDSOURCE:
				{
					if (itSearchMap->second->m_tCreated + SEARCHFINDSOURCE_LIFETIME < tNow)
					{
						delete itSearchMap->second;
						itSearchMap = m_mapSearches.erase(itSearchMap);
					}
					else if (itSearchMap->second->GetAnswers() >= SEARCHFINDSOURCE_TOTAL || itSearchMap->second->m_tCreated + SEARCHFINDSOURCE_LIFETIME - SEC(20) < tNow)
						itSearchMap->second->PrepareToStop();
					else
						itSearchMap->second->JumpStart();
					break;
				}
			case CSearch::NODE:
				{
					if (itSearchMap->second->m_tCreated + SEARCHNODE_LIFETIME < tNow)
					{
						delete itSearchMap->second;
						itSearchMap = m_mapSearches.erase(itSearchMap);
					}
					else
						itSearchMap->second->JumpStart();
					break;
				}
			case CSearch::NODECOMPLETE:
				{
					if (itSearchMap->second->m_tCreated + SEARCHNODE_LIFETIME < tNow)
					{
						// Tell Kad that it can start publishing.
						CKademlia::GetPrefs()->SetPublish(true);
						delete itSearchMap->second;
						itSearchMap = m_mapSearches.erase(itSearchMap);
					}
					else if ((itSearchMap->second->m_tCreated + SEARCHNODECOMP_LIFETIME < tNow) && (itSearchMap->second->GetAnswers() >= SEARCHNODECOMP_TOTAL))
					{
						// Tell Kad that it can start publishing.
						CKademlia::GetPrefs()->SetPublish(true);
						delete itSearchMap->second;
						itSearchMap = m_mapSearches.erase(itSearchMap);
					}
					else
						itSearchMap->second->JumpStart();
					break;
				}
			case CSearch::STOREFILE:
				{
					if (itSearchMap->second->m_tCreated + SEARCHSTOREFILE_LIFETIME < tNow)
					{
						delete itSearchMap->second;
						itSearchMap = m_mapSearches.erase(itSearchMap);
					}
					else if (itSearchMap->second->GetAnswers() >= SEARCHSTOREFILE_TOTAL || itSearchMap->second->m_tCreated + SEARCHSTOREFILE_LIFETIME - SEC(20) < tNow)
						itSearchMap->second->PrepareToStop();
					else
						itSearchMap->second->JumpStart();
					break;
				}
			case CSearch::STOREKEYWORD:
				{
					if (itSearchMap->second->m_tCreated + SEARCHSTOREKEYWORD_LIFETIME < tNow)
					{
						delete itSearchMap->second;
						itSearchMap = m_mapSearches.erase(itSearchMap);
					}
					else if (itSearchMap->second->GetAnswers() >= SEARCHSTOREKEYWORD_TOTAL || itSearchMap->second->m_tCreated + SEARCHSTOREKEYWORD_LIFETIME - SEC(20)< tNow)
						itSearchMap->second->PrepareToStop();
					else
						itSearchMap->second->JumpStart();
					break;
				}
			case CSearch::STORENOTES:
				{
					if (itSearchMap->second->m_tCreated + SEARCHSTORENOTES_LIFETIME < tNow)
					{
						delete itSearchMap->second;
						itSearchMap = m_mapSearches.erase(itSearchMap);
					}
					else if (itSearchMap->second->GetAnswers() >= SEARCHSTORENOTES_TOTAL || itSearchMap->second->m_tCreated + SEARCHSTORENOTES_LIFETIME - SEC(20)< tNow)
						itSearchMap->second->PrepareToStop();
					else
						itSearchMap->second->JumpStart();
					break;
				}
			default:
				{
					if (itSearchMap->second->m_tCreated + SEARCH_LIFETIME < tNow)
					{
						delete itSearchMap->second;
						itSearchMap = m_mapSearches.erase(itSearchMap);
					}
					else
						itSearchMap->second->JumpStart();
					break;
				}
		}
	}
}

void CSearchManager::UpdateStats()
{
	// Update stats on the searches, this info can be used to determine if we need can start new searches.
	uint8 uTotalFile = 0;
	uint8 uTotalStoreSrc = 0;
	uint8 uTotalStoreKey = 0;
	uint8 uTotalSource = 0;
	uint8 uTotalNotes = 0;
	uint8 uTotalStoreNotes = 0;
	for (SearchMap::const_iterator itSearchMap = m_mapSearches.begin(); itSearchMap != m_mapSearches.end(); ++itSearchMap)
	{
		switch(itSearchMap->second->GetSearchTypes())
		{
			case CSearch::FILE:
				uTotalFile++;
				break;
			case CSearch::STOREFILE:
				uTotalStoreSrc++;
				break;
			case CSearch::STOREKEYWORD:
				uTotalStoreKey++;
				break;
			case CSearch::FINDSOURCE:
				uTotalSource++;
				break;
			case CSearch::STORENOTES:
				uTotalStoreNotes++;
				break;
			case CSearch::NOTES:
				uTotalNotes++;
				break;
		}
	}
	CPrefs *pPrefs = CKademlia::GetPrefs();
	if(pPrefs)
	{
		pPrefs->SetTotalFile(uTotalFile);
		pPrefs->SetTotalStoreSrc(uTotalStoreSrc);
		pPrefs->SetTotalStoreKey(uTotalStoreKey);
		pPrefs->SetTotalSource(uTotalSource);
		pPrefs->SetTotalNotes(uTotalNotes);
		pPrefs->SetTotalStoreNotes(uTotalStoreNotes);
	}
}

void CSearchManager::ProcessPublishResult(const CUInt128 &uTarget, const uint8 uLoad, const bool bLoadResponse)
{
	// We tried to publish some info and got a result.
	CSearch *pSearch = NULL;
	SearchMap::const_iterator itSearchMap = m_mapSearches.find(uTarget);
	if (itSearchMap != m_mapSearches.end())
		pSearch = itSearchMap->second;

	// Result could be very late and store deleted, abort.
	if (pSearch == NULL)
		return;

	switch(pSearch->GetSearchTypes())
	{
		case CSearch::STOREKEYWORD:
			if( bLoadResponse )
				pSearch->UpdateNodeLoad( uLoad );
			break;
		case CSearch::STOREFILE:
		case CSearch::STORENOTES:
			break;
	}

	// Inc the number of answers.
	pSearch->m_uAnswers++;
	// Update the search for the GUI
	theApp.emuledlg->kademliawnd->searchList->SearchRef(pSearch);
}


void CSearchManager::ProcessResponse(const CUInt128 &uTarget, uint32 uFromIP, uint16 uFromPort, ContactList *plistResults)
{
	// We got a response to a kad lookup.
	CSearch *pSearch = NULL;
	SearchMap::const_iterator itSearchMap= m_mapSearches.find(uTarget);
	if (itSearchMap != m_mapSearches.end())
		pSearch = itSearchMap->second;

	// If this search was deleted before this response, delete contacts and abort, otherwise process them.
	if (pSearch == NULL)
	{
		for (ContactList::const_iterator itContactList = plistResults->begin(); itContactList != plistResults->end(); ++itContactList)
			delete (*itContactList);
		delete plistResults;
		return;
	}
	else
		pSearch->ProcessResponse(uFromIP, uFromPort, plistResults);
}

void CSearchManager::ProcessResult(const CUInt128 &uTarget, const CUInt128 &uAnswer, TagList *plistInfo)
{
	// We have results for a request for info.
	CSearch *pSearch = NULL;
	SearchMap::const_iterator itSearchMap = m_mapSearches.find(uTarget);
	if (itSearchMap != m_mapSearches.end())
		pSearch = itSearchMap->second;

	// If this search was deleted before these results, delete contacts and abort, otherwise process them.
	if (pSearch == NULL)
	{
		for (TagList::const_iterator itTagList = plistInfo->begin(); itTagList != plistInfo->end(); ++itTagList)
			delete *itTagList;
		delete plistInfo;
	}
	else
		pSearch->ProcessResult(uAnswer, plistInfo);
}

⌨️ 快捷键说明

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