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

📄 indexed.cpp

📁 一个关于电驴的源码,大家有需要可以下载
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			{
				// FIXME: There should never be an entry in the map which does have an empty 'entryList'
				// We now ownly let the clean method remove entries. This should be fixed.
				if (currSource->entryList.GetCount() > 0)
				{
					delete currSource->entryList.GetHead();
					currSource->entryList.RemoveHead();
				}
				currSource->entryList.AddHead(entry);
				return true;
			}
			else
			{
				currSource = new Source;
				currSource->sourceID.setValue(sourceID);
				currSource->entryList.AddHead(entry);
				currKeyHash->m_Source_map.SetAt(CCKey(currSource->sourceID.getData()), currSource);
				return true;
			}
		}
	}
	catch(...)
	{
		CKademlia::debugLine("Exception in CIndexed::writeFile");
		ASSERT(0);
	}
	return false;

}

bool CIndexed::AddSources(const CUInt128& keyID, const CUInt128& sourceID, Kademlia::CEntry* entry)
{
	try
	{
		KeyHash* currKeyHash;
		if(!m_Sources_map.Lookup(CCKey(keyID.getData()), currKeyHash))
		{
			Source* currSource = new Source;
			currSource->sourceID.setValue(sourceID);
			currSource->entryList.AddHead(entry);
			currKeyHash = new KeyHash;
			currKeyHash->keyID.setValue(keyID);
			currKeyHash->m_Source_map.SetAt(CCKey(currSource->sourceID.getData()), currSource);
			m_Sources_map.SetAt(CCKey(currKeyHash->keyID.getData()), currKeyHash);
			return true;
		}
		else
		{
			Source* currSource;
			if(currKeyHash->m_Source_map.Lookup(CCKey(sourceID.getData()), currSource))
			{
				for(POSITION pos5 = currSource->entryList.GetHeadPosition(); pos5 != NULL; )
				{
					POSITION pos6 = pos5;
					Kademlia::CEntry* currName = currSource->entryList.GetNext(pos5);
					if(currName->ip == entry->ip && currName->tcpport == entry->tcpport)
					{
						currSource->entryList.RemoveAt(pos6);
						delete currName;
						currSource->entryList.AddHead(entry);
						return true;
					}
				}
				//New entry
				if( currSource->entryList.GetCount() > KADEMLIAMAXSOUCEPERFILE )
				{
					CKademlia::debugMsg("Rotating sources");
					Kademlia::CEntry* toremove = currSource->entryList.GetTail();
					currSource->entryList.RemoveTail();
					delete toremove;
				}
				Kademlia::CEntry* toadd = entry;
				currSource->entryList.AddHead(toadd);
				return true;
			}
			else
			{
				currSource = new Source;
				currSource->sourceID.setValue(sourceID);
				currSource->entryList.AddHead(entry);
				currKeyHash->m_Source_map.SetAt(CCKey(currSource->sourceID.getData()), currSource);
				return true;
			}
		}
	}
	catch(...)
	{
		CKademlia::debugLine("Exception in CIndexed::AddSource");
	}
	return false;
}

