//多线程查询顶点数目 uint32_t Client::read_all_vertex(list<Vertex_u> **vertexes,uint32_t *size){ if(current_graph()=="") return STATUS_NOT_EXIST;//如果还没有连接图,则返回状态STATUS_NOT_EXIST //获取所有节点的ip vector<string> ips; get_all_meta(ips); //多线程的发送,所以要给每个线程数据 *size=ips.size(); *vertexes=new list<Vertex_u>[*size]; Ip_All_Vertex* datas=new Ip_All_Vertex[*size]; uint32_t index=0; pthread_t *threads=new pthread_t[*size]; for(int index=0;index<*size;index++){ datas[index].graph_name=graph_name; datas[index].sock=find_sock(ips[index]); datas[index].vertexes=&(*vertexes)[index]; pthread_create(&threads[index],NULL,thread_read_all_vertex,&datas[index]); } //等待线程的运行完成 for(index=0;index<*size;index++){ pthread_join(threads[index],NULL); } delete[] datas; delete[] threads; return STATUS_OK; }
//批量读取边,返回所有的边,源顶点和目的顶点就没有规律了,还要在上面封装接口来读取某个源顶点和目的顶点的边,也可以由用户完成 //如果vertexes是空,则不会发送请求 uint32_t Client::read_two_edges(list<Two_vertex>& vertexes,list<Edge_u> &edges){ if(current_graph()=="") return STATUS_NOT_EXIST;//如果还没有连接图,则返回状态STATUS_NOT_EXIST //找所有边的元数据,由于有缓存,这个操作不会成为瓶颈。边在获取元数据的时候按照ip分类 unordered_map<string,list<Two_vertex>*> classify; list<Two_vertex>::iterator it=vertexes.begin(); unordered_map<string,list<Two_vertex>*>::iterator it_cl; string ip; while(it!=vertexes.end()){ ip=get_meta(graph_name,(*it).s_id); it_cl=classify.find(ip); if(it_cl==classify.end()){ //如果没有这个ip类,则创建,然后把边加入到该ip类 classify.insert(pair<string,list<Two_vertex>*>(ip,new list<Two_vertex>())); it_cl=classify.find(ip); it_cl->second->push_back(*it); }else{ it_cl->second->push_back(*it); } it++; } //元数据查完后,就开始分别把每个ip类的顶点对发送出去 it_cl=classify.begin(); while(it_cl!=classify.end()){ Requester req_slave(*find_sock(it_cl->first)); req_slave.ask(CMD_READ_TWO_EDGES,*(it_cl->second),graph_name); req_slave.parse_ans(edges); delete it_cl->second;//这个ip类的边插完了,则释放空间 it_cl++; } return STATUS_OK; }
//多线程批量读取具有某属性的所有边 uint32_t Client::read_edge_index_pthread(string id,list<Edge_u> **edges,uint32_t *size){ if(current_graph()=="") return STATUS_NOT_EXIST;//如果还没有连接图,则返回状态STATUS_NOT_EXIST //获取所有节点的ip vector<string> ips; get_all_meta(ips); //构造参数proto_blog_id,长度超过后,就会截取 proto_blog_id blog_id(graph_name,id); //多线程的发送,所以要给每个线程数据 *size=ips.size(); *edges=new list<Edge_u>[*size]; Ip_Blog_ID* datas=new Ip_Blog_ID[*size]; uint32_t index=0; pthread_t *threads=new pthread_t[*size]; for(int index=0;index<*size;index++){ datas[index].blog_id=blog_id; datas[index].sock=find_sock(ips[index]); datas[index].edges=&(*edges)[index]; pthread_create(&threads[index],NULL,thread_read_edge_index,&datas[index]); } //等待线程的运行完成 for(index=0;index<*size;index++){ pthread_join(threads[index],NULL); } delete[] datas; delete[] threads; return STATUS_OK; }
//多线程查询边数目 uint32_t Client::get_edge_num_pthread(uint32_t **nums,uint32_t *size){ if(current_graph()=="") return STATUS_NOT_EXIST;//如果还没有连接图,则返回状态STATUS_NOT_EXIST //获取所有节点的ip vector<string> ips; get_all_meta(ips); //多线程的发送,所以要给每个线程数据 *size=ips.size(); *nums=new uint32_t[*size]; Ip_Graph* datas=new Ip_Graph[*size]; uint32_t index=0; pthread_t *threads=new pthread_t[*size]; for(int index=0;index<*size;index++){ datas[index].graph_name=graph_name; datas[index].sock=find_sock(ips[index]); datas[index].nums=&(*nums)[index]; pthread_create(&threads[index],NULL,thread_get_edge_num,&datas[index]); } //等待线程的运行完成 for(index=0;index<*size;index++){ pthread_join(threads[index],NULL); } delete[] datas; delete[] threads; return STATUS_OK; }
//根据某个属性范围,查询所有的边 uint32_t Client::read_edge_index_range(list<Edge_u> &edges,string min,string max){ if(current_graph()=="") return STATUS_NOT_EXIST;//如果还没有连接图,则返回状态STATUS_NOT_EXIST //如果连接图了,则首先找图和顶点的元数据,先在缓存中找,没找到再去master询问 string ip=string(getenv("LOCAL_IP")); Requester req_slave(*find_sock(ip)); proto_blog_id_range mes_slave(graph_name,min,max); req_slave.ask(CMD_GET_INDEX_RANGE_EDGE,&mes_slave,sizeof(proto_blog_id_range)); req_slave.parse_ans(edges); return STATUS_OK; }
//返回一个顶点的所有边 uint32_t Client::read_edges(v_type id,list<Edge_u>& edges){ if(current_graph()=="") return STATUS_NOT_EXIST;//如果还没有连接图,则返回状态STATUS_NOT_EXIST //如果连接图了,则首先找图和源顶点的元数据,先在缓存中找,没找到再去master询问 string ip=get_meta(graph_name,id); Requester req_slave(*find_sock(ip)); proto_graph_vertex mes_slave(graph_name,id); req_slave.ask(CMD_READ_EDGES,&mes_slave,sizeof(proto_graph_vertex)); req_slave.parse_ans(edges); return req_slave.get_status(); }
//增加一条边,顶点不存在的时候不会自动创建顶点,添加边就会失败 uint32_t Client::add_edge(Edge_u &e){ if(current_graph()=="") return STATUS_NOT_EXIST;//如果还没有连接图,则返回状态STATUS_NOT_EXIST //如果连接图了,则首先找图和源顶点的元数据,先在缓存中找,没找到再去master询问 string ip=get_meta(graph_name,e.s_id); Requester req_slave(*find_sock(ip)); proto_edge_u mes_slave(graph_name,e); req_slave.ask(CMD_ADD_EDGE,&mes_slave,sizeof(proto_edge_u)); req_slave.parse_ans(); return req_slave.get_status();//返回结果 }
//查询出度在某个范围内的顶点 uint32_t Client::read_index_vertex(list<Vertex_u>& vertexes,e_type min,e_type max){ if(current_graph()=="") return STATUS_NOT_EXIST;//如果还没有连接图,则返回状态STATUS_NOT_EXIST //如果连接图了,则首先找图和顶点的元数据,先在缓存中找,没找到再去master询问 string ip=string(getenv("LOCAL_IP")); Requester req_slave(*find_sock(ip)); proto_graph_cd mes_slave(graph_name,min,max); req_slave.ask(CMD_GET_INDEX_VERTEX,&mes_slave,sizeof(proto_graph_cd)); req_slave.parse_ans(vertexes); return STATUS_OK; }
//增加一个顶点 uint32_t Client::add_vertex(Vertex_u &v){ if(current_graph()=="") return STATUS_NOT_EXIST;//如果还没有连接图,则返回状态STATUS_NOT_EXIST //先得到元数据信息,也就是顶点所在ip string ip=get_meta(graph_name,v.id); //向slave添加顶点 Requester req_slave(*find_sock(ip)); proto_graph_vertex_u mes_slave(graph_name,v); req_slave.ask(CMD_ADD_VERTEX,&mes_slave,sizeof(proto_graph_vertex_u)); req_slave.parse_ans(); return req_slave.get_status();//返回结果 }
//多线程版,批量增加边,如果num不为空,则存储实际添加的边的数目,因为有些顶点可能不存在,添加就会失败 uint32_t Client::add_edges_pthread(list<Edge_u> &edges,uint32_t *num){ if(current_graph()=="") return STATUS_NOT_EXIST;//如果还没有连接图,则返回状态STATUS_NOT_EXIST //找所有边的元数据,由于有缓存,这个操作不会成为瓶颈。边在获取元数据的时候按照ip分类 unordered_map<string,list<Edge_u>*> classify; list<Edge_u>::iterator it=edges.begin(); unordered_map<string,list<Edge_u>*>::iterator it_cl; string ip; while(it!=edges.end()){ ip=get_meta(graph_name,(*it).s_id); it_cl=classify.find(ip); if(it_cl==classify.end()){ //如果没有这个ip类,则创建,然后把边加入到该ip类 classify.insert(pair<string,list<Edge_u>*>(ip,new list<Edge_u>())); it_cl=classify.find(ip); it_cl->second->push_back(*it); }else{ it_cl->second->push_back(*it); } it++; } //元数据查完后,就开始分别把每个ip类的边发送出去 uint32_t size=classify.size(); Ip_Edges* datas=new Ip_Edges[size]; uint32_t index=0; pthread_t *threads=new pthread_t[size]; it_cl=classify.begin(); while(it_cl!=classify.end()){ datas[index].graph_name=graph_name; datas[index].sock=find_sock(it_cl->first); datas[index].edges=it_cl->second; datas[index].num=0; pthread_create(&threads[index],NULL,thread_add_edges,&datas[index]); index++; it_cl++; } //等待线程的运行完成 for(index=0;index<size;index++){ pthread_join(threads[index],NULL); } //计算成功添加的边数 if(num!=NULL){ *num=0; for(index=0;index<size;index++){ *num+=datas[index].num; } } //清理内存 for(index=0;index<size;index++){ delete datas[index].edges; } delete[] datas; delete[] threads; return STATUS_OK; }
//多线程批量读取边 uint32_t Client::read_two_edges_pthread(list<Two_vertex>& vertexes,list<Edge_u> **edges,uint32_t *size){ if(current_graph()=="") return STATUS_NOT_EXIST;//如果还没有连接图,则返回状态STATUS_NOT_EXIST //找所有边的元数据,由于有缓存,这个操作不会成为瓶颈。边在获取元数据的时候按照ip分类 unordered_map<string,list<Two_vertex>*> classify; list<Two_vertex>::iterator it=vertexes.begin(); unordered_map<string,list<Two_vertex>*>::iterator it_cl; string ip; while(it!=vertexes.end()){ ip=get_meta(graph_name,(*it).s_id); it_cl=classify.find(ip); if(it_cl==classify.end()){ //如果没有这个ip类,则创建,然后把边加入到该ip类 classify.insert(pair<string,list<Two_vertex>*>(ip,new list<Two_vertex>())); it_cl=classify.find(ip); it_cl->second->push_back(*it); }else{ it_cl->second->push_back(*it); } it++; } //元数据查完后,就开始分别把每个ip类的顶点对发送出去,多线程的发送,所以要给每个线程数据 *size=classify.size(); *edges=new list<Edge_u>[*size]; Ip_Two_Vertex* datas=new Ip_Two_Vertex[*size]; uint32_t index=0; pthread_t *threads=new pthread_t[*size]; it_cl=classify.begin(); while(it_cl!=classify.end()){ datas[index].graph_name=graph_name; datas[index].sock=find_sock(it_cl->first); datas[index].vertexes=it_cl->second; datas[index].edges=&(*edges)[index]; pthread_create(&threads[index],NULL,thread_read_two_edges,&datas[index]); index++; it_cl++; } //等待线程的运行完成 for(index=0;index<*size;index++){ pthread_join(threads[index],NULL); } //清理内存 for(index=0;index<*size;index++){ delete datas[index].vertexes; } delete[] datas; delete[] threads; return STATUS_OK; }
//查询顶点的信息,如果顶点存在则返回ok状态,不存在返回 uint32_t Client::read_vertex(v_type id,Vertex_u& v,uint32_t *num){ if(current_graph()=="") return STATUS_NOT_EXIST;//如果还没有连接图,则返回状态STATUS_NOT_EXIST //如果连接图了,则首先找图和顶点的元数据,先在缓存中找,没找到再去master询问 string ip=get_meta(graph_name,id); Requester req_slave(*find_sock(ip)); proto_graph_vertex mes_slave(graph_name,id); req_slave.ask(CMD_READ_VERTEX,&mes_slave,sizeof(proto_graph_vertex)); req_slave.parse_ans(); uint32_t res=req_slave.get_status(); if(res==STATUS_OK){ proto_vertex_num *mes=(proto_vertex_num*)req_slave.get_data(); v=mes->vertex; *num=mes->num; } return res; }
bool operator()(boost::filesystem::path const &input_file) { Graph &graph = current_graph(); if (visited_.find(input_file) == visited_.end()) { visited_.insert(input_file); if (boost::filesystem::is_directory(input_file)) { /* avoid infinite recursion */ if (boost::filesystem::is_symlink(input_file)) { std::set<boost::filesystem::path> deps; std::auto_ptr<Collector> collector = Collector::get_collector(input_file); if (collector.get()) { (*collector)(deps); if (deps.size() == 0) assert(deps.size() == 1); (*this)(*deps.begin()); } } /* recurse through directories */ else { logging::log(logging::info) << "walking directory: " << input_file << std::endl; boost::system::error_code ec; std::vector<boost::filesystem::path> children; for (boost::filesystem::directory_iterator node(input_file, ec), end; node != end; node.increment(ec)) { if (not ec) children.push_back(node->path()); } BOOST_FOREACH(boost::filesystem::path const & child, children) { if(! (*this)(child) ) { logging::log(logging::warning) << "skipping entry '" << child.string() << std::endl; // TODO: native() vs. // string on windows } } } } else if (boost::filesystem::is_other(input_file)) {
//批量增加边,如果num不为空,则存储实际添加的边的数目,因为有些顶点可能不存在,添加就会失败 uint32_t Client::add_edges(list<Edge_u> &edges,uint32_t *num){ if(current_graph()=="") return STATUS_NOT_EXIST;//如果还没有连接图,则返回状态STATUS_NOT_EXIST //找所有边的元数据,由于有缓存,这个操作不会成为瓶颈。边在获取元数据的时候按照ip分类 unordered_map<string,list<Edge_u>*> classify; list<Edge_u>::iterator it=edges.begin(); unordered_map<string,list<Edge_u>*>::iterator it_cl; string ip; while(it!=edges.end()){ ip=get_meta(graph_name,(*it).s_id); it_cl=classify.find(ip); if(it_cl==classify.end()){ //如果没有这个ip类,则创建,然后把边加入到该ip类 classify.insert(pair<string,list<Edge_u>*>(ip,new list<Edge_u>())); it_cl=classify.find(ip); it_cl->second->push_back(*it); }else{ it_cl->second->push_back(*it); } it++; } //元数据查完后,就开始分别把每个ip类的边发送出去 if(num!=NULL) *num=0; it_cl=classify.begin(); while(it_cl!=classify.end()){ Requester req_slave(*find_sock(it_cl->first)); req_slave.ask(CMD_ADD_EDGES,*(it_cl->second),graph_name); req_slave.parse_ans(); if(num!=NULL){ //统计插入的边的数目 *num+=atoi((char*)req_slave.get_data()); } delete it_cl->second;//这个ip类的边插完了,则释放空间 it_cl++; } return STATUS_OK; }