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

📄 chordfingerpns.c

📁 P2P模拟器
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 2003-2005 Jinyang Li *                    Massachusetts Institute of Technology *  * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: *  * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. *  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */#include  "chordfingerpns.h"#include "observers/chordobserver.h"#include "p2psim/network.h"#include <stdio.h>#include <iostream>using namespace std;extern bool static_sim;ChordFingerPNS::ChordFingerPNS(IPAddress i, Args& a, LocTable *l, const char *name)   : Chord(i, a, New LocTable(), name) {   _base = a.nget<uint>("base",2,10);  _samples = a.nget<int>("samples",_nsucc,10);  _fingerlets = a.nget<uint>("fingerlets",1,10);  _stab_pns_running = false;  _stab_pns_outstanding = 0;  _stab_pns_timer = a.nget<uint>("pnstimer",_stab_succlist_timer,10);  learntable = New LocTable();  learntable->set_timeout(10*_stab_pns_timer);  learntable->set_evict(false);  learntable->init(me);}voidChordFingerPNS::oracle_node_died(IDMap n){  Chord::oracle_node_died(n);  IDMap tmp = loctable->succ(n.id,LOC_ONCHECK);  if (tmp.ip != n.ip) return;  //lost one my of finger?  vector<IDMap> ids = ChordObserver::Instance(NULL)->get_sorted_nodes();  uint sz = ids.size();  CHID lap = (CHID) -1;  while (lap > 1) {    lap = lap / _base;    for (uint j = 1; j <= (_base-1); j++) {      if (ConsistentHash::between(me.id+lap*j, me.id+lap*(j+1), n.id)) {	loctable->del_node(n);	//find a replacement for this finger	IDMap tmpf;	tmpf.id = lap * j + me.id;	uint s_pos = upper_bound(ids.begin(), ids.end(), tmpf, Chord::IDMap::cmp) - ids.begin();	s_pos = s_pos % sz;	tmpf.id = lap * (j+1) + me.id;	uint e_pos = upper_bound(ids.begin(), ids.end(), tmpf, Chord::IDMap::cmp) - ids.begin();	e_pos = e_pos % sz;	if (s_pos == e_pos) return;	IDMap min_f = ids[s_pos];	Topology *t = Network::Instance()->gettopology();	uint min_l = t->latency(me.ip,min_f.ip);	int k = 0;	for (uint i = s_pos; i!= e_pos; i = (i+1)%sz) {	  if (t->latency(me.ip,ids[i].ip) < min_l) {	    min_f = ids[i];	    min_l = t->latency(me.ip, ids[i].ip);	    k++;	    if (_samples > 0 && k>= _samples) break;	  }	}	loctable->add_node(min_f);//add replacement pns finger	CDEBUG(3) << "oracle_node_died del " << n.ip << "," << printID(n.id)	  << "add " << min_f.ip << "," << printID(min_f.id) << endl;	return;      }    }  }  assert(0);}voidChordFingerPNS::oracle_node_joined(IDMap n){  Chord::oracle_node_joined(n);  IDMap tmp = loctable->succ(n.id,LOC_ONCHECK);  if (tmp.ip == n.ip) return;  //is the new node one of my finger?  vector<IDMap> ids = ChordObserver::Instance(NULL)->get_sorted_nodes();  uint sz = ids.size();  CHID lap = (CHID) -1;  while (lap > 1) {    lap = lap / _base;    for (uint j = 1; j <= (_base-1); j++) {      if (ConsistentHash::between(me.id+lap*j, me.id+lap*(j+1), n.id)) {	IDMap s = loctable->succ(me.id + lap * j,LOC_ONCHECK);	if (!ConsistentHash::between(me.id+lap*j, me.id+lap*(j+1), s.id)) {	  loctable->add_node(n);	  CDEBUG(3) << "oracle_node_joined finger add " << n.ip << ","	    << printID(n.id) << endl;	  return;	}	IDMap tmpf;	tmpf.id = lap * j + me.id;	uint s_pos = upper_bound(ids.begin(), ids.end(), tmpf, Chord::IDMap::cmp) - ids.begin();	uint n_pos = find(ids.begin(),ids.end(),n) - ids.begin();	n_pos = n_pos + sz;	if (_samples < 0 || (int)(n_pos - s_pos) <= _samples) {	  //choose the closer one	  Topology *t = Network::Instance()->gettopology();	  if (t->latency(me.ip, n.ip) < t->latency(me.ip, s.ip)) {	    loctable->del_node(s,true);	    loctable->add_node(n);	    CDEBUG(3) << "oracle_node_joined finger del " << s.ip << ","	      << printID(s.id) << "add " << n.ip << "," << printID(n.id)	      << endl;	  }	} 	return;      }    }  }  assert(0);}inline static void which_finger(uint base, ConsistentHash::CHID id, ConsistentHash::CHID meid,     ConsistentHash::CHID &fs, ConsistentHash::CHID &fe){  ConsistentHash::CHID lap = (ConsistentHash::CHID) -1;  ConsistentHash::CHID finger;  while (1) {    lap = lap/base;    for (uint j = (base-1); j >= 1; j--) {      finger = lap * j + meid;      if (ConsistentHash::between(finger,finger+lap,id)) {	fs = finger;	fe = finger + lap;	return;      }    }  }}voidChordFingerPNS::learn_info(IDMap n){  assert(learntable);  if(loctable->update_ifexists(n))     return;  if (learntable->update_ifexists(n))    return;  Topology *t = Network::Instance()->gettopology();  IDMap ns = loctable->succ(n.id+1,LOC_ONCHECK);  LocTable::idmapwrap *naked_ns = NULL;  if ((ns.ip==0) || (ns.ip == me.ip))    goto NEXT_CHECK;  naked_ns = loctable->get_naked_node(ns.id);  assert(naked_ns);  if (naked_ns->is_succ) {    loctable->add_node(n,true); //accidentally discovered a new successor    return;  }else if (!naked_ns->fs)     goto NEXT_CHECK;  //assert(naked_ns->status == LOC_HEALTHY);  if (!naked_ns->fs) return;  if (ConsistentHash::between(naked_ns->fs,naked_ns->fe,n.id)) {    if ((t->latency(me.ip,ns.ip) > t->latency(me.ip,n.ip)) || (naked_ns->status==LOC_ONCHECK)) {      loctable->add_node(n,false,true,naked_ns->fs,naked_ns->fe); //a better finger in latency      loctable->del_node(ns,true);      return;    }else{      learntable->add_node(n);      return;    }  } NEXT_CHECK:  IDMap ps = loctable->pred(n.id-1,LOC_ONCHECK);  LocTable::idmapwrap *naked_ps = loctable->get_naked_node(ps.id);  if (naked_ps && naked_ns && (!naked_ps->is_succ)) {    if ((naked_ps->fe == naked_ns->fs) || ConsistentHash::between(naked_ps->fs,naked_ps->fe,n.id)) {      //good good      if (t->latency(me.ip,ns.ip) > t->latency(me.ip,n.ip)) {	loctable->add_node(n,false,true,naked_ps->fs,naked_ps->fe);	loctable->del_node(ns,true);	return;      }    }else{      learntable->add_node(n);      return;    }  }  ConsistentHash::CHID fs,fe;  which_finger(_base,n.id,me.id,fs,fe);  loctable->add_node(n,false,true,fs,fe);}boolChordFingerPNS::replace_node(IDMap n, IDMap &replacement){  assert(learntable);  LocTable::idmapwrap *naked = loctable->get_naked_node(n.id);  if (!naked)    return false;  if (naked->is_succ) {    //printf("%s no replacement for successor list %u,%qx\n",ts(), n.ip,n.id);    //no replacement    return false;  }else{    vector<IDMap> v = learntable->succs(naked->fs,_samples);    IDMap min_f = me;    Time min_lat = 10000000;    Topology *t = Network::Instance()->gettopology();    for (uint i = 0; i < v.size(); i++) {      if (ConsistentHash::between(naked->fs,naked->fe,v[i].id)) { 	if (min_lat > t->latency(me.ip,v[i].ip) && v[i].ip!=n.ip) {	  min_lat = t->latency(me.ip,v[i].ip);	  min_f = v[i];	}      }else{	break;      }    }    if (min_f.ip!=me.ip) {      if (t->latency(me.ip,min_f.ip) < t->latency(me.ip,n.ip)) 	loctable->add_node(min_f,false,true,naked->fs,naked->fe);      else	loctable->add_node(min_f,false,true,naked->fs,naked->fe,true);      loctable->del_node(n);      learntable->del_node(min_f,true);      replacement = min_f;      assert(min_f.ip != 0);      //printf("%s replaced finger %u,%qx range (%qx,%qx) latency %u with %u,%qx latency %u\n", ts(), n.ip, n.id, naked->fs, naked->fe, (uint) t->latency(me.ip, n.ip), replacement.ip, replacement.id, (uint)t->latency(me.ip,replacement.ip));      return true;    }else{      //printf("%s not replaced finger %u,%qx range (%qx,%qx) latency %u\n",ts(), n.ip,n.id, naked->fs,naked->fe, (uint)t->latency(me.ip, n.ip));    }  }  return false;}voidChordFingerPNS::initstate(){  vector<IDMap> ids = ChordObserver::Instance(NULL)->get_sorted_nodes();  uint sz = ids.size();  uint my_pos = find(ids.begin(), ids.end(), me) - ids.begin();  assert(my_pos < sz && ids[my_pos].id == me.id);  CHID min_lap = ids[(my_pos+_nsucc) % sz].id - me.id;  CHID lap = (CHID) -1;  Topology *t = Network::Instance()->gettopology();  while (lap > min_lap) {    lap = lap / _base;    for (uint j = 1; j <= (_base -1); j++) {      if (lap * j < min_lap) continue;      IDMap tmpf;      tmpf.id = lap * j + me.id;      uint s_pos = upper_bound(ids.begin(), ids.end(), tmpf, Chord::IDMap::cmp) - ids.begin();      s_pos = s_pos % sz;      tmpf.id = lap * (j+1) + me.id + 1;      uint e_pos = upper_bound(ids.begin(), ids.end(), tmpf, Chord::IDMap::cmp) - ids.begin();      e_pos = e_pos % sz;      if (s_pos == e_pos) continue;      IDMap min_f;      min_f.ip = 0;      uint min_l = 1000000;      hash_map<IPAddress, bool> inserted;      for (uint x = 0; x < _fingerlets; x++) {	int k = 0;	for (uint i = s_pos; i!= e_pos; i = (i+1)%sz) {	  if (inserted.find(ids[i].ip)==inserted.end() && t->latency(me.ip,ids[i].ip) < min_l) { 	    min_f = ids[i];	    min_l = t->latency(me.ip, ids[i].ip);

⌨️ 快捷键说明

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