bool SearchTermsMatch(const SSearchTerm* pSearchTerm, const Kademlia::CEntry* item, CStringArray& astrFileNameTokens)
{
	// boolean operators
	if (pSearchTerm->type == SSearchTerm::AND)
		return SearchTermsMatch(pSearchTerm->left, item, astrFileNameTokens) && SearchTermsMatch(pSearchTerm->right, item, astrFileNameTokens);
	
	if (pSearchTerm->type == SSearchTerm::OR)
		return SearchTermsMatch(pSearchTerm->left, item, astrFileNameTokens) || SearchTermsMatch(pSearchTerm->right, item, astrFileNameTokens);
	
	if (pSearchTerm->type == SSearchTerm::NAND)
		return SearchTermsMatch(pSearchTerm->left, item, astrFileNameTokens) && !SearchTermsMatch(pSearchTerm->right, item, astrFileNameTokens);

	// 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)
	{
		int iStrSearchTerms = pSearchTerm->astr->GetCount();
		if (iStrSearchTerms == 0)
			return false;
#if 0
		//TODO: Use a pre-tokenized list for better performance.
		// tokenize the filename (very expensive) only once per search expression and only if really needed
		if (astrFileNameTokens.GetCount() == 0)
		{
			int iPosTok = 0;
			CString strTok(item->fileName.Tokenize(" ()[]{}<>,._-!?", iPosTok));
			while (!strTok.IsEmpty())
			{
				astrFileNameTokens.Add(strTok);
				strTok = item->fileName.Tokenize(" ()[]{}<>,._-!?", iPosTok);
			}
		}
		if (astrFileNameTokens.GetCount() == 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++)
		{
			bool bFoundSearchTerm = false;
			for (int i = 0; i < astrFileNameTokens.GetCount(); i++)
			{
				// the file name string was already stored in lowercase
				// the string search term was already stored in lowercase
				if (strcmp(astrFileNameTokens.GetAt(i), pSearchTerm->astr->GetAt(iSearchTerm)) == 0)
				{
					bFoundSearchTerm = true;
					break;
				}
			}
			if (!bFoundSearchTerm)
				return false;
		}
#else
		// 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 (strstr(item->fileName, pSearchTerm->astr->GetAt(iSearchTerm)) == NULL)
				return false;
		}
#endif
		return true;

		// 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)
	{
		if (pSearchTerm->tag->m_type == 2) // meta tags with string values
		{
			TagList::const_iterator it;
			for (it = item->taglist.begin(); it != item->taglist.end(); it++)
			{
				const Kademlia::CTag* tag = *it;
				if (tag->IsStr() && pSearchTerm->tag->m_name.Compare(tag->m_name) == 0)
					return tag->GetStr().CompareNoCase(pSearchTerm->tag->GetStr()) == 0;
			}
		}
	}
	else if (pSearchTerm->type == SSearchTerm::OpGreaterEqual)
	{
		if (pSearchTerm->tag->IsInt()) // meta tags with integer values
		{
			TagList::const_iterator it;
			for (it = item->taglist.begin(); it != item->taglist.end(); it++)
			{
				const Kademlia::CTag* tag = *it;
				if (tag->IsInt() && pSearchTerm->tag->m_name.Compare(tag->m_name) == 0)
					return tag->GetInt() >= pSearchTerm->tag->GetInt();
			}
		}
		else if (pSearchTerm->tag->IsFloat()) // meta tags with float values
		{
			TagList::const_iterator it;
			for (it = item->taglist.begin(); it != item->taglist.end(); it++)
			{
				const Kademlia::CTag* tag = *it;
				if (tag->IsFloat() && pSearchTerm->tag->m_name.Compare(tag->m_name) == 0)
					return tag->GetFloat() >= pSearchTerm->tag->GetFloat();
			}
		}
	}
	else if (pSearchTerm->type == SSearchTerm::OpLessEqual)
	{
		if (pSearchTerm->tag->IsInt()) // meta tags with integer values
		{
			TagList::const_iterator it;
			for (it = item->taglist.begin(); it != item->taglist.end(); it++)
			{
				const Kademlia::CTag* tag = *it;
				if (tag->IsInt() && pSearchTerm->tag->m_name.Compare(tag->m_name) == 0)
					return tag->GetInt() <= pSearchTerm->tag->GetInt();
			}
		}
		else if (pSearchTerm->tag->IsFloat()) // meta tags with float values
		{
			TagList::const_iterator it;
			for (it = item->taglist.begin(); it != item->taglist.end(); it++)
			{
				const Kademlia::CTag* tag = *it;
				if (tag->IsFloat() && pSearchTerm->tag->m_name.Compare(tag->m_name) == 0)
					return tag->GetFloat() <= pSearchTerm->tag->GetFloat();
			}
		}
	}
	else if (pSearchTerm->type == SSearchTerm::OpGreater)
	{
		if (pSearchTerm->tag->IsInt()) // meta tags with integer values
		{
			TagList::const_iterator it;
			for (it = item->taglist.begin(); it != item->taglist.end(); it++)
			{
				const Kademlia::CTag* tag = *it;
				if (tag->IsInt() && pSearchTerm->tag->m_name.Compare(tag->m_name) == 0)
					return tag->GetInt() > pSearchTerm->tag->GetInt();
			}
		}
		else if (pSearchTerm->tag->IsFloat()) // meta tags with float values
		{
			TagList::const_iterator it;
			for (it = item->taglist.begin(); it != item->taglist.end(); it++)
			{
				const Kademlia::CTag* tag = *it;
				if (tag->IsFloat() && pSearchTerm->tag->m_name.Compare(tag->m_name) == 0)
					return tag->GetFloat() > pSearchTerm->tag->GetFloat();
			}
		}
	}
	else if (pSearchTerm->type == SSearchTerm::OpLess)
	{
		if (pSearchTerm->tag->IsInt()) // meta tags with integer values
		{
			TagList::const_iterator it;
			for (it = item->taglist.begin(); it != item->taglist.end(); it++)
			{
				const Kademlia::CTag* tag = *it;
				if (tag->IsInt() && pSearchTerm->tag->m_name.Compare(tag->m_name) == 0)
					return tag->GetInt() < pSearchTerm->tag->GetInt();
			}
		}
		else if (pSearchTerm->tag->IsFloat()) // meta tags with float values
		{
			TagList::const_iterator it;
			for (it = item->taglist.begin(); it != item->taglist.end(); it++)
			{
				const Kademlia::CTag* tag = *it;
				if (tag->IsFloat() && pSearchTerm->tag->m_name.Compare(tag->m_name) == 0)
					return tag->GetFloat() < pSearchTerm->tag->GetFloat();
			}
		}
	}
	else if (pSearchTerm->type == SSearchTerm::OpEqual)
	{
		if (pSearchTerm->tag->IsInt()) // meta tags with integer values
		{
			TagList::const_iterator it;
			for (it = item->taglist.begin(); it != item->taglist.end(); it++)
			{
				const Kademlia::CTag* tag = *it;
				if (tag->IsInt() && pSearchTerm->tag->m_name.Compare(tag->m_name) == 0)
					return tag->GetInt() == pSearchTerm->tag->GetInt();
			}
		}
		else if (pSearchTerm->tag->IsFloat()) // meta tags with float values
		{
			TagList::const_iterator it;
			for (it = item->taglist.begin(); it != item->taglist.end(); it++)
			{
				const Kademlia::CTag* tag = *it;
				if (tag->IsFloat() && pSearchTerm->tag->m_name.Compare(tag->m_name) == 0)
					return tag->GetFloat() == pSearchTerm->tag->GetFloat();
			}
		}
	}
	else if (pSearchTerm->type == SSearchTerm::OpNotEqual)
	{
		if (pSearchTerm->tag->IsInt()) // meta tags with integer values
		{
			TagList::const_iterator it;
			for (it = item->taglist.begin(); it != item->taglist.end(); it++)
			{
				const Kademlia::CTag* tag = *it;
				if (tag->IsInt() && pSearchTerm->tag->m_name.Compare(tag->m_name) == 0)
					return tag->GetInt() != pSearchTerm->tag->GetInt();
			}
		}
		else if (pSearchTerm->tag->IsFloat()) // meta tags with float values
		{
			TagList::const_iterator it;
			for (it = item->taglist.begin(); it != item->taglist.end(); it++)
			{
				const Kademlia::CTag* tag = *it;
				if (tag->IsFloat() && pSearchTerm->tag->m_name.Compare(tag->m_name) == 0)
					return tag->GetFloat() != pSearchTerm->tag->GetFloat();
			}
		}
	}

	return false;
}

