Наследование: IComparable
Пример #1
0
 /// <summary>
 /// Returns what contact is blocking insertion (least promoted), or null if no contact is.
 /// </summary>
 /// <param name="toAdd">The node to add</param>
 /// <returns>The first element of the bucket</returns>
 public Contact Blocker(ID toAdd)
 {
     int bucket = BucketFor(toAdd);
     lock(buckets[bucket]) { // Nobody can move it while we're getting it
         if(buckets[bucket].Count < BUCKET_SIZE) {
             return null;
         } else {
             return buckets[bucket][0];
         }
     }
 }
Пример #2
0
        /// <summary>
        /// Make a new bucket list, for holding node contacts.
        /// </summary>
        /// <param name="ourID">The ID to center the list on.</param>
        public BucketList(ID ourID)
        {
            this.ourID = ourID;
            buckets = new List<List<Contact>>(NUM_BUCKETS);
            accessTimes = new List<DateTime>();

            // Set up each bucket
            for(int i = 0; i < NUM_BUCKETS; i++) {
                buckets.Add(new List<Contact>(BUCKET_SIZE));
                accessTimes.Add(default(DateTime));
            }
        }
Пример #3
0
        /// <summary>
        /// Determines the least significant bit at which the given ID differs from this one, from 0 through 8 * ID_LENGTH - 1.
        /// PRECONDITION: IDs do not match.
        /// </summary>
        /// <param name="other">The ID to compare to</param>
        /// <returns>The least significant bit where can be found the difference</returns>
        public int DifferingBit(ID other)
        {
            ID differingBits = this ^ other;
            int differAt = 8 * ID_LENGTH - 1;

            // Subtract 8 for every zero byte from the right
            int i = ID_LENGTH - 1;
            while(i >= 0 && differingBits.data[i] == 0) {
                differAt -= 8;
                i--;
            }

            // Subtract 1 for every zero bit from the right
            int j = 0;
            // 1 << j = pow(2, j)
            while(j < 8 && (differingBits.data[i] & (1 << j)) == 0) {
                j++;
                differAt--;
            }

            return differAt;
        }
Пример #4
0
 /// <summary>
 /// Do we have the specified value for the given key?
 /// </summary>
 /// <param name="key"></param>
 /// <param name="hash"></param>
 /// <returns></returns>
 public bool Contains(ID key, ID hash)
 {
     lock(store) {
         return store.ContainsKey(key) && store[key].ContainsKey(hash);
     }
 }
Пример #5
0
 /// <summary>
 /// Returns what bucket an ID maps to.
 /// PRECONDITION: ourID not passed.
 /// </summary>
 /// <param name="id">The id to check</param>
 /// <returns>The bucket number</returns>
 private int BucketFor(ID id)
 {
     return(ourID.DifferingBit(id));
 }
Пример #6
0
 /// <summary>
 /// Remove a contact.
 /// </summary>
 /// <param name="toRemove">The identificator od the contact to remove</param>
 public void Remove(ID toRemove)
 {
     int bucket = BucketFor(toRemove);
     lock(buckets[bucket]) { // Nobody can move it while we're removing it
         for(int i = 0; i < buckets[bucket].Count; i++) {
             if(buckets[bucket][i].NodeID == toRemove) {
                 buckets[bucket].RemoveAt(i);
                 return;
             }
         }
     }
 }
Пример #7
0
        /// <summary>
        /// Return the number of nodes in the network closer to the key than us.
        /// This is a guess as described at http://xlattice.sourceforge.net/components/protocol/kademlia/specs.html
        /// </summary>
        /// <param name="key">The key to analize</param>
        /// <returns>the number of nodes found</returns>
        public int NodesToKey(ID key)
        {
            int j = BucketFor(key);

            // Count nodes in earlier buckets
            int inEarlierBuckets = 0;
            for(int i = 0; i < j; i++) {
                inEarlierBuckets += buckets[i].Count;
            }

            // Count closer nodes in actual bucket
            int inActualBucket = 0;
            lock(buckets[j]) {
                foreach(Contact c in buckets[j]) {
                    if((c.NodeID ^ ourID) < (key ^ ourID)) { // Closer to us than key
                        inActualBucket++;
                    }
                }
            }

            return inEarlierBuckets + inActualBucket;
        }
