Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package kademlia
- import (
- "container/list";
- "container/vector";
- "exp/iterable";
- "sort";
- )
- const BucketSize = 20;
- type RoutingTable struct {
- node Contact;
- buckets [IdLength*8]*list.List;
- }
- type ContactRecord struct {
- node *Contact;
- sortKey NodeID;
- }
- func (rec *ContactRecord) Less(other interface{}) bool {
- return rec.sortKey.Less(other.(*ContactRecord).sortKey);
- }
- func NewRoutingTable(node *Contact) (ret *RoutingTable) {
- ret = new(RoutingTable);
- for i := 0; i < IdLength * 8; i++ {
- ret.buckets[i] = list.New();
- }
- ret.node = *node;
- return;
- }
- func (table *RoutingTable) Update(contact *Contact) {
- prefix_length := contact.id.Xor(table.node.id).PrefixLen();
- bucket := table.buckets[prefix_length];
- element := iterable.Find(bucket, func(x interface{}) bool {
- return x.(*Contact).id.Equals(table.node.id);
- });
- if element == nil {
- if bucket.Len() <= BucketSize {
- bucket.PushFront(contact);
- }
- // TODO: Handle insertion when the list is full by evicting old elements if
- // they don't respond to a ping.
- } else {
- bucket.MoveToFront(element.(*list.Element));
- }
- }
- func copyToVector(start, end *list.Element, vec *vector.Vector, target NodeID) {
- for elt := start; elt != end; elt = elt.Next() {
- contact := elt.Value.(*Contact);
- vec.Push(&ContactRecord{contact, contact.id.Xor(target)});
- }
- }
- func (table *RoutingTable) FindClosest(target NodeID, count int) (ret *vector.Vector) {
- ret = new(vector.Vector).Resize(0, count);
- bucket_num := target.Xor(table.node.id).PrefixLen();
- bucket := table.buckets[bucket_num];
- copyToVector(bucket.Front(), nil, ret, target);
- for i := 1; (bucket_num-i >= 0 || bucket_num+i < IdLength*8) && ret.Len() < count; i++ {
- if bucket_num - i >= 0 {
- bucket = table.buckets[bucket_num - i];
- copyToVector(bucket.Front(), nil, ret, target);
- }
- if bucket_num + i < IdLength * 8 {
- bucket = table.buckets[bucket_num + i];
- copyToVector(bucket.Front(), nil, ret, target);
- }
- }
- sort.Sort(ret);
- if ret.Len() > count {
- ret.Cut(count, ret.Len());
- }
- return;
- }
Add Comment
Please, Sign In to add comment