25 #include "ns3/ndnSIM/model/ndn-common.hpp" 
   29 #include <boost/intrusive/unordered_set.hpp> 
   30 #include <boost/intrusive/list.hpp> 
   31 #include <boost/intrusive/set.hpp> 
   32 #include <boost/functional/hash.hpp> 
   33 #include <boost/interprocess/smart_ptr/unique_ptr.hpp> 
   35 #include <boost/foreach.hpp> 
   36 #include <boost/mpl/if.hpp> 
   45 template<
typename Payload, 
typename BasePayload = Payload>
 
   46 struct pointer_payload_traits {
 
   47   typedef Payload payload_type;  
 
   48   typedef Payload* storage_type; 
 
   49   typedef Payload* insert_type;  
 
   51   typedef Payload* return_type;             
 
   52   typedef const Payload* const_return_type; 
 
   56   typedef const BasePayload*
 
   59   static Payload* empty_payload;
 
   62 template<
typename Payload, 
typename BasePayload>
 
   63 Payload* pointer_payload_traits<Payload, BasePayload>::empty_payload = 0;
 
   65 template<
typename Payload, 
typename BasePayload = Payload>
 
   66 struct smart_pointer_payload_traits {
 
   67   typedef Payload payload_type;
 
   68   typedef ns3::Ptr<Payload> storage_type;
 
   69   typedef ns3::Ptr<Payload> insert_type;
 
   71   typedef ns3::Ptr<Payload> return_type;
 
   72   typedef ns3::Ptr<const Payload> const_return_type;
 
   74   typedef ns3::Ptr<BasePayload> base_type;
 
   75   typedef ns3::Ptr<const BasePayload> const_base_type;
 
   77   static ns3::Ptr<Payload> empty_payload;
 
   80 template<
typename Payload, 
typename BasePayload>
 
   81 ns3::Ptr<Payload> smart_pointer_payload_traits<Payload, BasePayload>::empty_payload = 0;
 
   83 template<
typename Payload, 
typename BasePayload = Payload>
 
   84 struct non_pointer_traits {
 
   85   typedef Payload payload_type;
 
   86   typedef Payload storage_type;
 
   87   typedef const Payload& insert_type; 
 
   89   typedef Payload& return_type;
 
   90   typedef const Payload& const_return_type;
 
   92   typedef BasePayload& base_type;
 
   93   typedef const BasePayload& const_base_type;
 
   95   static Payload empty_payload;
 
   98 template<
typename Payload, 
typename BasePayload>
 
   99 Payload non_pointer_traits<Payload, BasePayload>::empty_payload = Payload();
 
  104 template<
typename FullKey, 
typename PayloadTraits, 
typename PolicyHook>
 
  107 template<
typename FullKey, 
typename PayloadTraits, 
typename PolicyHook>
 
  109 operator<<(std::ostream& os, const trie<FullKey, PayloadTraits, PolicyHook>& trie_node);
 
  111 template<
typename FullKey, 
typename PayloadTraits, 
typename PolicyHook>
 
  113 operator==(
const trie<FullKey, PayloadTraits, PolicyHook>& a,
 
  114            const trie<FullKey, PayloadTraits, PolicyHook>& b);
 
  116 template<
typename FullKey, 
typename PayloadTraits, 
typename PolicyHook>
 
  118 hash_value(
const trie<FullKey, PayloadTraits, PolicyHook>& trie_node);
 
  123 template<
class T, 
class NonConstT>
 
  127 class trie_point_iterator;
 
  129 template<
typename FullKey, 
typename PayloadTraits, 
typename PolicyHook>
 
  132   typedef typename FullKey::value_type Key;
 
  134   typedef trie* iterator;
 
  135   typedef const trie* const_iterator;
 
  137   typedef trie_iterator<trie, trie> recursive_iterator;
 
  138   typedef trie_iterator<const trie, trie> const_recursive_iterator;
 
  140   typedef trie_point_iterator<trie> point_iterator;
 
  141   typedef trie_point_iterator<const trie> const_point_iterator;
 
  143   typedef PayloadTraits payload_traits;
 
  145   inline trie(
const Key& key, 
size_t bucketSize = 1, 
size_t bucketIncrement = 1)
 
  147     , initialBucketSize_(bucketSize)
 
  148     , bucketIncrement_(bucketIncrement)
 
  149     , bucketSize_(initialBucketSize_)
 
  150     , buckets_(new bucket_type[bucketSize_]) 
 
  153     , children_(bucket_traits(buckets_.get(), bucketSize_))
 
  154     , payload_(PayloadTraits::empty_payload)
 
  161     payload_ = PayloadTraits::empty_payload; 
 
  162     children_.clear_and_dispose(trie_delete_disposer());
 
  168     children_.clear_and_dispose(trie_delete_disposer());
 
  171   template<
class Predicate>
 
  173   clear_if(Predicate cond)
 
  175     recursive_iterator trieNode(
this);
 
  176     recursive_iterator end(0);
 
  178     while (trieNode != end) {
 
  179       if (cond(*trieNode)) {
 
  180         trieNode = recursive_iterator(trieNode->erase());
 
  187   friend bool operator==<>(
const trie<FullKey, PayloadTraits, PolicyHook>& a,
 
  188                            const trie<FullKey, PayloadTraits, PolicyHook>& b);
 
  191   hash_value<>(
const trie<FullKey, PayloadTraits, PolicyHook>& trie_node);
 
  193   inline std::pair<iterator, bool>
 
  194   insert(
const FullKey& key, 
typename PayloadTraits::insert_type payload)
 
  196     trie* trieNode = 
this;
 
  198     BOOST_FOREACH (
const Key& subkey, key) {
 
  199       typename unordered_set::iterator item = trieNode->children_.find(subkey);
 
  200       if (item == trieNode->children_.end()) {
 
  201         trie* newNode = 
new trie(subkey, initialBucketSize_, bucketIncrement_);
 
  203         newNode->parent_ = trieNode;
 
  205         if (trieNode->children_.size() >= trieNode->bucketSize_) {
 
  206           trieNode->bucketSize_ += trieNode->bucketIncrement_;
 
  207           trieNode->bucketIncrement_ *= 2; 
 
  209           buckets_array newBuckets(
new bucket_type[trieNode->bucketSize_]);
 
  210           trieNode->children_.rehash(bucket_traits(newBuckets.get(), trieNode->bucketSize_));
 
  211           trieNode->buckets_.swap(newBuckets);
 
  214         std::pair<typename unordered_set::iterator, bool> ret =
 
  215           trieNode->children_.insert(*newNode);
 
  217         trieNode = &(*ret.first);
 
  223     if (trieNode->payload_ == PayloadTraits::empty_payload) {
 
  224       trieNode->payload_ = payload;
 
  225       return std::make_pair(trieNode, 
true);
 
  228       return std::make_pair(trieNode, 
false);
 
  237     payload_ = PayloadTraits::empty_payload;
 
  247     if (payload_ == PayloadTraits::empty_payload && children_.size() == 0) {
 
  251       trie* parent = parent_;
 
  253         .erase_and_dispose(*
this,
 
  254                            trie_delete_disposer()); 
 
  256       return parent->prune();
 
  267     if (payload_ == PayloadTraits::empty_payload && children_.size() == 0) {
 
  271       trie* parent = parent_;
 
  273         .erase_and_dispose(*
this,
 
  274                            trie_delete_disposer()); 
 
  290   inline std::tuple<iterator, bool, iterator>
 
  291   find(
const FullKey& key)
 
  293     trie* trieNode = 
this;
 
  294     iterator foundNode = (payload_ != PayloadTraits::empty_payload) ? 
this : 0;
 
  295     bool reachLast = 
true;
 
  297     BOOST_FOREACH (
const Key& subkey, key) {
 
  298       typename unordered_set::iterator item = trieNode->children_.find(subkey);
 
  299       if (item == trieNode->children_.end()) {
 
  306         if (trieNode->payload_ != PayloadTraits::empty_payload)
 
  307           foundNode = trieNode;
 
  311     return std::make_tuple(foundNode, reachLast, trieNode);
 
  320   template<
class Predicate>
 
  321   inline std::tuple<iterator, bool, iterator>
 
  322   find_if(
const FullKey& key, Predicate pred)
 
  324     trie* trieNode = 
this;
 
  325     iterator foundNode = (payload_ != PayloadTraits::empty_payload) ? 
this : 0;
 
  326     bool reachLast = 
true;
 
  328     BOOST_FOREACH (
const Key& subkey, key) {
 
  329       typename unordered_set::iterator item = trieNode->children_.find(subkey);
 
  330       if (item == trieNode->children_.end()) {
 
  337         if (trieNode->payload_ != PayloadTraits::empty_payload && pred(trieNode->payload_)) {
 
  338           foundNode = trieNode;
 
  343     return std::make_tuple(foundNode, reachLast, trieNode);
 
  354     if (payload_ != PayloadTraits::empty_payload)
 
  357     typedef trie<FullKey, PayloadTraits, PolicyHook> trie;
 
  358     for (
typename trie::unordered_set::iterator subnode = children_.begin();
 
  359          subnode != children_.end(); subnode++)
 
  362       iterator value = subnode->find();
 
  376   template<
class Predicate>
 
  377   inline const iterator
 
  378   find_if(Predicate pred)
 
  380     if (payload_ != PayloadTraits::empty_payload && pred(payload_))
 
  383     typedef trie<FullKey, PayloadTraits, PolicyHook> trie;
 
  384     for (
typename trie::unordered_set::iterator subnode = children_.begin();
 
  385          subnode != children_.end(); subnode++)
 
  388       iterator value = subnode->find_if(pred);
 
  405   template<
class Predicate>
 
  406   inline const iterator
 
  407   find_if_next_level(Predicate pred)
 
  409     typedef trie<FullKey, PayloadTraits, PolicyHook> trie;
 
  410     for (
typename trie::unordered_set::iterator subnode = children_.begin();
 
  411          subnode != children_.end(); subnode++) {
 
  412       if (pred(subnode->key())) {
 
  413         return subnode->find();
 
  432   typename PayloadTraits::const_return_type
 
  438   typename PayloadTraits::return_type
 
  445   set_payload(
typename PayloadTraits::insert_type payload)
 
  457   PrintStat(std::ostream& os) 
const;
 
  461   struct trie_delete_disposer {
 
  463     operator()(trie* delete_this)
 
  470   struct array_disposer {
 
  478   friend std::ostream& operator<<<>(std::ostream& os, 
const trie& trie_node);
 
  481   PolicyHook policy_hook_;
 
  484   boost::intrusive::unordered_set_member_hook<> unordered_set_member_hook_;
 
  487   typedef trie self_type;
 
  488   typedef boost::intrusive::member_hook<trie, boost::intrusive::unordered_set_member_hook<>,
 
  489                                         &trie::unordered_set_member_hook_> member_hook;
 
  491   typedef boost::intrusive::unordered_set<trie, member_hook> unordered_set;
 
  492   typedef typename unordered_set::bucket_type bucket_type;
 
  493   typedef typename unordered_set::bucket_traits bucket_traits;
 
  495   template<
class T, 
class NonConstT>
 
  496   friend class trie_iterator;
 
  499   friend class trie_point_iterator;
 
  507   size_t initialBucketSize_;
 
  508   size_t bucketIncrement_;
 
  511   typedef boost::interprocess::unique_ptr<bucket_type, array_disposer<bucket_type>> buckets_array;
 
  512   buckets_array buckets_;
 
  513   unordered_set children_;
 
  515   typename PayloadTraits::storage_type payload_;
 
  519 template<
typename FullKey, 
typename PayloadTraits, 
typename PolicyHook>
 
  521 operator<<(std::ostream& os, const trie<FullKey, PayloadTraits, PolicyHook>& trie_node)
 
  523   os << 
"# " << trie_node.key_ << ((trie_node.payload_ != PayloadTraits::empty_payload) ? 
"*" : 
"")
 
  525   typedef trie<FullKey, PayloadTraits, PolicyHook> trie;
 
  527   for (
typename trie::unordered_set::const_iterator subnode = trie_node.children_.begin();
 
  528        subnode != trie_node.children_.end(); subnode++)
 
  531     os << 
"\"" << &trie_node << 
"\"" 
  532        << 
" [label=\"" << trie_node.key_
 
  533        << ((trie_node.payload_ != PayloadTraits::empty_payload) ? 
"*" : 
"") << 
"\"]\n";
 
  534     os << 
"\"" << &(*subnode) << 
"\"" 
  535        << 
" [label=\"" << subnode->key_
 
  536        << ((subnode->payload_ != PayloadTraits::empty_payload) ? 
"*" : 
"") << 
"\"]" 
  539     os << 
"\"" << &trie_node << 
"\"" 
  541        << 
"\"" << &(*subnode) << 
"\"" 
  549 template<
typename FullKey, 
typename PayloadTraits, 
typename PolicyHook>
 
  551 trie<FullKey, PayloadTraits, PolicyHook>::PrintStat(std::ostream& os)
 const 
  553   os << 
"# " << key_ << ((payload_ != PayloadTraits::empty_payload) ? 
"*" : 
"") << 
": " 
  554      << children_.size() << 
" children" << std::endl;
 
  555   for (
size_t bucket = 0, maxbucket = children_.bucket_count(); bucket < maxbucket; bucket++) {
 
  556     os << 
" " << children_.bucket_size(bucket);
 
  560   typedef trie<FullKey, PayloadTraits, PolicyHook> trie;
 
  561   for (
typename trie::unordered_set::const_iterator subnode = children_.begin();
 
  562        subnode != children_.end(); subnode++)
 
  565     subnode->PrintStat(os);
 
  569 template<
typename FullKey, 
typename PayloadTraits, 
typename PolicyHook>
 
  571 operator==(
const trie<FullKey, PayloadTraits, PolicyHook>& a,
 
  572            const trie<FullKey, PayloadTraits, PolicyHook>& b)
 
  574   return a.key_ == b.key_;
 
  577 template<
typename FullKey, 
typename PayloadTraits, 
typename PolicyHook>
 
  579 hash_value(
const trie<FullKey, PayloadTraits, PolicyHook>& trie_node)
 
  584 template<
class Trie, 
class NonConstTrie> 
 
  585 class trie_iterator {
 
  591   trie_iterator(
typename Trie::iterator item)
 
  595   trie_iterator(Trie& item)
 
  604   const Trie& operator*()
 const 
  612   const Trie* operator->()
 const 
  617   operator==(trie_iterator<const Trie, NonConstTrie>& other)
 const 
  619     return (trie_ == other.trie_);
 
  622   operator==(trie_iterator<Trie, NonConstTrie>& other)
 
  624     return (trie_ == other.trie_);
 
  627   operator!=(trie_iterator<const Trie, NonConstTrie>& other)
 const 
  629     return !(*
this == other);
 
  632   operator!=(trie_iterator<Trie, NonConstTrie>& other)
 
  634     return !(*
this == other);
 
  637   trie_iterator<Trie, NonConstTrie>&
 
  640     if (trie_->children_.size() > 0)
 
  641       trie_ = &(*trie_->children_.begin());
 
  647   trie_iterator<Trie, NonConstTrie>&
 
  655   typedef typename boost::mpl::if_<boost::is_same<Trie, NonConstTrie>,
 
  656                                    typename Trie::unordered_set::iterator,
 
  657                                    typename Trie::unordered_set::const_iterator>::type set_iterator;
 
  662     if (trie_->parent_ != 0) {
 
  664       set_iterator item = 
const_cast<NonConstTrie*
>(trie_)
 
  665                             ->parent_->children_.iterator_to(const_cast<NonConstTrie&>(*trie_));
 
  667       if (item != trie_->parent_->children_.end()) {
 
  671         trie_ = trie_->parent_;
 
  684 class trie_point_iterator {
 
  686   typedef typename boost::mpl::if_<boost::is_same<Trie, const Trie>,
 
  687                                    typename Trie::unordered_set::const_iterator,
 
  688                                    typename Trie::unordered_set::iterator>::type set_iterator;
 
  691   trie_point_iterator()
 
  695   trie_point_iterator(
typename Trie::iterator item)
 
  699   trie_point_iterator(Trie& item)
 
  701     if (item.children_.size() != 0)
 
  702       trie_ = &*item.children_.begin();
 
  711   const Trie& operator*()
 const 
  719   const Trie* operator->()
 const 
  724   operator==(trie_point_iterator<const Trie>& other)
 const 
  726     return (trie_ == other.trie_);
 
  731     return (trie_ == other.trie_);
 
  734   operator!=(trie_point_iterator<const Trie>& other)
 const 
  736     return !(*
this == other);
 
  741     return !(*
this == other);
 
  744   trie_point_iterator<Trie>&
 
  747     if (trie_->parent_ != 0) {
 
  748       set_iterator item = trie_->parent_->children_.iterator_to(*trie_);
 
  750       if (item == trie_->parent_->children_.end())
 
  761   trie_point_iterator<Trie>&
 
std::size_t hash_value(const ::ndn::name::Component component)
 
bool operator!=(const GlobalRouter::Incidency &a, const GlobalRouter::Incidency &b)
 
bool operator==(const GlobalRouter::Incidency &a, const GlobalRouter::Incidency &b)