Пример #8
0
 /// <summary>
 /// See if we have a contact with the given ID.
 /// </summary>
 /// <param name="toCheck">The ID to find into the structure</param>
 /// <returns>true if the contact is found into the structure</returns>
 public bool Contains(ID toCheck)
 {
     return this.Get(toCheck) != null;
 }
Пример #9
0
 /*
 IList<Uri> Get(ID tag_id)
 {
     return new List<Uri>();
 }
 */
 public DateTime GetPublicationTime(ID tag_id, Uri uri)
 {
     return new DateTime();
 }
Пример #10
0
 /// <summary>
 /// Gets a list of all value hashes for the given key
 /// It's a copy, iterate all you want.
 /// </summary>
 /// <param name="key"></param>
 /// <returns></returns>
 public IList<ID> GetHashes(ID key)
 {
     List<ID> toReturn = new List<ID>();
     lock(store) {
         if(store.ContainsKey(key)) {
             foreach(ID hash in store[key].Keys) {
                 toReturn.Add(hash);
             }
         }
     }
     return toReturn;
 }
Пример #11
0
 /// <summary>
 /// Get a particular value by key and hash, or null.
 /// </summary>
 /// <param name="key"></param>
 /// <param name="hash"></param>
 /// <returns></returns>
 public string Get(ID key, ID hash)
 {
     lock(store) {
         if(this.Contains(key, hash)) {
             File.ReadAllText(PathFor(key, hash));
         }
     }
     return null;
 }
Пример #12
0
 /// <summary>
 /// Get all data values for the given key, or an empty list.
 /// </summary>
 /// <param name="key"></param>
 /// <returns></returns>
 public IList<string> Get(ID key)
 {
     List<string> toReturn = new List<string>();
     lock(store) {
         if(ContainsKey(key)) {
             foreach(ID hash in store[key].Keys) {
                 // Load the value and add it to the list
                 toReturn.Add(File.ReadAllText(PathFor(key, hash)));
             }
         }
     }
     return toReturn;
 }
Пример #13
0
 public bool ContainsUrl(ID tag_id, Uri uri)
 {
     return false;
 }
Пример #14
0
 public bool ContainsTag(ID tag_id)
 {
     return false;
 }
Пример #15
0
 /// <summary>
 /// Do we have any data for the given key?
 /// </summary>
 /// <param name="key"></param>
 /// <returns></returns>
 public bool ContainsKey(ID key)
 {
     return store.ContainsKey(key);
 }
Пример #16
0
 /// <summary>
 /// Return a list of the BUCKET_SIZE contacts with IDs closest to 
 /// target, not containing any contacts with the excluded ID. 
 /// </summary>
 /// <param name="target">The target to find the close node to</param>
 /// <param name="excluded">The excluded ID</param>
 /// <returns>The list of contacts found</returns>
 public List<Contact> CloseContacts(ID target, ID excluded)
 {
     return CloseContacts(NUM_BUCKETS, target, excluded);
 }
Пример #17
0
        /// <summary>
        /// Returns a list of the specified number of contacts with IDs closest 
        /// to the given key, excluding the excluded ID.
        /// </summary>
        /// <param name="count">The number of contacts to found</param>
        /// <param name="target">The target node</param>
        /// <param name="excluded">The excluded node</param>
        /// <returns>The list of contacts found</returns>
        public List<Contact> CloseContacts(int count, ID target, ID excluded)
        {
            // These lists are sorted by distance.
            // Closest is first.
            List<Contact> found = new List<Contact>();
            List<ID> distances = new List<ID>();

            // For every Contact we have
            for(int i = 0; i < NUM_BUCKETS; i++) {
                lock(buckets[i]) {
                    for(int j = 0; j < buckets[i].Count; j++) {
                        Contact applicant = buckets[i][j];

                        // Exclude excluded contact
                        if(applicant.NodeID == excluded) {
                            continue;
                        }

                        // Add the applicant at the right place
                        ID distance = applicant.NodeID ^ target;
                        int addIndex = 0;
                        while(addIndex < distances.Count && distances[addIndex] < distance) {
                            addIndex++;
                        }
                        distances.Insert(addIndex, distance);
                        found.Insert(addIndex, applicant);

                        // Remove the last entry if we've grown too big
                        if(distances.Count >= count) {
                            distances.RemoveAt(distances.Count - 1);
                            found.RemoveAt(found.Count - 1);
                        }
                    }
                }
            }

            // Give back the list of closest.
            return found;
        }
