bullet.mac
来自「这是一个著名的应用层组播中间件的源码」· MAC 代码 · 共 1,126 行 · 第 1/3 页
MAC
1,126 行
else { candidate_set<cand_bullet_summary_ticket> empty(BULLET_MAX_CANDS); route_collect(from, field(sequence), 0, empty, 0, 0, -1); printf("RanSub: send empty coll seq %d to %x\n", field(sequence), from); } delete myticket; } joined recv collect { sprintf(trace_buf_, "RanSub: got coll seq %d(%d desc.) from %x\n", field(sequence), field(descendants), from); trace_print(); if (sequence == field(sequence)) { if (neighbor_query(mychildren, from)) { neighbor_ransub_children *mykid = neighbor_entry(mychildren, from); mykid->gathered = field(mycollect); mykid->represents = field(descendants); mykid->seq = field(sequence); } joined_xmit_collect_if_need(); } } API notify { // I am being notified of changes in the tree below int i; if (type == NBR_TYPE_CHILDREN) { if (size > BULLET_MAX_CHILDREN) { printf("Exception: notified of too many children %d!\n", size); exit(54); } for (i=0; i<size; i++) { if (!neighbor_query(mychildren, neighbors[i])) { sprintf(trace_buf_, "Bullet: child %x added\n", neighbors[i]); trace_print(); neighbor_add (mychildren, neighbors[i]); neighbor_ransub_children *just_added = neighbor_entry(mychildren, neighbors[i]); just_added->seq = -1; just_added->represents = 1; just_added->bandwidth_factor = 0.1; } } int remove[BULLET_MAX_CHILDREN]; int rc=0; foreach_neighbor (neighbor_ransub_children *, kid, mychildren) { int found = 0; for (i=0; i<size; i++) { if (neighbors[i] == kid->ipaddr) found = 1; } if (found == 0) { remove[rc] = kid->ipaddr; rc++; } } for (i=0; i<rc; i++) { sprintf(trace_buf_, "Bullet: child %x removed\n", remove[i]); trace_print(); neighbor_remove (mychildren, remove[i]); } joined_xmit_collect_if_need(); } else { if (!neighbor_query(myparent, neighbors[0])) { sprintf(trace_buf_, "Bullet: parent changed to %x\n", neighbors[0]); trace_print(); neighbor_clear(myparent); neighbor_add (myparent, neighbors[0]); } } upcall_notify(mychildren, NBR_TYPE_CHILDREN); // Notify upper layer of change }} //transitionsroutines { void joined_got_multi_data() { neighbor_ransub_parent *papa; neighbor_senders_to_me *givuh; double application_spacing = (double)(parameters.getint("data_packet_size")) *8/(1000.0*(double) parameters.getint("streaming_rate")); //#define TRACE_KEY_MOD 100#ifdef TRACE_KEY_MOD if (got_key%TRACE_KEY_MOD == 0 && source_ != me) { sprintf(trace_buf_, "REPLAY_PACKET %s %s %d\n", get_hostname(got_from), get_hostname(), got_key); trace_print(); }#endif// int useful = working_file.insert( got_key, 0 ); int useful = working_file.insert( got_key, 0, (unsigned char *)got_msg, got_size ); if (got_type == BULLET_DATA_PARENT && neighbor_query(myparent, got_from)) { papa = neighbor_entry(myparent, got_from); parent_file.insert( got_key, 1); papa->arrivals.update(); if (useful) papa->useful.update(); } else if (got_type == BULLET_DATA_PARALLEL && neighbor_query(givers, got_from)) { givuh = neighbor_entry(givers, got_from); parallel_file.insert( got_key, 1); givuh->arrivals.update(); if (useful) givuh->useful.update(); } master.update(); if (useful) { total_received++; master_useful.update(); upcall_deliver( got_msg, got_size, COMM_TYPE_MULTICAST); sprintf(trace_buf_, "got useful data %d, type %d, from %.8x\n", got_key, got_type, got_from); cut_trace(); } else { sprintf(trace_buf_, "got useless data %d, type %d, from %.8x\n", got_key, got_type, got_from); cut_trace(); got_msg = 0; return; } if (!neighbor_size(mychildren)) { got_msg = 0; multicast_success_code = 0; // technically, we're OK return; // no kids, noone to send to } int current = 0; double myrandom = 0.0; int sent_this_interval=0; // int strategy = BULLET_STRAT_SPLITTER; // int strategy = BULLET_STRAT_DISJOINT; // int strategy = BULLET_STRAT_STREAMTOALL; // int strategy = BULLET_STRAT_TRY; int bullet_strategy = parameters.getint("bullet_strategy"); foreach_neighbor (neighbor_ransub_children*, kid, mychildren ) { sent_this_interval += kid->sent; kid->density = (double)kid->represents/(double) (descendants); if (kid->density > 1.0) kid->density = 1.0; } unsigned int splitter = got_key % neighbor_size(mychildren); // for splitter int sent_packet = 0; int assigned = neighbor_random(mychildren)->ipaddr; if (bullet_strategy == BULLET_STRAT_TRY) { // find out who this packet belongs and try to send it to him foreach_neighbor (neighbor_ransub_children*, kid, mychildren ) { if (sent_this_interval == 0 || (((double)kid->sent / (double)sent_this_interval) < kid->density)) { assigned = kid->ipaddr; } } neighbor_ransub_children *assigned_ent = neighbor_entry (mychildren, assigned); route_papa_data( assigned, COMM_TYPE_MULTICAST, got_key, got_msg, got_size, -1); if (!macedon_sendret) { assigned_ent->sent++; assigned_ent->kid_digest.insert(got_key); sent_packet = 1; } else { assigned_ent->not_sent++; } } foreach_neighbor (neighbor_ransub_children*, kid, mychildren ) { int should_send = 0; if (bullet_strategy == BULLET_STRAT_STREAMTOALL) { should_send = 1; } else if (bullet_strategy == BULLET_STRAT_SPLITTER) { if (splitter == 0) { should_send = 1; } splitter--; } else if (bullet_strategy == BULLET_STRAT_TRY) { if (kid->ipaddr != assigned ) { if (!sent_packet) { // this packet has not been sent yet, I will try should_send = 1; } else { // have gas if I havent missed out sending more than a little amount of what I was supposed to send int gas_to_send = (int)(1.0/kid->bandwidth_factor); // the commented kid->sent allows us to send gas to a child even // if we didn't send it any packets it's supposed to own // in this interval. Important for performance when using // unencoded content if ( // kid->sent && got_key % gas_to_send == 0 ) { should_send = 1; } } } } should_send &= (!kid->kid_digest.contains(got_key)); if (should_send) { // sprintf(trace_buf_, "Sending %d to %x strat %d\n", got_key, kid->ipaddr, bullet_strategy); // trace_print(); route_papa_data( kid->ipaddr, COMM_TYPE_MULTICAST, got_key, got_msg, got_size, -1); if (!macedon_sendret) { if (!sent_packet) { kid->sent++; } else { // was a dupe kid->gas_sent++; kid->bandwidth_factor = min(kid->bandwidth_factor+application_spacing/(double)BULLET_REFRESH_INTERVAL, 1.0); } kid->kid_digest.insert(got_key); sent_packet = 1; } else // the send didn't work if (!sent_packet) { kid->not_sent++; } else { // was a dupe anyway kid->bandwidth_factor = max(kid->bandwidth_factor-application_spacing/(double)BULLET_REFRESH_INTERVAL, 0.00001); } } else { // sprintf(trace_buf_, "Not sending %d to %x strat %d\n", got_key, kid->ipaddr, bullet_strategy); // trace_print(); } } got_msg = 0; multicast_success_code = !sent_packet; }// ---------------------------------------------- // close_peers// ---------------------------------------------- void any_close_peers() { // close peers if need be int drop = 0; double drop_bw; double least_from_me=1.0; if (sequence%3 != 0) return; // first nuke the receiver who gets the least from me if ( !neighbor_space(getters) ) { // only take one out if no space foreach_neighbor (neighbor_receivers_from_me*, gettuh, getters) { if ( curtime - gettuh->start_time > ((double)3 * BULLET_NORMAL_RANSUB) ) { // Allow at least 3 RanSub epochs for each guy to get data if (gettuh->reported_peer_bandwidth/gettuh->reported_total_bandwidth < least_from_me ) { drop = gettuh->ipaddr; least_from_me = gettuh->reported_peer_bandwidth/gettuh->reported_total_bandwidth; } } } if (drop) { neighbor_receivers_from_me *nuke = neighbor_entry(getters, drop); route_remove(nuke->ipaddr, 0, 0, -1); sprintf(trace_buf_, "Sender: Closing useless receiver %x with values %f %f %f\n", nuke->ipaddr, nuke->reported_peer_bandwidth, nuke->reported_total_bandwidth, nuke->start_time); trace_print(); neighbor_remove (getters, nuke->ipaddr); } }// foreach_neighbor (neighbor_senders_to_me*, givuh, givers) {// sprintf(trace_buf_, "rcvdst %9s %8x bw %6d use %6d lr %4.2f%% \n", // get_hostname(givuh->ipaddr), // givuh->ipaddr,// (int) givuh->arrivals.get_value(),// (int) givuh->useful.get_value(),// 0// // (application->parallel_transport ? 100*application->parallel_transport->loss_rate(givuh->ipaddr): 0)// );// trace_print();// } drop = 0; int closed_irrat=0; // then nuke the sender who gives me nothing or the one who gives me the least if ( !neighbor_space(givers) ) { // only take one out if there is no space foreach_neighbor (neighbor_senders_to_me*, givuh, givers) { if ( curtime - givuh->start_time > ((double)3 * BULLET_NORMAL_RANSUB) ) { // Allow at least 3 RanSub epochs for each guy to give us data if (givuh->useful.get_value()/givuh->arrivals.get_value() < BULLET_CLOSING_RATIO && !neighbor_query(myparent, givuh->ipaddr)) { sprintf(trace_buf_, "Receiver: Closing irrational sender %x with values %f %f\n", givuh->ipaddr, givuh->useful.get_value(), givuh->arrivals.get_value()); trace_print(); closed_irrat = givuh->ipaddr; } else if ( !drop || givuh->useful.get_value() < drop_bw) { drop = givuh->ipaddr; drop_bw = givuh->useful.get_value(); } } } if (closed_irrat) { neighbor_remove (givers, closed_irrat); route_remove(closed_irrat, 0, 0, -1); } if (!closed_irrat && drop) { neighbor_senders_to_me *nuke = neighbor_entry(givers, drop); route_remove(nuke->ipaddr, 0, 0, -1); sprintf(trace_buf_, "Receiver: Closing useless sender %x with values %f %f %f\n", nuke->ipaddr, nuke->useful.get_value(), nuke->arrivals.get_value(), nuke->start_time); trace_print(); neighbor_remove (givers, nuke->ipaddr); } } } void joined_xmit_collect_if_need() { bullet_summary_ticket* myticket = new bullet_summary_ticket(working_set::UNIVERSE_SIZE); * myticket = working_file.get_sketch(); myticket->st.address = me; int propagate=1; foreach_neighbor(neighbor_ransub_children *, kid, mychildren) { if (kid->seq != sequence && kid->seq !=-1) propagate = 0; } if (propagate) { sprintf(trace_buf_,"joined_xmit_collect_if_need: kids are okay\n"); trace_print (); } if (collect_expired) propagate = 1; if (propagate && collect_missing) { collect_missing = 0; candidate_set<cand_bullet_summary_ticket> tosend(BULLET_MAX_CANDS); if ( neighbor_space(getters) && source_ != me ) tosend.addj(myticket->st); int sofar = 1; descendants = 0; foreach_neighbor(neighbor_ransub_children *, kid, mychildren) { descendants += kid->represents; tosend.compact(kid->gathered, kid->represents, sofar); sofar+=kid->represents; if (collect_expired && kid->seq != sequence && kid->seq !=-1) { // this kid isn't ready, we timed out the collect sprintf(trace_buf_,"kid->address: %x timed out seq %d sequence %d\n", kid->ipaddr, kid->seq, sequence); trace_print (); kid->represents=0; } } if (source_ == me) { curset = tosend; // curset.printem(me); } else { neighbor_ransub_parent *papa = neighbor_random(myparent); sprintf(trace_buf_, "RanSub: sending collect sequence %d (%d desc.)to %x.\n", sequence, descendants+1, papa->ipaddr); trace_print(); route_collect(papa->ipaddr, sequence, descendants+1, tosend, 0, 0, -1); } } delete myticket; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?