PtrTracer(const ManagedHeap& heap) { // сформировать список объектов objects.reserve(heap.allocations.size()); for(Allocations::const_iterator i = heap.allocations.begin(); i != heap.allocations.end(); ++i) objects.push_back(Object(i->first, i->second.size, i->second.info)); std::sort(objects.begin(), objects.end(), sorter); // сформировать карту ссылок for(Ptrs::const_iterator i = heap.ptrs.begin(); i != heap.ptrs.end(); ++i) { // найти объект, в котором содержится указатель Objects::const_iterator j = std::upper_bound(objects.begin(), objects.end(), i->first, sorter); if(j > objects.begin()) { --j; if((size_t)((char*)i->first - (char*)j->data) < j->size) // да, указатель содержится в этом объекте // получить объект, на который указывает указатель, и добавить ссылку links.insert(std::make_pair(j, std::lower_bound(objects.begin(), objects.end(), i->second, sorter))); } } }
NetPath VirtualLinkRouter::routeKShortestPathsALL(VirtualLink * virtualLink, Network * network, std::vector<NetPath> * pathStorage) { // links and switches that would be removed from the network, // they should be restored after algorithm's finish Links removedLinks; Switches removedSwitches; // first, create the graph with decreased capacities decreaseCapacities(virtualLink, network, &removedLinks, &removedSwitches); // Yen's algorithm NetPath shortest = searchPathDejkstra(virtualLink, network, K_SHORTEST_PATHS); if ( shortest.size() == 0 ) { restoreCapacities(virtualLink, network, &removedLinks, &removedSwitches); return NetPath(); // no path found! } pathStorage->push_back(shortest); Links& links = network->getLinks(); unsigned pathsFound = 1; long pathWeight = calculateKShortestPathWeight(shortest); bool isNewPathFound = true; while ( isNewPathFound && pathsFound < Criteria::kShortestPathDepth() ) { NetPath candidate = shortest; NetPath::iterator it = shortest.begin(); NetPath::iterator itEnd = shortest.end(); isNewPathFound = false; bool isNewCandidateFound = false; Link * linkToRemove = NULL; for ( ; it != itEnd; ++it ) { if ( (*it)->isLink() && links.find(static_cast<Link*>(*it)) != links.end() ) { // removing link and trying dejkstra links.erase(links.find(static_cast<Link*>(*it))); NetPath newPath = searchPathDejkstra(virtualLink, network, K_SHORTEST_PATHS); if ( newPath.size() == shortest.size() ) { isNewPathFound = true; pathStorage->push_back(newPath); ++pathsFound; long weight = calculateKShortestPathWeight(newPath); if ( weight > pathWeight ) { isNewCandidateFound = true; linkToRemove = static_cast<Link*>(*it); pathWeight = weight; candidate = newPath; if ( pathsFound == Criteria::kShortestPathDepth() ) break; } if ( linkToRemove == NULL ) linkToRemove = static_cast<Link*>(*it); // to avoid the situation with removing NULL-link } links.insert(static_cast<Link*>(*it)); // inserting link again } } if ( isNewCandidateFound ) shortest = candidate; if ( isNewPathFound && pathsFound != Criteria::kShortestPathDepth() ) { // restoring the capacity of link being removed linkToRemove->RemoveAssignment(virtualLink); links.erase(links.find(linkToRemove)); removedLinks.insert(linkToRemove); } } // restoring removed capacities restoreCapacities(virtualLink, network, &removedLinks, &removedSwitches); return shortest; }