Пример #18
0
 /// <summary>
 /// Returns when the given value was last inserted by
 /// its original publisher, or null if the value isn't present.
 /// </summary>
 /// <param name="key"></param>
 /// <returns></returns>
 public DateTime? GetPublicationTime(ID key, ID hash)
 {
     lock(store) {
         if(store.ContainsKey(key) && store[key].ContainsKey(hash)) {
             return store[key][hash].timestamp;
         }
     }
     return null;
 }
Пример #19
0
 /// <summary>
 /// Return the contact with the given ID, or null if it's not found.
 /// </summary>
 /// <param name="toGet">The ID of the contact to Get</param>
 /// <returns>The contact found</returns>
 public Contact Get(ID toGet)
 {
     int bucket = BucketFor(toGet);
     lock(buckets[bucket]) { // Nobody can move it while we're getting it
         for(int i = 0; i < buckets[bucket].Count; i++) {
             if(buckets[bucket][i].NodeID == toGet) {
                 return buckets[bucket][i];
             }
         }
     }
     return null;
 }
Пример #20
0
 public void Put(ID tag_id, Uri uri, DateTime publicationTime)
 {
 }
Пример #21
0
        /// <summary>
        /// Move the contact with the given ID to the front of its bucket.
        /// </summary>
        /// <param name="toPromote">The identificator of the contact to promote</param>
        public void Promote(ID toPromote)
        {
            Contact promotee = Get(toPromote);
            int bucket = BucketFor(toPromote);

            lock(buckets[bucket]) { // Nobody can touch it while we move it.
                buckets[bucket].Remove(promotee); // Take out
                buckets[bucket].Add(promotee); // And put in at end
            }

            lock(accessTimes) {
                accessTimes[bucket] = DateTime.Now;
            }
        }
Пример #22
0
        /// <summary>
        /// Store a key/value pair published originally at the given UTC timestamp. Value is kept until keepTime past timestamp.
        /// </summary>
        /// <param name="key"></param>
        /// <param name="hash">The hash of the value</param>
        /// <param name="val"></param>
        /// <param name="timestamp"></param>
        /// <param name="keepTime"></param>
        public void Put(ID key, ID hash, string val, DateTime timestamp, TimeSpan keepFor)
        {
            // Write the file
            CreatePath(Path.GetDirectoryName(PathFor(key, hash)));
            File.WriteAllText(PathFor(key, hash), val);

            // Record its existence
            Entry entry = new Entry();
            entry.timestamp = timestamp;
            entry.keepFor = keepFor;

            lock(store) {
                if(!store.ContainsKey(key)) {
                    store[key] = new SortedList<ID, Entry>();
                }
                store[key][hash] = entry;
            }
        }
Пример #23
0
 /// <summary>
 /// Report that a lookup was done for the given key.
 /// Key must not match our ID.
 /// </summary>
 /// <param name="key">The bucket that refer the bucket to touch</param>
 public void Touch(ID key)
 {
     lock(accessTimes) {
         accessTimes[BucketFor(key)] = DateTime.Now;
     }
 }
Пример #24
0
 public void RefreshResource(ID tag_id, Uri uri, DateTime timestamp)
 {
 }
Пример #25
0
 /// <summary>
 /// Change the timing information on an existing entry, if extant.
 /// </summary>
 /// <param name="key"></param>
 /// <param name="hash"></param> 
 /// <param name="newStamp"></param>
 /// <param name="newKeep"></param>
 public void Restamp(ID key, ID hash, DateTime newStamp, TimeSpan newKeep)
 {
     lock(store) {
         if(store.ContainsKey(key) && store[key].ContainsKey(hash)) {
             store[key][hash].timestamp = newStamp;
             store[key][hash].keepFor = newKeep;
         }
     }
 }
