/// <summary> /// Method that removes the expired elements from the DHT. This method search for expired element and add it to a structure, /// then delete all the expired elements and if a resource remanins without any supplier will be deleted too. /// </summary> public void Expire() { List <KademliaResource> lr = new List <KademliaResource>(); LinkedList <ExpireIteratorDesc> cleanList = new LinkedList <ExpireIteratorDesc>(); _repository.GetAll <KademliaResource>(lr); Parallel.ForEach <KademliaResource, ExpireIteratorDesc>(lr, () => new ExpireIteratorDesc(), (key, loop, iter_index, iter_desc) => { if (key == null) { return(iter_desc); } if (iter_desc.TagId == null) { iter_desc.TagId = key.Id; } List <DhtElement> dhtElementList = key.Urls.ToList(); for (int k = 0; k < dhtElementList.Count; k++) { DhtElement delem = dhtElementList[k]; if (DateTime.Compare(delem.Publication.Add(delem.Validity), DateTime.Now) <= 0) { iter_desc.Expired.Add(delem); } } if (iter_desc.Expired.Count == key.Urls.Count) { iter_desc.ToBeDeleted = true; } else { iter_desc.ToBeDeleted = false; } return(iter_desc); }, (finalResult) => cleanList.AddLast(finalResult) ); Parallel.ForEach <ExpireIteratorDesc>(cleanList, (iter_desc) => { if (iter_desc == null) { return; } if (iter_desc.ToBeDeleted) { DeleteTag(iter_desc.TagId); } else { _repository.ArrayRemoveByPosition(iter_desc.TagId, "Urls", iter_desc.Expired.ToArray <DhtElement>()); } } ); }
/// <summary> /// Returns the publication time of a Dht Element related to a Resource. /// </summary> /// <param name="tagid">Resource Identifier</param> /// <param name="url">Url of the Dht Element</param> /// <returns>The publication time of the Dht Element if it exists, the DateTime min value if the element doesn't exist</returns> public DateTime GetPublicationTime(string tagid, Uri url) { KademliaResource rs = Get(tagid); if (rs != null) { DhtElement elem = rs.Urls.ToList().Find(de => { return(de.Url.Equals(url)); } ); if (elem != null) { return(elem.Publication); } } return(DateTime.MinValue); }
/// <summary> /// Method that implements the registration of a peer as supplier for a given resource. /// This method just load the resource and adds the Dht Element if it's not already in the suppliers list. /// </summary> /// <param name="tagid">Resource Identifier</param> /// <param name="url">Url of the supplier</param> /// <param name="pubtime">Publication Time for the supplier</param> /// <returns></returns> public bool Put(string tagid, Uri url, DateTime pubtime) { KademliaResource rs = new KademliaResource(); DhtElement dhtElem = new DhtElement(url, pubtime, this._elementValidity); RepositoryResponse resp = _repository.GetByKey <KademliaResource>(tagid, rs); if (resp == RepositoryResponse.RepositoryLoad) { if (!rs.Urls.Contains(dhtElem)) { _repository.ArrayAddElement(rs.Id, "Urls", dhtElem); return(true); } else { log.Debug("Urls " + url.ToString() + " already known"); } } return(false); }
/// <summary> /// Checks if the given resource contains the Url in its supplier list /// </summary> /// <param name="tagid">Resource identifier</param> /// <param name="url">Url of the supplier</param> /// <returns>True if the Peer with the given Url is a supplier for the resource.</returns> public bool ContainsUrl(string tagid, Uri url) { KademliaResource rs = Get(tagid); DhtElement fakeElem = new DhtElement() { Url = url }; if (rs != null) { if (rs.Urls.Contains(fakeElem)) { return(true); } else { return(false); } } return(false); }
/// <summary> /// Stores a tag as resource into the kademlia repository. If the resource already exists the method tries to add the /// given Url (with the desired publication time) to the list of suppliers for that resource; if the url is already known /// the method does nothing. If the resource is new first the method adds it to the repository and then generates a set of /// keywords related to the new resource. For each generated keyword, if this is already in the repository the tag /// identifier (that is the resource identifier too) will be added to the related tags list, if the keyword doesn't exist /// it will be created and its related tags list will contains only the new resource. /// </summary> /// <param name="tag">Tag to store in the kademlia resource</param> /// <param name="peer">Url of the supplier</param> /// <param name="pubtime">Publication TIme</param> /// <returns>False if something went wrong, true otherwise</returns> public bool StoreResource(CompleteTag tag, Uri peer, DateTime pubtime) { KademliaResource rs = new KademliaResource(); Console.WriteLine("Storing resource from peer " + peer); DhtElement dhtElem = new DhtElement(peer, pubtime, this._elementValidity); RepositoryResponse resp = _repository.GetByKey <KademliaResource>(tag.TagHash, rs); if (resp == RepositoryResponse.RepositoryLoad) { if (!rs.Urls.Contains(dhtElem)) { _repository.ArrayAddElement(rs.Id, "Urls", dhtElem); } else { log.Debug("Urls " + peer.ToString() + " already known"); } } else if (resp == RepositoryResponse.RepositoryMissingKey) { rs = new KademliaResource(tag, dhtElem); if (_repository.Save(rs) == RepositoryResponse.RepositorySuccess) { List <string> pks = new List <string>(generatePrimaryKey(tag)); List <KademliaKeyword> keys = new List <KademliaKeyword>(); if (_repository.GetByKeySet(pks.ToArray(), keys) > 0) { foreach (KademliaKeyword k in keys) { if (!k.Tags.Contains(rs.Id)) { _repository.ArrayAddElement(k.Id, "Tags", rs.Id); } pks.Remove(k.Id); } foreach (String pk in pks) { KademliaKeyword localKey = new KademliaKeyword(pk, rs.Id); _repository.Save(localKey); } } else { log.Error("Unexpected reposnde while getting keywords"); return(false); } } else { log.Error("Unexpected response while inserting Tag with key " + tag.TagHash); return(false); } } else { log.Error("Unexpected response while testing presence of the key " + tag.TagHash); return(false); } return(true); }