📄 indexed.cpp
字号:
toaddH->keyID.setValue(keyWordID);
Source* toaddS = new Source;
toaddS->sourceID.setValue(sourceID);
Kademlia::CEntry* toaddN = entry;
toaddS->entryList.AddHead(toaddN);
toaddH->sourceList.AddHead(toaddS);
keywordHashList.AddHead(toaddH);
return true;
}
for(POSITION pos = keywordHashList.GetHeadPosition(); pos != NULL; )
{
POSITION pos2 = pos;
KeywordHash* currKeywordHash = keywordHashList.GetNext(pos);
if (currKeywordHash->keyID == keyWordID){
for(POSITION pos3 = currKeywordHash->sourceList.GetHeadPosition(); pos3 != NULL; ){
POSITION pos4 = pos3;
Source* currSource = currKeywordHash->sourceList.GetNext(pos3);
if (currSource->sourceID == sourceID){
for(POSITION pos5 = currSource->entryList.GetHeadPosition(); pos5 != NULL; ){
POSITION pos6 = pos5;
Kademlia::CEntry* currName = currSource->entryList.GetNext(pos5);
if ( !entry->source )
{
if(!currName->source)
{
currSource->entryList.RemoveAt(pos6);
delete currName;
currSource->entryList.AddHead(entry);
return false;
}
}
else if( entry->source )
{
if(currName->ip == entry->ip && currName->tcpport == entry->tcpport)
{
currSource->entryList.RemoveAt(pos6);
delete currName;
currSource->entryList.AddHead(entry);
return false;
}
}
}
//New entry
if(entry->source)
{
if( currSource->entryList.GetCount() > 50 )
{
Kademlia::CEntry* toremove = currSource->entryList.GetTail();
currSource->entryList.RemoveTail();
delete toremove;
}
Kademlia::CEntry* toadd = entry;
currSource->entryList.AddHead(toadd);
return true;
}
}
}
Source* toaddS = new Source;
toaddS->sourceID.setValue(sourceID);
Kademlia::CEntry* toaddN = entry;
toaddS->entryList.AddHead(toaddN);
currKeywordHash->sourceList.AddHead(toaddS);
return true;
//New Source
}
}
KeywordHash* toaddH = new KeywordHash;
toaddH->keyID.setValue(keyWordID);
Source* toaddS = new Source;
toaddS->sourceID.setValue(sourceID);
Kademlia::CEntry* toaddN = entry;
toaddS->entryList.AddHead(toaddN);
toaddH->sourceList.AddHead(toaddS);
keywordHashList.AddHead(toaddH);
return true;
//This is a new key!
} catch(...){ASSERT(0);}
return false;
}
bool SearchTermsMatch(const SSearchTerm* pSearchTerm, const Kademlia::CEntry* item)
{
#define ASSERT_RETURN(x) if (!(x)) { ASSERT(0); return false; } // it's not worth that we crash here
ASSERT_RETURN( pSearchTerm != NULL );
ASSERT_RETURN( item != NULL );
// boolean operators
if (pSearchTerm->type == SSearchTerm::AND){
ASSERT_RETURN( pSearchTerm->left != NULL && pSearchTerm->right != NULL );
return SearchTermsMatch(pSearchTerm->left, item) && SearchTermsMatch(pSearchTerm->right, item);
}
if (pSearchTerm->type == SSearchTerm::OR){
ASSERT_RETURN( pSearchTerm->left != NULL && pSearchTerm->right != NULL );
return SearchTermsMatch(pSearchTerm->left, item) || SearchTermsMatch(pSearchTerm->right, item);
}
if (pSearchTerm->type == SSearchTerm::NAND){
ASSERT_RETURN( pSearchTerm->left != NULL && pSearchTerm->right != NULL );
return SearchTermsMatch(pSearchTerm->left, item) && !SearchTermsMatch(pSearchTerm->right, item);
}
// word which is to be searched in the file name (and in additional meta data as done by some ed2k servers???)
if (pSearchTerm->type == SSearchTerm::String){
ASSERT_RETURN( pSearchTerm->str != NULL );
//TODO: Use a pre-tokenized list for better performance.
int iPos = 0;
CString strTok(item->fileName.Tokenize(" ()[]{}<>,._-!?", iPos));
while (!strTok.IsEmpty()){
if (stricmp(strTok, *(pSearchTerm->str)) == 0)
return true;
strTok = item->fileName.Tokenize(" ()[]{}<>,._-!?", iPos);
}
// search string value in all string meta tags (this includes also the filename)
// although this would work, I am no longer sure if it's the correct way to process the search requests..
/*const Kademlia::CTag *tag;
TagList::const_iterator it;
for (it = item->taglist.begin(); it != item->taglist.end(); it++)
{
tag = *it;
if (tag->m_type == 2)
{
//TODO: Use a pre-tokenized list for better performance.
int iPos = 0;
CString strTok(static_cast<const CTagStr *>(tag)->m_value.Tokenize(" ()[]{}<>,._-!?", iPos));
while (!strTok.IsEmpty()){
if (stricmp(strTok, *(pSearchTerm->str)) == 0)
return true;
strTok = static_cast<const CTagStr *>(tag)->m_value.Tokenize(" ()[]{}<>,._-!?", iPos);
}
}
}*/
return false;
}
if (pSearchTerm->type == SSearchTerm::MetaTag){
ASSERT_RETURN( pSearchTerm->tag != NULL );
if (pSearchTerm->tag->m_type == 2){ // meta tags with string values
const Kademlia::CTag *tag;
TagList::const_iterator it;
for (it = item->taglist.begin(); it != item->taglist.end(); it++)
{
tag = *it;
if (tag->IsStr() && pSearchTerm->tag->m_name == tag->m_name)
return tag->GetStr().CompareNoCase(pSearchTerm->tag->GetStr()) == 0;
}
}
}
else if (pSearchTerm->type == SSearchTerm::Min){
ASSERT_RETURN( pSearchTerm->tag != NULL );
if (pSearchTerm->tag->IsInt()){ // meta tags with integer values
const Kademlia::CTag *tag;
TagList::const_iterator it;
for (it = item->taglist.begin(); it != item->taglist.end(); it++)
{
tag = *it;
if (tag->IsInt() && pSearchTerm->tag->m_name == tag->m_name)
return tag->GetInt() >= pSearchTerm->tag->GetInt();
}
}
else if (pSearchTerm->tag->IsFloat()){ // meta tags with float values
const Kademlia::CTag *tag;
TagList::const_iterator it;
for (it = item->taglist.begin(); it != item->taglist.end(); it++)
{
tag = *it;
if (tag->IsFloat() && pSearchTerm->tag->m_name == tag->m_name)
return tag->GetFloat() >= pSearchTerm->tag->GetFloat();
}
}
}
else if (pSearchTerm->type == SSearchTerm::Max){
ASSERT_RETURN( pSearchTerm->tag != NULL );
if (pSearchTerm->tag->IsInt()){ // meta tags with integer values
const Kademlia::CTag *tag;
TagList::const_iterator it;
for (it = item->taglist.begin(); it != item->taglist.end(); it++)
{
tag = *it;
if (tag->IsInt() && pSearchTerm->tag->m_name == tag->m_name)
return tag->GetInt() <= pSearchTerm->tag->GetInt();
}
}
else if (pSearchTerm->tag->IsFloat()){ // meta tags with float values
const Kademlia::CTag *tag;
TagList::const_iterator it;
for (it = item->taglist.begin(); it != item->taglist.end(); it++)
{
tag = *it;
if (tag->IsFloat() && pSearchTerm->tag->m_name == tag->m_name)
return tag->GetFloat() <= pSearchTerm->tag->GetFloat();
}
}
}
//ASSERT(0);
return false;
#undef ASSERT_RETURN
}
void CIndexed::SendValidResult( Kademlia::CUInt128 keyWordID, const SSearchTerm* pSearchTerms, const sockaddr_in *senderAddress, bool source ){
try
{
byte packet[1024*50];
CByteIO bio(packet,sizeof(packet));
bio.writeByte(OP_KADEMLIAHEADER);
bio.writeByte(KADEMLIA_SEARCH_RES);
bio.writeUInt128(keyWordID);
bio.writeUInt16(0);
time_t now = time(NULL) - (KADEMLIAINDEXCLEAN);
uint16 maxResults = 50;
uint16 count = 0;
for(POSITION pos = keywordHashList.GetHeadPosition(); pos != NULL; )
{
KeywordHash* currKeywordHash = keywordHashList.GetNext(pos);
if (currKeywordHash->keyID == keyWordID)
{
for(POSITION pos3 = currKeywordHash->sourceList.GetHeadPosition(); pos3 != NULL; )
{
Source* currSource = currKeywordHash->sourceList.GetNext(pos3);
for(POSITION pos5 = currSource->entryList.GetHeadPosition(); pos5 != NULL; )
{
POSITION pos6 = pos5;
Kademlia::CEntry* currName = currSource->entryList.GetNext(pos5);
if( currName->lifetime < now )
{
currSource->entryList.RemoveAt(pos6);
delete currName;
currName = NULL;
}
else
{
if( source )
{
if( currName->source )
{
if( count < maxResults )
{
bio.writeUInt128(currName->sourceID);
bio.writeTagList(currName->taglist);
count++;
}
}
}
else
{
if( !currName->source)
{
if ( !pSearchTerms || SearchTermsMatch(pSearchTerms, currName) )
{
if( count < maxResults ){
bio.writeUInt128(currName->sourceID);
bio.writeTagList(currName->taglist);
count++;
}
}
}
}
}
}
}
}
}
if( count )
{
uint32 len = sizeof(packet)-bio.getAvailable();
// CKademlia::debugMsg("Sent UDP OpCode KADEMLIA_SEARCH_RESULT (Keyword)(%u)", ntohl(senderAddress->sin_addr.s_addr));
// CMiscUtils::debugHexDump(packet, len);
TRACE("Search %u\n", count);
memcpy(packet+18, &count, 2);
CKademliaUDPListener *udpListner = CKademlia::getUDPListener();
ASSERT(udpListner != NULL);
udpListner->sendPacket(packet, len, ntohl(senderAddress->sin_addr.s_addr), ntohs(senderAddress->sin_port));
}
clean();
} catch(...){ASSERT(0);}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -