Example #1
0
	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;
}