📄 indexed.cpp
字号:
catch ( CIOException *ioe )
{
AddDebugLogLine( false, _T("Exception in CIndexed::~CIndexed (IO error(%i))"), ioe->m_iCause);
ioe->Delete();
}
catch (...)
{
AddDebugLogLine(false, _T("Exception in CIndexed::~CIndexed"));
}
}
void CIndexed::Clean(void)
{
try
{
if( m_tLastClean > time(NULL) )
return;
uint32 uRemovedKey = 0;
uint32 uRemovedSource = 0;
uint32 uTotalSource = 0;
uint32 uTotalKey = 0;
time_t tNow = time(NULL);
{
POSITION pos1 = m_mapKeyword.GetStartPosition();
while( pos1 != NULL )
{
CCKey key1;
KeyHash* pCurrKeyHash;
m_mapKeyword.GetNextAssoc( pos1, key1, pCurrKeyHash );
POSITION pos2 = pCurrKeyHash->mapSource.GetStartPosition();
while( pos2 != NULL )
{
CCKey key2;
Source* pCurrSource;
pCurrKeyHash->mapSource.GetNextAssoc( pos2, key2, pCurrSource );
for(POSITION pos3 = pCurrSource->ptrlEntryList.GetHeadPosition(); pos3 != NULL; )
{
POSITION pos4 = pos3;
CEntry* pCurrName = pCurrSource->ptrlEntryList.GetNext(pos3);
uTotalKey++;
if( !pCurrName->m_bSource && pCurrName->m_tLifetime < tNow)
{
uRemovedKey++;
pCurrSource->ptrlEntryList.RemoveAt(pos4);
delete pCurrName;
}
}
if( pCurrSource->ptrlEntryList.IsEmpty())
{
pCurrKeyHash->mapSource.RemoveKey(key2);
delete pCurrSource;
}
}
if( pCurrKeyHash->mapSource.IsEmpty())
{
m_mapKeyword.RemoveKey(key1);
delete pCurrKeyHash;
}
}
}
{
POSITION pos1 = m_mapSources.GetStartPosition();
while( pos1 != NULL )
{
CCKey key1;
SrcHash* pCurrSrcHash;
m_mapSources.GetNextAssoc( pos1, key1, pCurrSrcHash );
for(POSITION pos2 = pCurrSrcHash->ptrlistSource.GetHeadPosition(); pos2 != NULL; )
{
POSITION pos3 = pos2;
Source* pCurrSource = pCurrSrcHash->ptrlistSource.GetNext(pos2);
for(POSITION pos4 = pCurrSource->ptrlEntryList.GetHeadPosition(); pos4 != NULL; )
{
POSITION pos5 = pos4;
CEntry* pCurrName = pCurrSource->ptrlEntryList.GetNext(pos4);
uTotalSource++;
if( pCurrName->m_tLifetime < tNow)
{
uRemovedSource++;
pCurrSource->ptrlEntryList.RemoveAt(pos5);
delete pCurrName;
}
}
if( pCurrSource->ptrlEntryList.IsEmpty())
{
pCurrSrcHash->ptrlistSource.RemoveAt(pos3);
delete pCurrSource;
}
}
if( pCurrSrcHash->ptrlistSource.IsEmpty())
{
m_mapSources.RemoveKey(key1);
delete pCurrSrcHash;
}
}
}
m_uTotalIndexSource = uTotalSource;
m_uTotalIndexKeyword = uTotalKey;
AddDebugLogLine( false, _T("Removed %u keyword out of %u and %u source out of %u"), uRemovedKey, uTotalKey, uRemovedSource, uTotalSource);
m_tLastClean = time(NULL) + MIN2S(30);
}
catch(...)
{
AddDebugLogLine(false, _T("Exception in CIndexed::clean"));
ASSERT(0);
}
}
bool CIndexed::AddKeyword(const CUInt128& uKeyID, const CUInt128& uSourceID, Kademlia::CEntry* pEntry, uint8& uLoad)
{
if( !pEntry )
return false;
if( m_uTotalIndexKeyword > KADEMLIAMAXENTRIES )
{
uLoad = 100;
return false;
}
if( pEntry->m_uSize == 0 || pEntry->m_fileName.IsEmpty() || pEntry->m_listTag.size() == 0 || pEntry->m_tLifetime < time(NULL))
return false;
KeyHash* pCurrKeyHash;
if(!m_mapKeyword.Lookup(CCKey(uKeyID.GetData()), pCurrKeyHash))
{
Source* pCurrSource = new Source;
pCurrSource->uSourceID.SetValue(uSourceID);
pCurrSource->ptrlEntryList.AddHead(pEntry);
pCurrKeyHash = new KeyHash;
pCurrKeyHash->uKeyID.SetValue(uKeyID);
pCurrKeyHash->mapSource.SetAt(CCKey(pCurrSource->uSourceID.GetData()), pCurrSource);
m_mapKeyword.SetAt(CCKey(pCurrKeyHash->uKeyID.GetData()), pCurrKeyHash);
uLoad = 1;
m_uTotalIndexKeyword++;
return true;
}
else
{
uint32 uIndexTotal = pCurrKeyHash->mapSource.GetCount();
if ( uIndexTotal > KADEMLIAMAXINDEX )
{
uLoad = 100;
//Too many entries for this Keyword..
return false;
}
Source* pCurrSource;
if(pCurrKeyHash->mapSource.Lookup(CCKey(uSourceID.GetData()), pCurrSource))
{
if (pCurrSource->ptrlEntryList.GetCount() > 0)
{
if( uIndexTotal > KADEMLIAMAXINDEX - 5000 )
{
uLoad = 100;
//We are in a hot node.. If we continued to update all the publishes
//while this index is full, popular files will be the only thing you index.
return false;
}
delete pCurrSource->ptrlEntryList.GetHead();
pCurrSource->ptrlEntryList.RemoveHead();
}
else
m_uTotalIndexKeyword++;
uLoad = (uint8)((uIndexTotal*100)/KADEMLIAMAXINDEX);
pCurrSource->ptrlEntryList.AddHead(pEntry);
return true;
}
else
{
pCurrSource = new Source;
pCurrSource->uSourceID.SetValue(uSourceID);
pCurrSource->ptrlEntryList.AddHead(pEntry);
pCurrKeyHash->mapSource.SetAt(CCKey(pCurrSource->uSourceID.GetData()), pCurrSource);
m_uTotalIndexKeyword++;
uLoad = (uint8)((uIndexTotal*100)/KADEMLIAMAXINDEX);
return true;
}
}
}
bool CIndexed::AddSources(const CUInt128& uKeyID, const CUInt128& uSourceID, Kademlia::CEntry* pEntry, uint8& uLoad)
{
if( !pEntry )
return false;
if( pEntry->m_uIP == 0 || pEntry->m_uTCPPort == 0 || pEntry->m_uUDPPort == 0 || pEntry->m_listTag.size() == 0 || pEntry->m_tLifetime < time(NULL))
return false;
SrcHash* pCurrSrcHash;
if(!m_mapSources.Lookup(CCKey(uKeyID.GetData()), pCurrSrcHash))
{
Source* pCurrSource = new Source;
pCurrSource->uSourceID.SetValue(uSourceID);
pCurrSource->ptrlEntryList.AddHead(pEntry);
pCurrSrcHash = new SrcHash;
pCurrSrcHash->uKeyID.SetValue(uKeyID);
pCurrSrcHash->ptrlistSource.AddHead(pCurrSource);
m_mapSources.SetAt(CCKey(pCurrSrcHash->uKeyID.GetData()), pCurrSrcHash);
m_uTotalIndexSource++;
uLoad = 1;
return true;
}
else
{
uint32 uSize = pCurrSrcHash->ptrlistSource.GetSize();
for(POSITION pos1 = pCurrSrcHash->ptrlistSource.GetHeadPosition(); pos1 != NULL; )
{
Source* pCurrSource = pCurrSrcHash->ptrlistSource.GetNext(pos1);
if( pCurrSource->ptrlEntryList.GetSize() )
{
CEntry* pCurrEntry = pCurrSource->ptrlEntryList.GetHead();
ASSERT(pCurrEntry!=NULL);
if( pCurrEntry->m_uIP == pEntry->m_uIP && ( pCurrEntry->m_uTCPPort == pEntry->m_uTCPPort || pCurrEntry->m_uUDPPort == pEntry->m_uUDPPort ))
{
delete pCurrSource->ptrlEntryList.RemoveHead();
pCurrSource->ptrlEntryList.AddHead(pEntry);
uLoad = (uint8)((uSize*100)/KADEMLIAMAXSOUCEPERFILE);
return true;
}
}
else
{
//This should never happen!
pCurrSource->ptrlEntryList.AddHead(pEntry);
ASSERT(0);
uLoad = (uint8)((uSize*100)/KADEMLIAMAXSOUCEPERFILE);
m_uTotalIndexSource++;
return true;
}
}
if( uSize > KADEMLIAMAXSOUCEPERFILE )
{
Source* pCurrSource = pCurrSrcHash->ptrlistSource.RemoveTail();
delete pCurrSource->ptrlEntryList.RemoveTail();
pCurrSource->uSourceID.SetValue(uSourceID);
pCurrSource->ptrlEntryList.AddHead(pEntry);
pCurrSrcHash->ptrlistSource.AddHead(pCurrSource);
uLoad = 100;
return true;
}
else
{
Source* pCurrSource = new Source;
pCurrSource->uSourceID.SetValue(uSourceID);
pCurrSource->ptrlEntryList.AddHead(pEntry);
pCurrSrcHash->ptrlistSource.AddHead(pCurrSource);
m_uTotalIndexSource++;
uLoad = (uint8)((uSize*100)/KADEMLIAMAXSOUCEPERFILE);
return true;
}
}
}
bool CIndexed::AddNotes(const CUInt128& uKeyID, const CUInt128& uSourceID, Kademlia::CEntry* pEntry, uint8& uLoad)
{
if( !pEntry )
return false;
if( pEntry->m_uIP == 0 || pEntry->m_listTag.size() == 0 )
return false;
SrcHash* pCurrNoteHash;
if(!m_mapNotes.Lookup(CCKey(uKeyID.GetData()), pCurrNoteHash))
{
Source* pCurrNote = new Source;
pCurrNote->uSourceID.SetValue(uSourceID);
pCurrNote->ptrlEntryList.AddHead(pEntry);
SrcHash* pCurrNoteHash = new SrcHash;
pCurrNoteHash->uKeyID.SetValue(uKeyID);
pCurrNoteHash->ptrlistSource.AddHead(pCurrNote);
m_mapNotes.SetAt(CCKey(pCurrNoteHash->uKeyID.GetData()), pCurrNoteHash);
uLoad = 1;
m_uTotalIndexNotes++;
return true;
}
else
{
uint32 uSize = pCurrNoteHash->ptrlistSource.GetSize();
for(POSITION pos1 = pCurrNoteHash->ptrlistSource.GetHeadPosition(); pos1 != NULL; )
{
Source* pCurrNote = pCurrNoteHash->ptrlistSource.GetNext(pos1);
if( pCurrNote->ptrlEntryList.GetSize() )
{
CEntry* pCurrEntry = pCurrNote->ptrlEntryList.GetHead();
if(pCurrEntry->m_uIP == pEntry->m_uIP || pCurrEntry->m_uSourceID == pEntry->m_uSourceID)
{
delete pCurrNote->ptrlEntryList.RemoveHead();
pCurrNote->ptrlEntryList.AddHead(pEntry);
uLoad = (uint8)((uSize*100)/KADEMLIAMAXNOTESPERFILE);
return true;
}
}
else
{
//This should never happen!
pCurrNote->ptrlEntryList.AddHead(pEntry);
ASSERT(0);
uLoad = (uint8)((uSize*100)/KADEMLIAMAXNOTESPERFILE);
m_uTotalIndexKeyword++;
return true;
}
}
if( uSize > KADEMLIAMAXNOTESPERFILE )
{
Source* pCurrNote = pCurrNoteHash->ptrlistSource.RemoveTail();
delete pCurrNote->ptrlEntryList.RemoveTail();
pCurrNote->uSourceID.SetValue(uSourceID);
pCurrNote->ptrlEntryList.AddHead(pEntry);
pCurrNoteHash->ptrlistSource.AddHead(pCurrNote);
uLoad = 100;
return true;
}
else
{
Source* pCurrNote = new Source;
pCurrNote->uSourceID.SetValue(uSourceID);
pCurrNote->ptrlEntryList.AddHead(pEntry);
pCurrNoteHash->ptrlistSource.AddHead(pCurrNote);
uLoad = (uint8)((uSize*100)/KADEMLIAMAXNOTESPERFILE);
m_uTotalIndexKeyword++;
return true;
}
}
}
bool CIndexed::AddLoad(const CUInt128& uKeyID, uint32 uTime)
{
//This is needed for when you restart the client.
if((uint32)time(NULL)>uTime)
return false;
Load* pLoad;
if(m_mapLoad.Lookup(CCKey(uKeyID.GetData()), pLoad))
return false;
pLoad = new Load();
pLoad->uKeyID.SetValue(uKeyID);
pLoad->uTime = uTime;
m_mapLoad.SetAt(CCKey(pLoad->uKeyID.GetData()), pLoad);
m_uTotalIndexLoad++;
return true;
}
bool SearchTermsMatch(const SSearchTerm* pSearchTerm, const Kademlia::CEntry* pItem)
{
// boolean operators
if (pSearchTerm->m_type == SSearchTerm::AND)
return SearchTermsMatch(pSearchTerm->m_pLeft, pItem) && SearchTermsMatch(pSearchTerm->m_pRight, pItem);
if (pSearchTerm->m_type == SSearchTerm::OR)
return SearchTermsMatch(pSearchTerm->m_pLeft, pItem) || SearchTermsMatch(pSearchTerm->m_pRight, pItem);
if (pSearchTerm->m_type == SSearchTerm::NOT)
return SearchTermsMatch(pSearchTerm->m_pLeft, pItem) && !SearchTermsMatch(pSearchTerm->m_pRight, pItem);
// word which is to be searched in the file name (and in additional meta data as done by some ed2k servers???)
if (pSearchTerm->m_type == SSearchTerm::String)
{
int iStrSearchTerms = pSearchTerm->m_pastr->GetCount();
if (iStrSearchTerms == 0)
return false;
// if there are more than one search strings specified (e.g. "aaa bbb ccc") the entire string is handled
// like "aaa AND bbb AND ccc". search all strings from the string search term in the tokenized list of
// the file name. all strings of string search term have to be found (AND)
for (int iSearchTerm = 0; iSearchTerm < iStrSearchTerms; iSearchTerm++)
{
// this will not give the same results as when tokenizing the filename string, but it is 20 times faster.
if (wcsstr(pItem->m_fileName, pSearchTerm->m_pastr->GetAt(iSearchTerm)) == NULL)
return false;
}
return true;
}
if (pSearchTerm->m_type == SSearchTerm::MetaTag)
{
if (pSearchTerm->m_pTag->m_type == 2) // meta tags with string values
{
for (TagList::const_iterator itTagList = pItem->m_listTag.begin(); itTagList != pItem->m_listTag.end(); ++itTagList)
{
const CKadTag* pTag = *itTagList;
if (pTag->IsStr() && pSearchTerm->m_pTag->m_name.Compare(pTag->m_name) == 0)
return pTag->GetStr().CompareNoCase(pSearchTerm->m_pTag->GetStr()) == 0;
}
}
}
else if (pSearchTerm->m_type == SSearchTerm::OpGreaterEqual)
{
if (pSearchTerm->m_pTag->IsInt()) // meta tags with integer values
{
for (TagList::const_iterator itTagList = pItem->m_listTag.begin(); itTagList != pItem->m_listTag.end(); ++itTagList)
{
const CKadTag* pTag = *itTagList;
if (pTag->IsInt() && pSearchTerm->m_pTag->m_name.Compare(pTag->m_name) == 0)
return pTag->GetInt() >= pSearchTerm->m_pTag->GetInt();
}
}
else if (pSearchTerm->m_pTag->IsFloat()) // meta tags with float values
{
for (TagList::const_iterator itTagList = pItem->m_listTag.begin(); itTagList != pItem->m_listTag.end(); ++itTagList)
{
const Kademlia::CKadTag* pTag = *itTagList;
if (pTag->IsFloat() && pSearchTerm->m_pTag->m_name.Compare(pTag->m_name) == 0)
return pTag->GetFloat() >= pSearchTerm->m_pTag->GetFloat();
}
}
}
else if (pSearchTerm->m_type == SSearchTerm::OpLessEqual)
{
if (pSearchTerm->m_pTag->IsInt()) // meta tags with integer values
{
for (TagList::const_iterator itTagList = pItem->m_listTag.begin(); itTagList != pItem->m_listTag.end(); ++itTagList)
{
const Kademlia::CKadTag* pTag = *itTagList;
if (pTag->IsInt() && pSearchTerm->m_pTag->m_name.Compare(pTag->m_name) == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -