diff --git a/pydyton/routers/hcbf.py b/pydyton/routers/hcbf.py index b6280fb1e2407ad9a42f139336b2022351d45006..d6c85c517aa5ed0e241ba4475794f0968e90ea67 100644 --- a/pydyton/routers/hcbf.py +++ b/pydyton/routers/hcbf.py @@ -1,74 +1,87 @@ def hcbf(self, packet, state): - if len(self.community) == 0: - return False - + if 'hcbf_ui' not in packet.stats: + packet.stats = { + f'hcbf_{reason}': 0 + for reason in ['direct', 'ui', 'lp','ui_lonely', 'lp_lonely', + 'cbc', 'ncf' ] + } + + stats = packet.stats + dest = packet.destination community = self.network.community - c_of = lambda n: community[n] - same_community = lambda a, b: c_of(a) == c_of(b) - - cbc_of = lambda n, d: community.get_cbc(c_of(n), c_of(d)) - lp_of = lambda n: community.get_lp(n) - ncf_of = lambda n, d: community.get_ncf(n, c_of(d)) - ui_of = lambda n: community.get_ui(n) + def send(to, reason): + stats[f'hcbf_{reason}'] += 1 + self.send(to, packet, reason=reason) - max = lambda a, b: a if a[0] >= b[0] else b + # case 1: direct delivery + if dest in self.links: + send(dest, 'direct') + return True - if len(c_of(self)) == 0: - return False + ui = lambda n: community.get_ui(n) + lp = lambda n: community.get_lp(n) + cbc = lambda n: community.get_cbc(n.community, dest.community) + ncf = lambda n: community.get_ncf(n, dest.community) - dest = packet.destination - max_cbc = (cbc_of(self, dest), self) - max_lp = (-1, None) - max_ncf= (ncf_of(self, dest), self) - max_ui = (-1, None) + local_community = [ + met for met in self.links if met in self.community + ] - my_lp = lp_of(self) - my_ui = ui_of(self) + not_local_community = [ + met for met in self.links if met not in self.community + ] - for met in self.links: - if met == dest: - # direct transfer - self.send(met, packet) + if self.community is dest.community and local_community: + max_ui = max(local_community, key=ui) + if ui(max_ui) > ui(self): + send(max_ui, 'ui') return True + elif ui(max_ui) < ui(self): + return False + # ui(max_ui) == ui(self) - if same_community(met, dest): - met_ui = ui_of(met) - met_lp = lp_of(met) - if met_ui > my_ui: - max_ui = max((met_ui, met), max_ui) - max_lp = max((met_lp, met), max_lp) - elif same_community(met, self): - met_cbc = cbc_of(met, dest) - max_cbc = max((met_cbc, met), max_cbc) - else: - met_ncf = ncf_of(met, dest) - max_ncf = max((met_ncf, met), max_ncf) - - if max_ui[1] is not None and same_community(max_ui[1], dest): - self.send(max_ui[1], packet) - return True - - if max_lp[1] is not None and same_community(max_lp[1], dest): - self.send(max_lp[1], packet) - return True - - if max_cbc[1] is not self: - self.send(max_cbc[1], packet) - return True - - if max_ncf[1] is not self: - self.send(max_ncf[1], packet) - return True + max_lp = max(local_community, key=lp) + if lp(max_lp) > lp(self): + send(max_lp, 'lp') + return True + elif lp(max_lp) < lp(self): + return False + # lp(max_lp) == lp(self) + + elif not_local_community: + max_ncf = max(not_local_community, key=ncf) + if ncf(max_ncf) > ncf(self): + send(max_ncf, 'ncf') + return True + elif ncf(max_ncf) < ncf(self): + return False + # ncf(max_ncf) == ncf(self) - if max_ui[1] is not None and max_ui[0] > my_ui: - self.send(max_ncf[1], packet) - self.send(max_ui[1], packet) - return True + max_cbc = max(not_local_community, key=cbc) + if cbc(max_cbc) > cbc(self): + send(max_cbc, 'cbc') + return True + elif cbc(max_cbc) < cbc(self): + return False + # cbc(max_cbc) == cbc(self) + + elif local_community: + max_ui = max(local_community, key=ui) + if ui(max_ui) > ui(self): + send(max_ui, 'ui_lonely') + return True + elif ui(max_ui) < ui(self): + return False + # ui(max_ui) == ui(self) - if max_lp[1] is not None and max_lp[0] > my_lp: - self.send(max_lp[1], packet) - return True + max_lp = max(local_community, key=lp) + if lp(max_lp) > lp(self): + send(max_lp, 'lp_lonely') + return True + elif lp(max_lp) < lp(self): + return False + # lp(max_lp) == lp(self) return False