void
merkle_syncer::error (str err)
{
  //warn << (u_int)this << ": SYNCER ERROR: " << err << "\n";
  fatal_err = err;
  setdone ();
}
Beispiel #2
0
static void *producer(char *dirnames[2]){
	DIR *rdir, *wdir;
	FILE *rfile, *wfile;
	char rfname[MAXNAME_SIZE], wfname[MAXNAME_SIZE];
	struct dirent *entry;
	struct stat *sbuf;
	buffer_t item;
	int err;
	if((rdir = opendir(dirnames[0])) == NULL || (wdir = opendir(dirnames[1])) == NULL)
		printf("watsouped all wrong \n");
	while((entry = readdir(rdir)) != NULL){
		if(lstat(entry->d_name, sbuf)){
			printf("naw this aint workeded\n");
			break;
		}
		if(!S_ISREG(sbuf->st_mode)){
			printf("derped on that one for sure\n");
			break;
		}
		if(strlen(entry->d_name)+strlen(dirnames[0]) >= MAXNAME_SIZE){
			printf("cant read that deep\n");
			break;
		}
		sprintf(rfname, "%s%s",dirnames[0], entry->d_name);
		if((rfile = fopen(rfname, "r")) == NULL){
			printf("reading wrongeded\n");
			break;
		}
		if((wfile = fopen(wfname, "w")) == NULL){
			close(fileno(rfile));
			printf("writing wrognned\n");
			break;
		}
		item.infd = fileno(rfile);
		item.outfd = fileno(wfile);
		item.filename = entry->d_name;
		if(err = putitem(item))
			break;
	}
	err = setdone();
	if(err != ECANCELED)
		seterror(err);
	return NULL;
}
void
merkle_syncer::next (void)
{
  trace << "local range [" <<  local_rngmin << "," << local_rngmax << "]\n";
  assert (!sync_done);
  assert (!fatal_err);

  // st is queue of pending index nodes
  while (st.size ()) {
    pair<merkle_rpc_node, int> &p = st.back ();
    merkle_rpc_node *rnode = &p.first;
    assert (!rnode->isleaf);
    
    merkle_node *lnode = ltree->lookup_exact (rnode->depth, rnode->prefix);

    if (!lnode) {
      fatal << "lookup_exact didn't match for " << rnode->prefix << " at depth " << rnode->depth << "\n";
    }
    

    trace << "starting from slot " << p.second << "\n";

    while (p.second < 64) {
      u_int i = p.second;
      p.second += 1;
      trace << "CHECKING: " << i;

      bigint remote = tobigint (rnode->child_hash[i]);
      bigint local = tobigint (lnode->child_hash(i));

      u_int depth = rnode->depth + 1;

      //prefix is the high bits of the first key 
      // the node is responsible for.
      merkle_hash prefix = rnode->prefix;
      prefix.write_slot (rnode->depth, i);
      bigint slot_rngmin = tobigint (prefix);
      bigint slot_width = bigint (1) << (160 - 6*depth);
      bigint slot_rngmax = slot_rngmin + slot_width - 1;

      bool overlaps = overlap (local_rngmin, local_rngmax, slot_rngmin, slot_rngmax);

      strbuf tr;
      if (remote != local) {
	tr << " differ. local " << local << " != remote " << remote;

	if (overlaps) {
	  tr << " .. sending\n";
	  sendnode (depth, prefix);
	  trace << tr;
	  ltree->lookup_release(lnode);
	  return;
	} else {
	  tr << " .. not sending\n";
	}
      } else {
	tr << " same. local " << local << " == remote " << remote << "\n";
      }
      trace << tr;
    }

    ltree->lookup_release(lnode);
    assert (p.second == 64);
    st.pop_back ();
  }

  trace << "DONE .. in NEXT\n";
  setdone ();
  trace << "OK!\n";
}