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

📄 indexed.cpp

📁 Kademlia---第第3代P2P原代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			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 + -