void solution::move_vertices( const std::list< std::pair<size_t,size_t> > & move_list ) { std::list<std::pair<page_iterator_t,edge_t> > all_touching_edges; for( auto i= move_list.begin(); i!= move_list.end(); ++i ) { size_t index1= i->first; size_t to_pos= i->second; if( index1 >= spine_order.size() || to_pos > spine_order.size() ) { throw std::out_of_range("move vertices outside of index range"); } std::list<std::pair<page_iterator_t,edge_t> > touching_edges; // collect touching edges for( auto p= pages.begin(); p != pages.end(); ++p ) for( auto e= p->edges.begin(); e != p->edges.end(); ++e ) if( e->first == spine_order[index1] || e->second == spine_order[index1] ) { touching_edges.push_back( make_pair(p,*e) ); all_touching_edges.push_back( make_pair(p,*e) ); } // remove touching edges for( auto i= touching_edges.begin(); i != touching_edges.end(); ++i ) remove_edge( * i->first, i->second ); // // moving spine order if( to_pos < spine_order.size() ) move_range( index1, 1, to_pos, spine_order ); else append_range( index1, 1, spine_order ); } // new order map int order_count= 0; for( auto v=spine_order.begin(); v!= spine_order.end(); ++v ) { spine_order_map[ *v ]= order_count++; } // re -add edges for( auto i= all_touching_edges.begin(); i != all_touching_edges.end(); ++i ) add_edge( * i->first, i->second ); }
int64_t ClusterMigrate::migrate_kv_data(Node *src_node, Node *dst_node, int num_keys){ src = init_client(src_node->ip, src_node->port); if(src == NULL){ log_error("failed to connect to server!"); return -1; } dst = init_client(dst_node->ip, dst_node->port); if(dst == NULL){ log_error("failed to connect to server!"); return -1; } if(check_version(src) == -1){ return -1; } if(check_version(dst) == -1){ return -1; } ssdb::Status s; KeyRange src_range = src_node->range; KeyRange dst_range = dst_node->range; log_info("old src %s", src_range.str().c_str()); log_info("old dst %s", dst_range.str().c_str()); std::string moved_max_key; int64_t bytes; bytes = move_range(src_range.end, &moved_max_key, num_keys); if(bytes == -1){ return -1; } if(bytes == 0){ return 0; } // update key range src_node->range = KeyRange(moved_max_key, src_range.end); { dst_node->range = KeyRange(dst_range.begin, moved_max_key); log_info("new dst: %s", dst_node->range.str().c_str()); ssdb::Status s = dst->set_kv_range(dst_node->range.begin, dst_node->range.end); if(!s.ok()){ log_fatal("dst server set_kv_range error!"); return -1; } } return bytes; }
int main(int argc, char **argv){ welcome(); AppArgs args; parse_args(&args, argc, argv); src = init_client(args.src_ip, args.src_port); if(src == NULL){ log_error("fail to connect to server!"); return 0; } dst = init_client(args.dst_ip, args.dst_port); if(dst == NULL){ log_error("fail to connect to server!"); return 0; } check_version(src); check_version(dst); KeyRange src_range; if(get_key_range(src, &src_range) == -1){ return -1; } log_info("old src %s", src_range.str().c_str()); KeyRange dst_range; if(get_key_range(dst, &dst_range) == -1){ return -1; } log_info("old dst %s", dst_range.str().c_str()); for(int i=0; i<args.limit; i+=BATCH_SIZE){ int num = BATCH_SIZE; if(args.limit - i < BATCH_SIZE){ num = args.limit - i; } // move data int ret; std::string moved_max_key; ret = move_range(src_range.start, src_range.end, num, &moved_max_key); if(ret == -1){ log_fatal("move_range error!"); exit(1); } if(ret == 0){ continue; } log_debug("moved %d key(s)", ret); while(ret == num){ // check again, make sure there is not key inserted before we lock range ret = move_range(src_range.start, moved_max_key, num, NULL); if(ret == -1){ log_fatal("move_range error!"); exit(1); } } KeyRange new_src_range(moved_max_key, src_range.end); KeyRange new_dst_range(dst_range.start, moved_max_key); log_info("src %s => %s", src_range.str().c_str(), new_src_range.str().c_str()); log_info("dst %s => %s", dst_range.str().c_str(), new_dst_range.str().c_str()); // update key range if(set_key_range(src, new_src_range) == -1){ log_fatal("src server set_kv_range error!"); exit(1); } if(set_key_range(dst, new_dst_range) == -1){ log_fatal("dst server set_kv_range error!"); exit(1); } } delete src; delete dst; return 0; }