⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chord.mac

📁 这是一个著名的应用层组播中间件的源码
💻 MAC
📖 第 1 页 / 共 2 页
字号:
  joined recv update_pred {    neighbor_finger *predent = neighbor_random( pred);    // check to see if sending node should be our predecessor    if (isinrange( field(id), predent->hashf, myhash)) {      sprintf(trace_buf_, "change pred: old %.8x new %.8x\n", predent->hashf, field(id));      trace_print();      neighbor_remove( pred, predent->ipaddr);      neighbor_add( pred, from);      predent->hashf = field(id);      upcall_notify(pred,NBR_TYPE_PEER);    }  }  joined timer fix_fingers {    // responsible for lazily correcting route (finger) table entries    int myrand, start, powow, nextguy;    neighbor_finger *myent, *predent;    myent = neighbor_random(myfinger[0]);    predent = neighbor_random(pred);    if (predent->ipaddr == me || myent->ipaddr == me)       return; // if i am alone in this ring, get out    myrand = randint(BITS-1) + 1; // select a random finger entry    start = (int)pow(2, myrand);    start = start + myhash; // the start address for this entry    // route a find pred toward this start address    nextguy = nexthop(start);    route_find_pred( nextguy, start, me, 0, 0, -1);     powow = myhash - start; // go backwards in the ring to correct others    // route an update others message toward them    nextguy = nexthop(powow);    route_update_others( nextguy, powow, myhash, me, 0, 0, -1);  }  joined recv find_pred_reply {    // when attempting to fix my finger table, I will get replies from nodes    // to consider    register_knowledge(field(succ), field(succ_id)); // update fingers  }  joined recv update_others {    int sendupdate, nextguy;    neighbor_finger *predent, *myent;    sendupdate = 0;  // don't send an update unless we change a finger entry    myent = neighbor_random(myfinger[0]); // successor    predent = neighbor_random(pred); // predecessor          if (isinrange(field(id), myhash, myent->hashf)) { // final destination      sendupdate = register_knowledge(field(who), field(node));      if (sendupdate == 1 && predent->ipaddr != me 	  && predent->ipaddr != field(who)) {        route_update_ft(predent->ipaddr, field(node), field(who), 0, 0, -1);      }      return;    }    nextguy = nexthop (field(id));    if (nextguy != me) { // route the message      route_update_others(nextguy, field(id), field(node), field(who), 0, 0, -1);    }  }  joined recv update_ft {    int mybit, loopbit, sendupdate, powow;    neighbor_finger *myent, *predent;    sendupdate = register_knowledge(field(who), field(node));    if (sendupdate == 1 && predent->ipaddr != me && predent->ipaddr != field(who)) { // only propagate if my state actually changed      route_update_ft( predent->ipaddr, field(node), field(who), 0, 0, -1);    }  }  any recv mapping {    map.insert(field(low_hash), field(high_hash), field(map_ip));    }  joined recv data {    routedata(field(sender_hash), field(sender_ip), field(receiver_hash), size, field(priority), msg, 0);  }  joined recv data_path_req {    routedata(field(sender_hash), field(sender_ip), field(receiver_hash), size, field(priority), msg, 1);  }  API route {    routedata(hashof(me), me, dest, size, transport, msg, 0);  }  API routeIP {    routedata(hashof(me), me, dest, size, transport, msg, 1);  }  any timer printer {    dump_state();  }  API downcall_ext {    switch(operation) {      case TEST_OWNER:          {          test_owner_arg *targ = (test_owner_arg*)arg;          neighbor_finger *predent;          predent = neighbor_random(pred);          return isinrangeright(targ->nodeId,predent->hashf,myhash);        }      default:         { //downcall not supported          return -1;        }    }    return 0;  }  API error {    neighbor_finger *myent, *myent2;    int loopbit;    sprintf(trace_buf_, "Neighbor %.8x died!\n", neighbor);    trace_print();    if (neighbor_query(pred, neighbor)) { // predecessor died      neighbor_remove(pred, neighbor);      myent = neighbor_random(myfinger[BITS-1]);      neighbor_add(pred, myent->ipaddr);      myent2 = neighbor_random(pred);      myent2->hashf = myent->hashf;      upcall_notify(pred,NBR_TYPE_PEER);    }    for (loopbit = BITS-1; loopbit>=1; loopbit--) {      if (neighbor_query(myfinger[loopbit], neighbor)) {        myent = neighbor_random(myfinger[loopbit-1]);        neighbor_remove(myfinger[loopbit], neighbor);        neighbor_add(myfinger[loopbit], myent->ipaddr);      }    }    if (neighbor_query(myfinger[0], neighbor)) { // successor diede      myent = neighbor_random(myfinger[0]);      int old_start = myent->start;      neighbor_remove(myfinger[0], neighbor);      if (neighbor_size (successors_succ))        myent = neighbor_random(successors_succ);      else        myent = neighbor_random(myfinger[1]);      neighbor_add(myfinger[0], myent->ipaddr);      myent2 = neighbor_random(myfinger[0]);      myent2->start = old_start;      myent2->hashf = myent->hashf;    }  }}routines {  int nexthop (int target) {    int i,j,done;    neighbor_finger *predent, *myent, *myent2;    done = 0; // haven't found the next hop yet    // first check if the target is beyond last finger    j = 0;    i = BITS-1;    myent = neighbor_random(myfinger[i]);    myent2 = neighbor_random(myfinger[j]);    if (isinrange( target, myent->start, myent2->start )) {      done = 1;    }    for (j = BITS-1; j > 0; j--) { // loop thru fingers to find right one      if (done == 0) {        i = j - 1;        myent = neighbor_random(myfinger[i]);        myent2 = neighbor_random(myfinger[j]);        if (isinrange( target, myent->start, myent2->start )) {          done = 1;        }      }    }    done = 0; // reset flag    for (j = i; j >= 0; j--) { // backs up to make sure that we forward to       // a node strictly before target      if (isinrange( myent->hashf, myent->start, target )) {        if (myent->start != target) {          done = 1;        }      }      if (myent->ipaddr == me || done == 0) { // still looking	// note that I should not forward to myself (lightly populated case)        myent = neighbor_random(myfinger[j]);      }    }    return myent->ipaddr;  // could return me if i am the only node  }  int register_knowledge (int target_ip, int target_hash) {    // updates the appropriate finger table entry     // returns 1 if an update occurred    int mybit, loopbit, powow;    int change=0;    neighbor_finger *predent, *myent, *myent2;    mybit = BITS-1;    for (loopbit = mybit; loopbit >= 0; loopbit--) {      myent = neighbor_random(myfinger[loopbit]);      powow = myent->start;      if (isinrange(target_hash, powow, myent->hashf)) {	sprintf(trace_buf_, "change finger %d: old %.8x new %.8x start %.8x\n", loopbit, myent->hashf, target_hash, powow);	trace_print();	change=1;	neighbor_remove( myfinger[loopbit], myent->ipaddr );	neighbor_add( myfinger[loopbit], target_ip);	myent = neighbor_random( myfinger[loopbit] );	myent->hashf = target_hash;	myent->start = powow;      }    }    return change;  }    void routedata (int route_from, int from_ip, int route_dest, int route_size, int route_transport, char *route_msg, int pathreq) {    int should_forward, nextguy;    neighbor_finger *predent;        predent = neighbor_random(pred);        if (isinrangeright(route_dest, predent->hashf, myhash)) {       // final destiation    }    else { // trying to route through      nextguy = nexthop(route_dest);      if (nextguy != me) { // I can route it	if (!pathreq)	  should_forward = upcall_forward(nextguy, route_msg, route_size, COMM_TYPE_UNICAST);	else 	  should_forward = 0;	if (should_forward == 0) {	  if (!pathreq) {  // no need to check cache, routing thru overlay	    route_data( nextguy, route_dest, from_ip, route_from, route_transport, route_msg, route_size, route_transport);	  }	  else { // requesting cache services	    int lower = map.query(route_dest);	    if (lower) {   // he's in my cache	      route_data( lower, route_dest, from_ip, route_from, route_transport, route_msg, route_size, route_transport);	    }	    else {	      route_data_path_req( nextguy, route_dest, from_ip, route_from, route_transport, route_msg, route_size, route_transport);	    }	  }	}	return;      }    }    // I must be the final destination    // I may be the only node in the system    should_forward = upcall_forward( 0, route_msg, route_size, COMM_TYPE_UNICAST);    if (should_forward == 0) {      //          printf("deliverance 1 dest %.8x, pred %.8x, mine %.8x\n", route_dest, predent->hashf, myhash);      int low;      if (predent->ipaddr == me)	low = myhash;      else	low = predent->hashf-1;      if(pathreq && from_ip!=me) { // send a mapping if possible	route_mapping(from_ip, low, myhash, me, 0, 0, -1);      }      upcall_deliver( route_msg, route_size, COMM_TYPE_UNICAST);    }  }}

⌨️ 快捷键说明

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