void CRoutingBin::GetClosestTo(uint32 uMaxType, const CUInt128 &uTarget, uint32 uMaxRequired, ContactMap *pmapResult, bool bEmptyFirst, bool bInUse) { // Empty list if requested. if (bEmptyFirst) pmapResult->clear(); // Return 0 since we have no entries. if (m_listEntries.size() == 0) return; // First put results in sort order for uTarget so we can insert them correctly. // We don't care about max results at this time. for (ContactList::const_iterator itContactList = m_listEntries.begin(); itContactList != m_listEntries.end(); ++itContactList) { if((*itContactList)->GetType() <= uMaxType) { CUInt128 uTargetDistance((*itContactList)->m_uClientID); uTargetDistance.Xor(uTarget); (*pmapResult)[uTargetDistance] = *itContactList; // This list will be used for an unknown time, Inc in use so it's not deleted. if( bInUse ) (*itContactList)->IncUse(); } } // Remove any extra results by least wanted first. while(pmapResult->size() > uMaxRequired) { // Dec in use count. if( bInUse ) (--pmapResult->end())->second->DecUse(); // remove from results pmapResult->erase(--pmapResult->end()); } return; }
void CRoutingZone::GetClosestTo(uint32 uMaxType, const CUInt128 &uTarget, const CUInt128 &uDistance, uint32 uMaxRequired, ContactMap *pmapResult, bool bEmptyFirst, bool bInUse) const { // If leaf zone, do it here if (IsLeaf()) { m_pBin->GetClosestTo(uMaxType, uTarget, uMaxRequired, pmapResult, bEmptyFirst, bInUse); return; } // otherwise, recurse in the closer-to-the-target subzone first int iCloser = uDistance.GetBitNumber(m_uLevel); m_pSubZones[iCloser]->GetClosestTo(uMaxType, uTarget, uDistance, uMaxRequired, pmapResult, bEmptyFirst, bInUse); // if still not enough tokens found, recurse in the other subzone too if (pmapResult->size() < uMaxRequired) m_pSubZones[1-iCloser]->GetClosestTo(uMaxType, uTarget, uDistance, uMaxRequired, pmapResult, false, bInUse); }
I only did a quick test of the code.. So it is possible there is still a bug.. Have fun.