Algorithm-Kademlia
view release on metacpan or search on metacpan
lib/Algorithm/Kademlia.pm view on Meta::CPAN
}
method get ($key_bin) {
my $entry = $store{$key_bin} // return;
if ( time() - $entry->time > $ttl ) {
delete $store{$key_bin};
return undef;
}
$entry; # Return the full entry now
}
};
class Algorithm::Kademlia::Storage::Entry v1.1.0 {
field $key : param : reader;
field $leechers : param : reader : writer;
field $seeds : param : reader : writer;
field $time : param : reader : writer;
field $value : param : reader : writer;
field $publisher : param : reader;
};
class Algorithm::Kademlia::Search v1.1.1 {
field $target_id_bin : param : reader;
field $k : param //= 20;
field $alpha : param //= 3;
field %nodes; # id_bin -> { data => ..., queried => 0, responded => 0, failed => 0 }
method add_candidates (@peers) {
for my $peer (@peers) {
my $id = $peer->{id};
next if $nodes{$id} && ( $nodes{$id}{queried} || $nodes{$id}{failed} );
$nodes{$id} //= { data => $peer->{data}, queried => 0, responded => 0, failed => 0 };
}
}
method pending_queries () {
grep { $_->{queried} && !$_->{responded} && !$_->{failed} } values %nodes;
}
method next_to_query () {
my @sorted = sort { ( $a^.$target_id_bin ) cmp( $b^.$target_id_bin ) } keys %nodes;
my @to_query;
for my $id (@sorted) {
next if $nodes{$id}{queried} || $nodes{$id}{failed};
push @to_query, { id => $id, data => $nodes{$id}{data} };
$nodes{$id}{queried} = 1;
last if @to_query >= $alpha;
}
@to_query;
}
method mark_responded ( $id_bin, @new_peers ) {
return unless $nodes{$id_bin};
$nodes{$id_bin}{responded} = 1;
$self->add_candidates(@new_peers);
}
method mark_failed ($id_bin) {
return unless $nodes{$id_bin};
$nodes{$id_bin}{failed} = 1;
}
method best_results () {
my @sorted = sort { ( $a^.$target_id_bin ) cmp( $b^.$target_id_bin ) } grep { $nodes{$_}{responded} } keys %nodes;
my @results = map { { id => $_, data => $nodes{$_}{data} } } splice( @sorted, 0, $k );
@results;
}
method is_finished () {
my @responded = grep { $_->{responded} } values %nodes;
return 1 if @responded >= $k;
my @available = grep { !$_->{queried} && !$_->{failed} } values %nodes;
return 1 if !@available && !$self->pending_queries;
0;
}
};
};
1;
( run in 0.709 second using v1.01-cache-2.11-cpan-39bf76dae61 )