Пример #26
0
 /// <summary>
 /// Where should we save a particular value?
 /// </summary>
 /// <param name="key"></param>
 /// <param name="hash"></param>
 /// <returns></returns>
 private string PathFor(ID key, ID hash)
 {
     return Path.Combine(Path.Combine(storageRoot, key.ToPathString()), hash.ToPathString() + DATA_EXTENSION);
 }
Пример #27
0
 /// <summary>
 /// Make a contact for a node with the given ID at the given location.
 /// </summary>
 /// <param name="id">The identificator of the node</param>
 /// <param name="endpoint">The address of the node</param>
 public Contact(ID id, Uri endpoint)
 {
     nodeID = id;
     nodeEndpoint = endpoint;
 }
Пример #28
0
        public static void Main(string[] args)
        {
            Console.WriteLine("ID tests");
            byte[] aData = new byte[20];
            aData[3] = 10;
            byte[] bData = new byte[20];
            bData[1] = 10;

            ID a = new ID(aData);
            ID b = new ID(bData);
            Debug.Assert(a != b);
            Debug.Assert(a == a);
            Debug.Assert(!(b == a));
            Debug.Assert(a < b);
            Debug.Assert(b > a);
            Debug.Assert(a.Equals(a));
            Debug.Assert(!a.Equals(b));
            Debug.Assert(a.GetHashCode() != b.GetHashCode());
            Debug.Assert(a.DifferingBit(b) == 4 * 8 - 2); // next to last bit of 4th byte differs
            Console.WriteLine("Test complete");

            Console.WriteLine("Testing KademilaNode");
            KademliaNode node1 = new KademliaNode(new EndpointAddress("soap.udp://localhost:8002/kademlia"));
            ServiceHost host1 = new ServiceHost(node1, new Uri("soap.udp://localhost:8002/kademlia"));
            KademliaNode node2 = new KademliaNode(new EndpointAddress("soap.udp://localhost:8001/kademlia"));
            ServiceHost host2 = new ServiceHost(node2, new Uri("soap.udp://localhost:8001/kademlia"));
            //			node1.Bootstrap();
            System.Threading.Thread.Sleep(50); // Wait for the other node to process its bucket queue
            node1.JoinNetwork();
            node2.JoinNetwork();

            // Do a big test
            List<KademliaNode> nl = new List<KademliaNode>();
            KademliaNode lastNode = node1;
            for(int i = 0; i < 10; i++) {
                KademliaNode node = new KademliaNode();
                node.Bootstrap();
                lastNode = node;
                System.Threading.Thread.Sleep(50); // Wait for the other node to process its bucket queue
                node.JoinNetwork();
                nl.Add(node);
            }
            host1.Close();
            host2.Close();
            Console.WriteLine("Connectivity tests complete");
            /*
            // Do a store test
            ID babiesID = ID.RandomID();
            node1.Put(babiesID, "=====I eat babies=====");
            Console.WriteLine("Store tests complete");

            // Get it back
            IList<string> foundVals = node1.Get(babiesID);
            foreach(string s in foundVals) {
                Console.WriteLine("1 Found: " + s);
            }
            foundVals = node2.Get(babiesID);
            foreach(string s in foundVals) {
                Console.WriteLine("2 Found: " + s);
            }
            Console.WriteLine("Find tests complete");

            Console.WriteLine("Testing DHT");
            Dht dht = new Dht("C:\\Users\\seby\\Documents\\progetto_malgeri\\p2p-player\\nodes"+Console.ReadLine()+".xml");
            dht.Put("A", "The value for A");
            Console.WriteLine("A = " + dht.Get("A"));

            Console.WriteLine("Multi-value test");
            dht.Put("Animal", "cat");
            dht.Put("Animal", "dog");
            dht.Put("Animal", "double-beaver");
            dht.Put("Animal", "wombat");
            dht.Put("Animal", "alot");
            Console.WriteLine("Animal entry count " + node1.Get(ID.Hash("Animal")).Count);
            Console.WriteLine("Animal entry count " + node2.Get(ID.Hash("Animal")).Count);
            Console.WriteLine("Arbitrary animal = " + dht.Get("Animal"));

            */
            Console.WriteLine("Testing complete! Press any key to exit the program.");
            Console.ReadLine();
        }