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)