bool SearchTermsMatch(const SSearchTerm* pSearchTerm, const Kademlia::CEntry* item)
{
	// tokenize the filename (very expensive) only once per search expression and only if really needed
	CStringArray astrFileNameTokens;
	return SearchTermsMatch(pSearchTerm, item, astrFileNameTokens);
}

void CIndexed::SendValidKeywordResult(const CUInt128& keyID, const SSearchTerm* pSearchTerms, uint32 ip, uint16 port)
{
	try
	{
		KeyHash* currKeyHash;
		if(m_Keyword_map.Lookup(CCKey(keyID.getData()), currKeyHash))
		{
			CKademliaUDPListener *udpListner = CKademlia::getUDPListener();
			ASSERT(udpListner != NULL); 
			byte packet[1024*50];
			CByteIO bio(packet,sizeof(packet));
			bio.writeByte(OP_KADEMLIAHEADER);
			bio.writeByte(KADEMLIA_SEARCH_RES);
			bio.writeUInt128(keyID);
			bio.writeUInt16(50);
			uint16 maxResults = 300;
			uint16 count = 0;
			POSITION pos2 = currKeyHash->m_Source_map.GetStartPosition();
			while( pos2 != NULL )
			{
				Source* currSource;
				CCKey key2;
				currKeyHash->m_Source_map.GetNextAssoc( pos2, key2, currSource );
				for(POSITION pos5 = currSource->entryList.GetHeadPosition(); pos5 != NULL; )
				{
					POSITION pos6 = pos5;
					Kademlia::CEntry* currName = currSource->entryList.GetNext(pos5);
					if ( !pSearchTerms || SearchTermsMatch(pSearchTerms, currName) )
					{
						if( count < maxResults ){
							bio.writeUInt128(currName->sourceID);
							bio.writeTagList(currName->taglist);
							count++;
							if( count % 50 == 0 )
							{
								uint32 len = sizeof(packet)-bio.getAvailable();
								if (thePrefs.GetDebugClientKadUDPLevel() > 0)
									DebugSend("KadSearchRes", ip, port);
								udpListner->sendPacket(packet, len, ip, port);
								bio.reset();
								bio.writeByte(OP_KADEMLIAHEADER);
								bio.writeByte(KADEMLIA_SEARCH_RES);
								bio.writeUInt128(keyID);
								bio.writeUInt16(50);
							}
						}
					}
				}
			}
			uint16 ccount = count % 50;
			if( ccount )
			{
				uint32 len = sizeof(packet)-bio.getAvailable();
				memcpy(packet+18, &ccount, 2);
				if (thePrefs.GetDebugClientKadUDPLevel() > 0)
					DebugSend("KadSearchRes", ip, port);
				udpListner->sendPacket(packet, len, ip, port);
			}
			clean();
		}
	} 
	catch(...)
	{
		CKademlia::debugLine("Exception in CIndexed::SendValidKeywordResult");
	}
}

