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

📄 walk.c

📁 基于DHT的对等协议
💻 C
字号:
#include <async.h>#include <aios.h>#include <chord.h>#include <coord.h>#include <id_utils.h>#include <misc_utils.h>#include "rpclib.h"#define TIMEOUT 10chordID wellknown_ID = -1;int succproc (CHORDPROC_GETSUCC_EXT);bool verify = false;bool verify_errors = false;// Sequential is what we believe is the correct sequencing of nodesvec<chord_node> sequential;void getsucc_cb (u_int64_t start, chord_node curr, chord_nodelistextres *res, clnt_stat err);inline const strbuf &format (const strbuf &sb, const chord_node &node){  str x = strbuf () << node.x;  sb << strbuf ("%40s", x.cstr ()) << " " << node.r.hostname << " "     << node.r.port << " " << node.vnode_num;  return sb;}voidverify_succlist (const vec<chord_node> &zs){  // This code assumes that the nodes in zs are ordered  strbuf s;  size_t sz = zs.size ();  size_t ssz = sequential.size ();  if (ssz == 0) {    for (size_t i = 1; i < sz; i++) {      sequential.push_back (zs[i]);    }  } else {    bool bad = false;    vec<chord_node> newseq;    size_t i = 1, j = 0;    while (i < sz && j < ssz) {      if (sequential[j].x == zs[i].x) {	newseq.push_back (sequential[j]);	format (s << "|   ", sequential[j]) << "\n";	j++; i++;      } else {	bad = true;	chordID prev (0);	chordID a, b;	if (newseq.size ()) prev = newseq.back ().x;        if (succproc == CHORDPROC_GETSUCC_EXT) {	  a = sequential[j].x;	  b = zs[i].x;	} else {	  b = sequential[j].x;	  a = zs[i].x;	}	if (between (prev, b, a)) {	  // incoming list is missing a node!	  format (s << "| R ", sequential[j]) << "\n";	  newseq.push_back (sequential[j]);	  j++;	} else {	  // we didn't know about a successor!	  format (s << "| L ", zs[i]) << "\n";	  newseq.push_back (zs[i]);	  i++;	}      }    }    // Ideally now there are still some nodes in zs but none    // left in sequential.  Sometimes, it is the other way.    // But not both.    assert (!(i < sz && j < ssz));    while (i < sz) {      newseq.push_back (zs[i++]);    }    while (j < ssz) {      bad = true;      // incoming list is missing a node!      format (s << "|'R ", sequential[j]) << "\n";      newseq.push_back (sequential[j++]);    }    if (bad) {      verify_errors = true;      aout << s;    }    sequential.clear ();    sequential = newseq;  }}voidgetsucc (const chord_node &n){  chord_nodelistextres *res = New chord_nodelistextres ();  doRPC (n, chord_program_1, succproc, &n.x, res,	 wrap (&getsucc_cb, getusec (), n, res));}voidgetsucc_cb (u_int64_t start, chord_node curr, chord_nodelistextres *res, clnt_stat err){  chord_node next;      if (err != 0 || res->status != CHORD_OK) {    aout << "failed to get a reading from " << curr << "; skipping.\n";    sequential.pop_front ();    if (sequential.size () == 0) {      fatal << "too many consecutive failures.\n";    }    next = sequential[0];    delete res;    getsucc (next);    return;  }  size_t sz = res->resok->nlist.size ();  vec<chord_node> zs;  for (size_t i = 0; i < sz; i++) {    chord_node z = make_chord_node (res->resok->nlist[i].n);    zs.push_back (z);  }  delete res;  curr = zs[0];  // ensure we talked to who we think we should be talking to.  assert (curr.x == sequential[0].x);  // Print full information for the node we just talked to  int index = curr.vnode_num;  assert (index >= 0);  char s[128];  sprintf (s, "e=%f", curr.e / Coord::PRED_ERR_MULT);  aout  << format (strbuf (), curr) << " "        << curr.coords[0] << " " << curr.coords[1] << " " << curr.coords[2] << " "	<< s << " "	<< (getusec () - start) << "\n";  if (verify) {    sequential.pop_front ();    verify_succlist (zs);  } else {    sequential = zs;    sequential.pop_front ();  }  // Out of nodes, done.  if (!sequential.size ())    exit (verify_errors == true ? 1 : 0);  next = sequential[0];  // wrapped around ring. done.  if (next.x == wellknown_ID)    exit (verify_errors == true ? 1 : 0);    getsucc (next);}void usage (){  warnx << "Usage: " << progname << " [-r] [-v] [-t maxtotaltime] -j <host>:<port>\n";  exit (1);}voidtimedout (int t){  fatal << "timed out after " << t << " seconds.\n";  exit (1);}intmain (int argc, char** argv) {  setprogname (argv[0]);  str host = "not set";  unsigned short port (0);  unsigned int maxtime (0);  int ch;  while ((ch = getopt (argc, argv, "j:rt:v")) != -1) {    switch (ch) {    case 'j':       {	char *bs_port = strchr(optarg, ':');	if (!bs_port) usage ();	*bs_port = 0;	bs_port++;	if (inet_addr (optarg) == INADDR_NONE) {	  //yep, this blocks	  struct hostent *h = gethostbyname (optarg);	  if (!h) {	    warn << "Invalid address or hostname: " << optarg << "\n";	    usage ();	  }	  struct in_addr *ptr = (struct in_addr *)h->h_addr;	  host = inet_ntoa (*ptr);	} else	  host = optarg;	port = atoi (bs_port);	break;      }    case 't':      maxtime = atoi (optarg);      break;    case 'v':      verify = true;      break;    case 'r':      succproc = CHORDPROC_GETPRED_EXT;      break;    default:      usage ();      break;    }  }  if (host == "not set")    usage ();      wellknown_ID = make_chordID (host, port, 0);  chord_node wellknown_node;  wellknown_node.x = wellknown_ID;  wellknown_node.r.hostname = host;  wellknown_node.r.port = port;  wellknown_node.vnode_num = 0;  sequential.push_back (wellknown_node);  getsucc (wellknown_node);  if (maxtime > 0)    delaycb (maxtime, wrap (&timedout, maxtime));  amain ();}

⌨️ 快捷键说明

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