📄 searchmanager.cpp
字号:
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 + -