int TMIgraph::readTopology(char *file_name) { int ret; Bitvector *lid; Bitvector *ilid; ifstream infile; string str; size_t found, first, second; FILE *instream; infile.open(file_name, ifstream::in); /*first the Global graph attributes - c igraph does not do it!!*/ while (infile.good()) { getline(infile, str); found = str.find("<data key=\"FID_LEN\">"); if (found != string::npos) { first = str.find(">"); second = str.find("<", first); sscanf(str.substr(first + 1, second - first - 1).c_str(), "%d", &fid_len); } found = str.find("<data key=\"TM\">"); if (found != string::npos) { first = str.find(">"); second = str.find("<", first); nodeID = str.substr(first + 1, second - first - 1); } found = str.find("<data key=\"TM_MODE\">"); if (found != string::npos) { first = str.find(">"); second = str.find("<", first); mode = str.substr(first + 1, second - first - 1); } } infile.close(); instream = fopen(file_name, "r"); ret = igraph_read_graph_graphml(&graph, instream, 0); fclose(instream); if (ret < 0) { return ret; } cout << "TM: " << igraph_vcount(&graph) << " nodes" << endl; cout << "TM: " << igraph_ecount(&graph) << " edges" << endl; for (int i = 0; i < igraph_vcount(&graph); i++) { string nID = string(igraph_cattribute_VAS(&graph, "NODEID", i)); string iLID = string(igraph_cattribute_VAS(&graph, "iLID", i)); reverse_node_index.insert(pair<string, int>(nID, i)); ilid = new Bitvector(iLID); nodeID_iLID.insert(pair<string, Bitvector *>(nID, ilid)); vertex_iLID.insert(pair<int, Bitvector *>(i, ilid)); //cout << "node " << i << " has NODEID " << nID << endl; //cout << "node " << i << " has ILID " << ilid->to_string() << endl; } for (int i = 0; i < igraph_ecount(&graph); i++) { string LID = string(igraph_cattribute_EAS(&graph, "LID", i)); reverse_edge_index.insert(pair<string, int>(LID, i)); lid = new Bitvector(LID); edge_LID.insert(pair<int, Bitvector *>(i, lid)); //cout << "edge " << i << " has LID " << lid->to_string() << endl; } return ret; }
Bitvector GraphRepresentation::calculateFID(string &source, string &destination) { int vertex_id; Bitvector result(dm->fid_len * 8); igraph_vs_t vs; igraph_vector_ptr_t res; igraph_vector_t to_vector; igraph_vector_t *temp_v; igraph_integer_t eid; /*find the vertex id in the reverse index*/ int from = (*reverse_node_index.find(source)).second; igraph_vector_init(&to_vector, 1); VECTOR(to_vector)[0] = (*reverse_node_index.find(destination)).second; /*initialize the sequence*/ igraph_vs_vector(&vs, &to_vector); /*initialize the vector that contains pointers*/ igraph_vector_ptr_init(&res, 1); temp_v = (igraph_vector_t *) VECTOR(res)[0]; temp_v = (igraph_vector_t *) malloc(sizeof (igraph_vector_t)); VECTOR(res)[0] = temp_v; igraph_vector_init(temp_v, 1); /*run the shortest path algorithm from "from"*/ igraph_get_shortest_paths(&igraph, &res, from, vs, IGRAPH_OUT); /*check the shortest path to each destination*/ temp_v = (igraph_vector_t *) VECTOR(res)[0]; //click_chatter("Shortest path from %s to %s", igraph_cattribute_VAS(&graph, "NODEID", from), igraph_cattribute_VAS(&graph, "NODEID", VECTOR(*temp_v)[igraph_vector_size(temp_v) - 1])); /*now let's "or" the FIDs for each link in the shortest path*/ for (int j = 0; j < igraph_vector_size(temp_v) - 1; j++) { igraph_get_eid(&igraph, &eid, VECTOR(*temp_v)[j], VECTOR(*temp_v)[j + 1], true); //click_chatter("node %s -> node %s", igraph_cattribute_VAS(&graph, "NODEID", VECTOR(*temp_v)[j]), igraph_cattribute_VAS(&graph, "NODEID", VECTOR(*temp_v)[j + 1])); //click_chatter("link: %s", igraph_cattribute_EAS(&graph, "LID", eid)); string LID(igraph_cattribute_EAS(&igraph, "LID", eid), dm->fid_len * 8); for (int k = 0; k < dm->fid_len * 8; k++) { if (LID[k] == '1') { (result)[ dm->fid_len * 8 - k - 1].operator |=(true); } } //click_chatter("FID of the shortest path: %s", result.to_string().c_str()); } /*now for all destinations "or" the internal linkID*/ vertex_id = (*reverse_node_index.find(destination)).second; string iLID(igraph_cattribute_VAS(&igraph, "iLID", vertex_id)); //click_chatter("internal link for node %s: %s", igraph_cattribute_VAS(&graph, "NODEID", vertex_id), iLID.c_str()); for (int k = 0; k < dm->fid_len * 8; k++) { if (iLID[k] == '1') { (result)[ dm->fid_len * 8 - k - 1].operator |=(true); } } igraph_vector_destroy((igraph_vector_t *) VECTOR(res)[0]); igraph_vector_destroy(&to_vector); igraph_vector_ptr_destroy_all(&res); igraph_vs_destroy(&vs); return result; }
int TEgraphMF::readTopology(const char *file_name) { int ret = 0; Bitvector* lid; Bitvector* ilid; ifstream infile; string str; size_t found, first, second; FILE *instream; infile.open(file_name, ifstream::in); /*first the Global graph attributes - c igraph does not do it!!*/ while (infile.good()) { getline(infile, str); found = str.find("<data key=\"FID_LEN\">"); if (found != string::npos) { first = str.find(">"); second = str.find("<", first); sscanf(str.substr(first + 1, second - first - 1).c_str(), "%d", &fid_len); } found = str.find("<data key=\"TM\">"); if (found != string::npos) { first = str.find(">"); second = str.find("<", first); nodeID = str.substr(first + 1, second - first - 1); } found = str.find("<data key=\"RV\">"); if (found != string::npos) { first = str.find(">"); second = str.find("<", first); RVnodeID = str.substr(first + 1, second - first - 1); } found = str.find("<data key=\"TM_MODE\">"); if (found != string::npos) { first = str.find(">"); second = str.find("<", first); mode = str.substr(first + 1, second - first - 1); } } infile.close(); instream = fopen(file_name, "r"); if (instream == NULL) { return -1; } //EF_ALLOW_MALLOC_0=1; ret = igraph_read_graph_graphml(&graph, instream, 0); //EF_ALLOW_MALLOC_0=0; fclose(instream); if (ret < 0) { return ret; } //cout << "TM: " << igraph_vcount(&graph) << " nodes" << endl; //cout << "TM: " << igraph_ecount(&graph) << " edges" << endl; for (int i = 0; i < igraph_vcount(&graph); i++) { string nID = string(igraph_cattribute_VAS(&graph, "NODEID", i)); string iLID = string(igraph_cattribute_VAS(&graph, "iLID", i)); reverse_node_index.insert(pair<string, int>(nID, i)); ilid = new Bitvector(iLID); nodeID_iLID.insert(pair<string, Bitvector* >(nID, ilid)); vertex_iLID.insert(pair<int, Bitvector* >(i, ilid)); cout<<"node "<<i<<" has NODEID"<<nID<<endl; cout<<"node "<<i<<" has ILID"<<ilid->to_string()<<endl; } for (int i = 0; i < igraph_ecount(&graph); i++) { string LID = string(igraph_cattribute_EAS(&graph, "LID", i)); reverse_edge_index.insert(pair<string, int>(LID, i)); lid = new Bitvector(LID); edge_LID.insert(pair<int, Bitvector* >(i, lid)); igraph_integer_t head; igraph_integer_t tail; igraph_edge(&graph, i,&head,&tail); cout << "edge " << i <<" "<<head<<"->"<<tail<<" has LID " << lid->to_string() << endl; } std::vector<int> edgepairs; std::vector<double> capacities; igraph_eit_t ieit; igraph_eit_create(&graph,igraph_ess_all(IGRAPH_EDGEORDER_ID),&ieit); while(!IGRAPH_EIT_END(ieit)) { igraph_integer_t edgeid = IGRAPH_EIT_GET(ieit); igraph_integer_t head; igraph_integer_t tail; // WARNING all edge capacities are give the same value // this needs to come from deployment script capacities.push_back(defaultBW); igraph_edge(&graph, edgeid,&head,&tail); cout<<"edge"<<head<<"->"<<tail<<endl; edgepairs.push_back(head); edgepairs.push_back(tail); IGRAPH_EIT_NEXT(ieit); } igraph_eit_destroy(&ieit); // create an initial dmand matrix assuming equal traffic // between all node pairs - unlikely to be correct but // as booststrap we do not know any better // THIS WILL NEED TO BE DYNAMICALLY UPDATED LATER for (int i = 0; i < igraph_vcount(&graph); i++) { for (int j = 0; j < igraph_vcount(&graph); j++) { if( i == j) continue; mf_demand demand; demand.source = i; demand.sink = j; // WARNING HARDCODED VALUE, ok for initial boostrap // as it is all relative. It should be obtained from // the deployment script as an initial demand. demand.demand = 1.0; demandMapMeasured.insert(pair<intpair,mf_demand>(intpair(i,j), demand)); } } graphMF = Graph_mf((int)igraph_vcount(&graph),edgepairs,capacities); // now demands are set to half the maximum flow when // using shortest paths assuming equal flow between // all pairs - enough for boostrapping // initial demand matrix done! //update_paths(); preCalculateFids(); return ret; }
//resiliency function for use later when supporting resiliency inside TE void TEgraphMF::updateGraph(string &source, string &destination, string &net, bool update_op){ igraph_vector_t v; igraph_es_t es; igraph_vector_t eids; int src_v = (*reverse_node_index.find(source)).second; int dst_v = (*reverse_node_index.find(destination)).second; string pairs[2]; pairs[0]=source + "/" + destination; pairs[1]=destination + "/" + source; if(net != "e"){ igraph_vector_init(&v, 2); igraph_vector_init(&eids,1); VECTOR(v)[0]=src_v; VECTOR(v)[1]=dst_v; } else { igraph_vector_init(&v, 4); igraph_vector_init(&eids,2); VECTOR(v)[0]=src_v; VECTOR(v)[1]=dst_v; VECTOR(v)[2]=dst_v; VECTOR(v)[3]=src_v; } if(update_op){ if(rmv_edge_lid.find(pairs[0]) != rmv_edge_lid.end()){ igraph_add_edge(&graph, src_v, dst_v); Bitvector *lid=new Bitvector(); lid = (*rmv_edge_lid.find(pairs[0])).second; igraph_cattribute_EAS_set(&graph, "LID", igraph_ecount(&graph) - 1, lid->to_string().c_str()); rmv_edge_lid.erase(pairs[0]); if((net=="e")&&(rmv_edge_lid.find(pairs[1]) != rmv_edge_lid.end())){ igraph_add_edge(&graph,dst_v , src_v); Bitvector *lid=new Bitvector(); lid = (*rmv_edge_lid.find(pairs[1])).second; igraph_cattribute_EAS_set(&graph, "LID", igraph_ecount(&graph) - 1, lid->to_string().c_str()); rmv_edge_lid.erase(pairs[1]); } cout<<"TM: Link Recovery: " << source << " - " << destination <<endl; } }else { if(net =="e"){ if ((rmv_edge_lid.find(pairs[0]) != rmv_edge_lid.end()) || (rmv_edge_lid.find(pairs[1]) != rmv_edge_lid.end())){ cout << "TM: Reported Edges are alreday disconnected" << endl; } else { igraph_es_pairs(&es, &v, true); #if IGRAPH_V >= IGRAPH_V_0_6 igraph_get_eids(&graph, &eids, &v, NULL, true, false); # else igraph_get_eids(&graph, &eids, &v, true); #endif for (int j = 0; j <= igraph_vector_size(&eids) - 1; j++) { Bitvector *lid = (*edge_LID.find(VECTOR(eids)[j])).second; rmv_edge_lid.insert(pair<string, Bitvector *>(pairs[j],lid)); } igraph_delete_edges(&graph, es); } } else if (net=="o"){ if(rmv_edge_lid.find(pairs[0]) != rmv_edge_lid.end()){ cout << "TM: Reproted Edge is already disconnected" << endl; } else { igraph_es_pairs(&es, &v, true); #if IGRAPH_V >= IGRAPH_V_0_6 igraph_get_eids(&graph, &eids, &v,NULL, true, false); # else igraph_get_eids(&graph, &eids, &v, true); #endif for (int j = 0; j <= igraph_vector_size(&eids) - 1; j++) { Bitvector *lid = (*edge_LID.find(VECTOR(eids)[j])).second; rmv_edge_lid.insert(pair<string, Bitvector *>(pairs[j],lid)); } igraph_delete_edges(&graph, es); } } } //mjreed MEMORY LEAK HERE reverse_edge_index.clear(); edge_LID.clear(); for (int i = 0; i < igraph_ecount(&graph); i++) { string LID = string(igraph_cattribute_EAS(&graph, "LID", i)); reverse_edge_index.insert(pair<string, int>(LID, i)); Bitvector* lid = new Bitvector(LID); edge_LID.insert(pair<int, Bitvector *>(i, lid)); //cout << "edge " << i << " has LID " << lid->to_string() << endl; } }