void CIndexed::SendValidSourceResult(const CUInt128& keyID, uint32 ip, uint16 port)
{
	try
	{
		KeyHash* currKeyHash;
		if(m_Sources_map.Lookup(CCKey(keyID.getData()), currKeyHash))
		{
			CKademliaUDPListener *udpListner = CKademlia::getUDPListener();
			ASSERT(udpListner != NULL); 
			byte packet[1024*50];
			CByteIO bio(packet,sizeof(packet));
			bio.writeByte(OP_KADEMLIAHEADER);
			bio.writeByte(KADEMLIA_SEARCH_RES);
			bio.writeUInt128(keyID);
			bio.writeUInt16(50);
			uint16 maxResults = 300;
			uint16 count = 0;
			POSITION pos2 = currKeyHash->m_Source_map.GetStartPosition();
			while( pos2 != NULL )
			{
				Source* currSource;
				CCKey key2;
				currKeyHash->m_Source_map.GetNextAssoc( pos2, key2, currSource );
				for(POSITION pos5 = currSource->entryList.GetHeadPosition(); pos5 != NULL; )
				{
					POSITION pos6 = pos5;
					Kademlia::CEntry* currName = currSource->entryList.GetNext(pos5);
					if( count < maxResults )
					{
						bio.writeUInt128(currName->sourceID);
						bio.writeTagList(currName->taglist);
						count++;
						if( count % 50 == 0 )
						{
							uint32 len = sizeof(packet)-bio.getAvailable();
							if (thePrefs.GetDebugClientKadUDPLevel() > 0)
								DebugSend("KadSearchRes", ip, port);
							udpListner->sendPacket(packet, len, ip, port);
							bio.reset();
							bio.writeByte(OP_KADEMLIAHEADER);
							bio.writeByte(KADEMLIA_SEARCH_RES);
							bio.writeUInt128(keyID);
							bio.writeUInt16(50);
						}
					}
				}
			}
			uint16 ccount = count % 50;
			if( ccount )
			{
				uint32 len = sizeof(packet)-bio.getAvailable();
				memcpy(packet+18, &ccount, 2);
				if (thePrefs.GetDebugClientKadUDPLevel() > 0)
					DebugSend("KadSearchRes", ip, port);
				udpListner->sendPacket(packet, len, ip, port);
			}
			clean();
		}
	} 
	catch(...)
	{
		CKademlia::debugLine("Exception in CIndexed::SendValidSourceResult");
	}
}

SSearchTerm::SSearchTerm()
{
	type = AND;
	tag = NULL;
	left = NULL;
	right = NULL;
}

SSearchTerm::~SSearchTerm()
{
	if (type == String)
		delete astr;
	delete tag;
}

⌨️ 快捷键说明

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