coop-agent.cc

来自「模拟器提供了一个简单易用的平台」· CC 代码 · 共 2,021 行 · 第 1/5 页

CC
2,021
字号
        if (l->ag_list.Locate(pred_aid) == NULL) { 	  count_pkts += send_data_pkt_to_layer(l,src_aid,src_nid,src_seqno);        }      }    }  }  if (state == JOIN) {    if ( (curr_join_q_lid < MAX_LAYERS) && (curr_join_q_lid > 0) ) {      LayerInfo * q_l = layers.arr[curr_join_q_lid];      assert (q_l != NULL);      assert (q_l->me_in_layer == false);      count_pkts += send_data_pkt_to_layer(q_l,src_aid,src_nid,src_seqno);    }    if (curr_join_q_lid < 0) { // Starting join query at BSE      // For join to higher layers, we probably already have the higher      // target layer from the previous leader which left the cluster or      // did a root xfer to me. Can use that as a fall back option.      // This should not be for layer 0.      LayerInfo * target_layer = layers.arr[target_join_q_lid];      if (target_layer != NULL) {	assert (target_layer->me_in_layer == false);	count_pkts += send_data_pkt_to_layer(target_layer,src_aid,src_nid,src_seqno);      }    }  }  if (is_source == true) {       AppPacket *ap = new AppPacket(PACKET_DATA);       ap->u.data_p.original_src.agent_id = src_aid;       ap->u.data_p.original_src.node_id = src_nid;       ap->u.data_p.seq_no = src_seqno;       ap->u.data_p.lid = -1;#ifdef LOG_DATA_PACKET_SEND       printf ("[coop %d %d ] At %8.4f send data-pkt : < [ %d %d ] > seq %d : to < [ %d %d ] > bse\n", id, n->id, Scheduler::Clock(), src_aid, src_nid, src_seqno, bse.agent_id, bse.node_id);#endif // LOG_DATA_PACKET_SEND       send_pkt_wrapper(ap,bse.agent_id, bse.node_id);       count_pkts ++;  }#ifdef LOG_DATA_PACKET_SEND_COUNT  if (count_pkts > 0)    printf ("[coop %d %d ] At %8.4f fwd-data count %d for < [ %d %d ]> seq-no %d\n",id, n->id, Scheduler::Clock(), count_pkts, src_aid, src_nid, src_seqno);#endif // LOG_DATA_PACKET_SEND_COUNT  return;}int coopAgent::send_data_pkt_to_layer (LayerInfo * l, int src_aid, int src_nid, int src_seqno) {  int count_pkts = 0;  for (void * pos = l->ag_list.GetHeadPosition();       pos != NULL;       l->ag_list.GetNext(pos) ) {    LayerAgentInfo * this_la = l->ag_list.GetAt(pos);    if (self_check(this_la) == false) {      if ( ( (bse.agent_id != this_la->ag.agent_id) || (bse.node_id != this_la->ag.node_id) ) &&         ( ( (this_la->ag.agent_id != src_aid) || (this_la->ag.node_id != src_nid) ) ) ) {       AppPacket *ap = new AppPacket(PACKET_DATA);       ap->u.data_p.original_src.agent_id = src_aid;       ap->u.data_p.original_src.node_id = src_nid;       ap->u.data_p.seq_no = src_seqno;       ap->u.data_p.lid = l->lid;#ifdef LOG_DATA_PACKET_SEND       printf ("[coop %d %d ] At %8.4f send data-pkt : < [ %d %d ] > seq %d : to < [ %d %d ] > lid %d\n", id, n->id, Scheduler::Clock(), src_aid, src_nid, src_seqno, this_la->ag.agent_id, this_la->ag.node_id, l->lid);#endif // LOG_DATA_PACKET_SEND       send_pkt_wrapper(ap,this_la->ag.agent_id, this_la->ag.node_id);       count_pkts ++;     }   } }  return count_pkts;}/* Have to be the cluster root to accept this merge *//* If we want to accept cluster merge at non-root agents, then * we have to change the mechanism of the merge, i.e. the merging * root should be able to first figure out which is the correct * root, and then advise the children appropriately of its * change to be the new correct root. */bool coopAgent::valid_cluster_merge_packet (AppPacket * ap) {  LayerInfo *l = layers.arr[ap->u.clustermerge_p.layer_id];  if (l == NULL)    return false;  if (l->me_in_layer == false)    return false;  if (self_check(l->root) == false)    return false;  return true;}bool coopAgent::valid_cluster_refresh_packet (AppPacket * ap) {  LayerInfo * l = layers.arr[ap->u.clusterrefresh_p.layer_id];  if (l == NULL)    return false;  if (l->me_in_layer == false)    return false;  void * pos = l->ag_list.Locate(ap->src_agent);  if (pos == NULL)    return false;  return true;}bool coopAgent::match_cluster_to_root_info (LayerInfo *l) {  bool has_change = false;  for (void * pos = l->ag_list.GetHeadPosition();       pos != NULL;       l->ag_list.GetNext(pos) ) {    LayerAgentInfo * la_ag = l->ag_list.GetAt(pos);    la_ag->valid_tmp = false;  }  for (int i = 0; i < l->root->agent_dist_arr_count; i++) {    void * pos = l->ag_list.Locate(l->root->agent_dist_arr[i].ag.agent_id);    LayerAgentInfo * this_la;    if (pos == NULL) {      this_la = new LayerAgentInfo (l->root->agent_dist_arr[i].ag.agent_id,l->root->agent_dist_arr[i].ag.node_id);      assert (self_check(this_la) == false); // Cannot have self unknown      l->AddClusterMember(this_la);      has_change = true;    }    else {      this_la = l->ag_list.GetAt(pos);    }    this_la->valid_tmp = true;  }  // Purge the members that are not in the cluster any more  for (void * pos = l->ag_list.GetHeadPosition();       pos != NULL;       ) {        LayerAgentInfo * la_ag = l->ag_list.GetAt(pos);    void * old_pos = pos;    l->ag_list.GetNext(pos);    if (la_ag->valid_tmp == false) {      l->ag_list.RemoveAt(old_pos);      assert (la_ag != NULL);      delete la_ag;      has_change = true;    }  }  return has_change;}/* Send query to the next lower layer if needed (i.e. to * one below this_lid). * If this is the target layer, then need to figure out point of * attachment */void coopAgent::continue_join_query (int this_lid) {#ifdef LOG_COOP_JUNK  printf ("[coop %d %d ] At %8.4f (c-cjq) : continue-join-query : lid %d\n", id, n->id, Scheduler::Clock(), this_lid);#endif // LOG_COOP_JUNK  if (this_lid > target_join_q_lid) { /* Probe all the cluster members */    LayerInfo *l = layers.arr[this_lid];    void * pos = l->ag_list.Locate(id);    if (pos != NULL) { // I am considered to be part of this cluster !      assert (self_check(l->root) == false); // I cannot be the root      delete_self_from_layer(l);      }#ifdef LOG_COOP_JUNK    printf ("[coop %d %d ] . . (c-cjq) : join-continue\n", id, n->id);#endif // LOG_COOP_JUNK    send_join_query_to_cluster(this_lid);    m_join_resp_received = 0;    curr_join_q_lid = this_lid;    jqt.SetTimer(CONST_JOIN_QUERY_TIMEOUT);    return;  }  else { /* Find point of attachment */    assert (this_lid == target_join_q_lid);    LayerInfo * lbase = layers.arr[this_lid];    LayerAgentInfo *self = new LayerAgentInfo(id,n->id);    self->dist = 0.0;    if (lbase->AddClusterMember(self) == false) {      delete self;      self = lbase->FindClusterMember(id);      assert(self->dist >= 0.0);    }    lbase->me_in_layer = true;        assert (lbase->root != NULL);    if (lbase->root->dist < 0.0)      assert (lbase->root->dist >= 0.0);    AppPacket *pkt = new AppPacket(JOIN_QUERY);    init_join_query_packet(pkt,this_lid,Scheduler::Clock(),true);    send_pkt_wrapper(pkt,lbase->root->ag.agent_id, lbase->root->ag.node_id);    lbase->cr_msgt.SetTimer(CONST_CLUSTER_REFRESH_MSG_TIMEOUT);    lbase->cr_chkt.SetTimer(CONST_CLUSTER_REFRESH_CHECK_TIMEOUT);    state = ATTACHED;    set_higher_layer_ping_timer();#ifdef LOG_COOP_JUNK    printf ("[coop %d %d ] . . (c-cjq) : attach to my-root < [ %d %d ] >\n", id, n->id, lbase->root->ag.agent_id,lbase->root->ag.node_id);#endif // LOG_COOP_JUNK    log_cluster_change_info(lbase->lid);#ifdef LOG_COOP_CLUSTER_CHANGE    display_cluster_info(lbase,lbase->lid);#endif // LOG_COOP_CLUSTER_CHANGE  }  return;}bool coopAgent::valid_join_query_forward_packet (int qlid, bool attach) {    if ( (qlid < 0) || ( (qlid == 0) && (attach == false) ) ) {     /* Wrong packet */    printf ("[Err] Found packet with qlid %d\n",qlid);    assert (0);    return false;  }    int lower_lid;  if (attach == true) /* This is an attach request */    lower_lid = qlid;  else    lower_lid = qlid - 1;  if (layers.arr[lower_lid] == NULL)    return false;  /* I must be part of this cluster. */  if (layers.arr[lower_lid]->me_in_layer == false)    return false;  return true;}/* Returns true if this is a valid join response packet that * we are expecting */bool coopAgent::valid_join_response_packet (AppPacket *ap) {  if (state != JOIN)    return false;  int this_lid = ap->u.joinresp_p.layer_id;  if ( (ap->src_agent == bse.agent_id) && (ap->src == bse.node_id) ) {    if (curr_join_q_lid != -1) // BSE-JF && (curr_join_q_lid != (this_lid+1) )      return false;    if (target_join_q_lid > this_lid) {      assert (0);      return false;    }  }  else { /* Check for other layer queries */    if (curr_join_q_lid != (this_lid+1))      return false;    LayerInfo * last_layer = layers.arr[curr_join_q_lid];    if (last_layer == NULL)      return false;    if (last_layer->ag_list.Locate(ap->u.joinresp_p.exp_src.agent_id) == NULL)      return false;  }  return true;}/* Sends a join query to all members specified in the given * layer. The expected response is all members in the immediate * lower layer. */void coopAgent::send_join_query_to_cluster (int layer_lid) {  LayerInfo * this_layer = layers.arr[layer_lid];#ifdef LOG_COOP_SEND    printf ("[coop %d %d ] At %8.4f (c-jqtc) : join-query-to-cluster : lid %d\n", id, n->id, Scheduler::Clock(), layer_lid);#endif // LOG_COOP_SEND  for (void * pos = this_layer->ag_list.GetHeadPosition();       pos != NULL;       this_layer->ag_list.GetNext(pos) ) {    LayerAgentInfo * coop_ag = this_layer->ag_list.GetAt(pos);    if ( (coop_ag->ag.agent_id == bse.agent_id) && (coop_ag->ag.node_id == bse.node_id) ) // Dont send this join query to the BSE      continue;    AppPacket *p = new AppPacket(JOIN_QUERY);    init_join_query_packet (p,layer_lid,Scheduler::Clock(),false);    send_pkt_wrapper(p,coop_ag->ag.agent_id,coop_ag->ag.node_id);#ifdef LOG_COOP_SEND    printf ("[coop %d %d ] . . (c-jqtc) < [ %d %d ] >\n", id, n->id, coop_ag->ag.agent_id, coop_ag->ag.node_id);#endif // LOG_COOP_SEND  }#ifdef LOG_COOP_SEND  printf ("\n");#endif // LOG_COOP_SEND  return;}void coopAgent::cancel_higher_layer_ping_timers (void) {  if (m_ping_in_progress == true) {    m_ping_in_progress = false;    m_hlprt.CancelTimer();    flush_lower_layers(layers.arr[m_ping_lid]);  }  m_hlpit.CancelTimer();  return;}void coopAgent::set_higher_layer_ping_timer (void) {  m_hlpit.SetTimer(CONST_HIGHER_LAYER_PING_INTERVAL_TIMEOUT);  return;}void coopAgent::handle_join_query_timeout (void) {  process_received_join_responses();  return;}void coopAgent::process_received_join_responses (void) {  assert (state == JOIN);  if (curr_join_q_lid  == -1) { /* BSE defaulted ! */    printf ("[coop %d %d ] At %8.4f BSE did not respond to join-query\n", id, n->id, Scheduler::Clock());    init_join_query(-1);#ifdef LOG_COOP_JUNK    printf ("[coop %d %d ] At %8.4f process-join-resps : bse defaults target lid %d\n", id, n->id, Scheduler::Clock(), target_join_q_lid);#endif // LOG_COOP_JUNK    return;  }  /* Find the closest agent to this member and re-start   * the query business for the lower layer */  LayerInfo * this_layer = layers.arr[curr_join_q_lid];  void * pos = this_layer->ag_list.Locate(id);  assert (pos == NULL);  LayerAgentInfo * min_dist_la_ag = find_closest_agent_in_layer(this_layer,NULL,true);  if (min_dist_la_ag != NULL) {    /* Send next set of queries if needed. */    // assert (layers.arr[curr_join_q_lid] == NULL); THIS ONE WAS WRONG    if (min_dist_la_ag->dist < 0.0)      printf ("[Err] At %f [ %d %d ] found closest agent [ %d %d ] with neg dist\n", Scheduler::Clock(), id, n->id, min_dist_la_ag->ag.agent_id, min_dist_la_ag->ag.node_id);    int lower_lid = curr_join_q_lid - 1;    flush_layer(lower_lid);    layers.arr[lower_lid] = min_dist_la_ag->lower_layer;    min_dist_la_ag->lower_layer = NULL;        LayerAgentInfo * mdla_in_lower = layers.arr[lower_lid]->FindClusterMember(min_dist_la_ag->ag.agent_id);    assert (mdla_in_lower != NULL);    mdla_in_lower->dist = min_dist_la_ag->dist;#ifdef LOG_COOP_JUNK    printf ("[coop %d %d ] At %8.4f process-join-resps : lid %d closest < [ %d %d ] > dist %f\n", id, n->id, Scheduler::Clock(), curr_join_q_lid, min_dist_la_ag->ag.agent_id, min_dist_la_ag->ag.node_id, min_dist_la_ag->dist);#endif // LOG_COOP_JUNK    continue_join_query(lower_lid);  }  else { /* Have to re-query the higher layer if no one in	  * curr_join_q_lid responded. */#ifdef LOG_COOP_JUNK    printf ("[coop %d %d ] At %8.4f process-join-resps  layer defaults lid %d\n", id, n->id, Scheduler::Clock(), this_layer->lid);#endif // LOG_COOP_JUNK    delete this_layer;    layers.arr[curr_join_q_lid] = NULL;    int higher_lid = curr_join_q_lid + 1;    if (higher_lid < MAX_LAYERS) {      if (layers.arr[higher_lid] != NULL) { /* Retry from the higher layer */	continue_join_query(higher_lid);      }      else { /* Have to re-start with the BSE */	init_join_query(-1);      }    }  }  return;}/* Find a new leader in the cluster. I am leaving this cluster, * so I am not included in this. */LayerAgentInfo * coopAgent::find_new_cluster_leader (LayerInfo *l, bool omit_self) {  if (l->root != NULL)    assert (self_check(l->root) == true);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?