blob: 86ca01fe2443c5040a6905e6e309d1a329bed14a [file] [log] [blame]
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -07001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2011 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
19 */
20
Alexander Afanasyev9a989702012-06-29 17:44:00 -070021#ifndef TRIE_H_
22#define TRIE_H_
23
24#include "ns3/ptr.h"
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070025
26#include <boost/intrusive/unordered_set.hpp>
Alexander Afanasyev89fb5352012-06-12 22:43:16 -070027#include <boost/intrusive/list.hpp>
Alexander Afanasyev9a989702012-06-29 17:44:00 -070028#include <boost/intrusive/set.hpp>
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070029#include <boost/functional/hash.hpp>
Alexander Afanasyev89fb5352012-06-12 22:43:16 -070030#include <boost/interprocess/smart_ptr/unique_ptr.hpp>
31#include <boost/tuple/tuple.hpp>
Alexander Afanasyev78057c32012-07-06 15:18:46 -070032#include <boost/foreach.hpp>
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070033
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070034namespace ndnSIM
35{
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070036
37/////////////////////////////////////////////////////
38// Allow customization for payload
39//
40template<typename Payload>
41struct pointer_payload_traits
42{
Alexander Afanasyev9e96e362012-07-02 23:04:39 -070043 typedef Payload payload_type;
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070044 typedef Payload* pointer_type;
45 typedef const Payload* const_pointer_type;
46
Alexander Afanasyev78057c32012-07-06 15:18:46 -070047 static Payload* empty_payload;
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070048};
49
50template<typename Payload>
Alexander Afanasyev78057c32012-07-06 15:18:46 -070051Payload*
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070052pointer_payload_traits<Payload>::empty_payload = 0;
53
54template<typename Payload>
55struct smart_pointer_payload_traits
56{
Alexander Afanasyev9e96e362012-07-02 23:04:39 -070057 typedef Payload payload_type;
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070058 typedef ns3::Ptr<Payload> pointer_type;
59 typedef ns3::Ptr<const Payload> const_pointer_type;
60
Alexander Afanasyev78057c32012-07-06 15:18:46 -070061 static ns3::Ptr<Payload> empty_payload;
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070062};
63
64template<typename Payload>
Alexander Afanasyev78057c32012-07-06 15:18:46 -070065ns3::Ptr<Payload>
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070066smart_pointer_payload_traits<Payload>::empty_payload = 0;
67
68
69////////////////////////////////////////////////////
70// forward declarations
71//
Alexander Afanasyev89fb5352012-06-12 22:43:16 -070072template<typename FullKey,
73 typename Payload,
Alexander Afanasyev9a989702012-06-29 17:44:00 -070074 typename PayloadTraits,
75 typename PolicyHook >
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070076class trie;
77
Alexander Afanasyev89fb5352012-06-12 22:43:16 -070078template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070079inline std::ostream&
Alexander Afanasyev89fb5352012-06-12 22:43:16 -070080operator << (std::ostream &os,
81 const trie<FullKey, Payload, PayloadTraits, PolicyHook> &trie_node);
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070082
Alexander Afanasyev89fb5352012-06-12 22:43:16 -070083template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070084bool
Alexander Afanasyev89fb5352012-06-12 22:43:16 -070085operator== (const trie<FullKey, Payload, PayloadTraits, PolicyHook> &a,
86 const trie<FullKey, Payload, PayloadTraits, PolicyHook> &b);
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070087
Alexander Afanasyev89fb5352012-06-12 22:43:16 -070088template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook >
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070089std::size_t
Alexander Afanasyev89fb5352012-06-12 22:43:16 -070090hash_value (const trie<FullKey, Payload, PayloadTraits, PolicyHook> &trie_node);
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070091
92///////////////////////////////////////////////////
93// actual definition
94//
95
96
97template<typename FullKey,
Alexander Afanasyev89fb5352012-06-12 22:43:16 -070098 typename Payload, typename PayloadTraits,
99 typename PolicyHook >
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700100class trie
101{
102public:
103 typedef typename FullKey::partial_type Key;
104
105 typedef trie* iterator;
106 typedef const trie* const_iterator;
107
108 inline
109 trie (const Key &key, size_t bucketSize = 10, size_t bucketIncrement = 10);
110
111 inline
112 ~trie ();
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700113
114 void
115 clear ()
116 {
117 children_.clear_and_dispose (trie_delete_disposer ());
118 }
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700119
120 // actual entry
121 friend bool
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700122 operator== <> (const trie<FullKey, Payload, PayloadTraits, PolicyHook> &a,
123 const trie<FullKey, Payload, PayloadTraits, PolicyHook> &b);
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700124
125 friend std::size_t
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700126 hash_value <> (const trie<FullKey, Payload, PayloadTraits, PolicyHook> &trie_node);
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700127
128 inline std::pair<iterator, bool>
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700129 insert (const FullKey &key,
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700130 typename PayloadTraits::pointer_type payload);
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700131
132 /**
133 * @brief Removes payload (if it exists) and if there are no children, prunes parents trie
134 */
135 inline void
136 erase ();
137
138 /**
139 * @brief Do exactly as erase, but without erasing the payload
140 */
141 inline void
142 prune ();
143
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700144 inline boost::tuple<const iterator, bool, const iterator>
145 find (const FullKey &key) const
146 {
147 return const_cast<trie*> (this)->find (key);
148 }
149
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700150 /**
151 * @brief Perform the longest prefix match
152 * @param key the key for which to perform the longest prefix match
153 *
154 * @return ->second is true if prefix in ->first is longer than key
155 */
156 inline boost::tuple<iterator, bool, iterator>
157 find (const FullKey &key);
158
159 /**
160 * @brief Find next payload of the sub-trie
161 * @returns end() or a valid iterator pointing to the trie leaf (order is not defined, enumeration )
162 */
163 inline iterator
164 find ();
165
166 /**
167 * @brief Find next payload of the sub-trie satisfying the predicate
168 * @param pred predicate
169 * @returns end() or a valid iterator pointing to the trie leaf (order is not defined, enumeration )
170 */
171 template<class Predicate>
172 inline iterator
173 find_if (Predicate pred);
174
175 iterator end ()
176 {
177 return 0;
178 }
179
180 const_iterator end () const
181 {
182 return 0;
183 }
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700184
185 typename PayloadTraits::const_pointer_type
186 payload () const
187 {
188 return payload_;
189 }
190
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700191 typename PayloadTraits::pointer_type
192 payload ()
193 {
194 return payload_;
195 }
196
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700197 void
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700198 set_payload (typename PayloadTraits::pointer_type payload)
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700199 {
200 payload_ = payload;
201 }
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700202
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700203 inline void
204 PrintStat (std::ostream &os) const;
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700205
206private:
207 //The disposer object function
208 struct trie_delete_disposer
209 {
210 void operator() (trie *delete_this)
211 {
212 // std::cout << "Deleting " << delete_this << "\n";
213 delete delete_this;
214 }
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700215 };
216
217 template<class D>
218 struct array_disposer
219 {
220 void operator() (D *array)
221 {
222 delete [] array;
223 }
224 };
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700225
226 friend
227 std::ostream&
228 operator<< < > (std::ostream &os, const trie &trie_node);
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700229
230public:
231 PolicyHook policy_hook_;
232
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700233private:
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700234 boost::intrusive::unordered_set_member_hook<> unordered_set_member_hook_;
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700235
236 // necessary typedefs
237 typedef trie self_type;
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700238 typedef boost::intrusive::member_hook< trie,
239 boost::intrusive::unordered_set_member_hook< >,
240 &trie::unordered_set_member_hook_ > member_hook;
241 typedef boost::intrusive::unordered_set< trie, member_hook > unordered_set;
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700242 typedef typename unordered_set::bucket_type bucket_type;
243 typedef typename unordered_set::bucket_traits bucket_traits;
244
245 ////////////////////////////////////////////////
246 // Actual data
247 ////////////////////////////////////////////////
248
249 Key key_; ///< name component
250
251 size_t initialBucketSize_;
252 size_t bucketIncrement_;
253
254 size_t bucketSize_;
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700255 typedef boost::interprocess::unique_ptr< bucket_type, array_disposer<bucket_type> > buckets_array;
256 buckets_array buckets_;
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700257 unordered_set children_;
258
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700259 typename PayloadTraits::pointer_type payload_;
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700260 trie *parent_; // to make cleaning effective
261};
262
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700263template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
264trie<FullKey, Payload, PayloadTraits, PolicyHook>
265::trie (const trie::Key &key, size_t bucketSize, size_t bucketIncrement)
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700266 : key_ (key)
267 , initialBucketSize_ (bucketSize)
268 , bucketIncrement_ (bucketIncrement)
269 , bucketSize_ (initialBucketSize_)
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700270 , buckets_ (new bucket_type [bucketSize_]) //cannot use normal pointer, because lifetime of buckets should be larger than lifetime of the container
271 , children_ (bucket_traits (buckets_.get (), bucketSize_))
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700272 , payload_ (PayloadTraits::empty_payload)
273 , parent_ (0)
274{
275}
276
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700277template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
278trie<FullKey, Payload, PayloadTraits, PolicyHook>
279::~trie ()
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700280{
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700281 payload_ = PayloadTraits::empty_payload; // necessary for smart pointers...
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700282 children_.clear_and_dispose (trie_delete_disposer ());
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700283}
284
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700285template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700286inline
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700287std::pair<typename trie<FullKey, Payload, PayloadTraits, PolicyHook>::iterator, bool>
288trie<FullKey, Payload, PayloadTraits, PolicyHook>
Alexander Afanasyev78057c32012-07-06 15:18:46 -0700289::insert (const FullKey &key, typename PayloadTraits::pointer_type payload)
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700290{
291 trie *trieNode = this;
292
293 BOOST_FOREACH (const Key &subkey, key)
294 {
295 typename unordered_set::iterator item = trieNode->children_.find (subkey);
296 if (item == trieNode->children_.end ())
297 {
298 trie *newNode = new trie (subkey, initialBucketSize_, bucketIncrement_);
299 // std::cout << "new " << newNode << "\n";
300 newNode->parent_ = trieNode;
301
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700302 if (trieNode->children_.size () >= trieNode->bucketSize_)
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700303 {
304 trieNode->bucketSize_ += trieNode->bucketIncrement_;
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700305 buckets_array newBuckets (new bucket_type [trieNode->bucketSize_]);
306 trieNode->children_.rehash (bucket_traits (newBuckets.get (), trieNode->bucketSize_));
307 trieNode->buckets_.swap (newBuckets);
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700308 }
309
310 std::pair< typename unordered_set::iterator, bool > ret =
311 trieNode->children_.insert (*newNode);
312
313 trieNode = &(*ret.first);
314 }
315 else
316 trieNode = &(*item);
317 }
318
319 if (trieNode->payload_ == 0)
320 {
321 trieNode->payload_ = payload;
322 return std::make_pair (trieNode, true);
323 }
324 else
325 return std::make_pair (trieNode, false);
326}
327
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700328template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700329inline
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700330boost::tuple<typename trie<FullKey, Payload, PayloadTraits, PolicyHook>::iterator,
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700331 bool,
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700332 typename trie<FullKey, Payload, PayloadTraits, PolicyHook>::iterator>
333trie<FullKey, Payload, PayloadTraits, PolicyHook>
334::find (const FullKey &key)
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700335{
336 trie *trieNode = this;
337 iterator foundNode = (payload_ != PayloadTraits::empty_payload) ? this : 0;
338 bool reachLast = true;
339
340 BOOST_FOREACH (const Key &subkey, key)
341 {
342 typename unordered_set::iterator item = trieNode->children_.find (subkey);
343 if (item == trieNode->children_.end ())
344 {
345 reachLast = false;
346 break;
347 }
348 else
349 {
350 trieNode = &(*item);
351
352 if (trieNode->payload_ != PayloadTraits::empty_payload)
353 foundNode = trieNode;
354 }
355 }
356
357 return boost::make_tuple (foundNode, reachLast, trieNode);
358}
359
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700360template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
361inline typename trie<FullKey, Payload, PayloadTraits, PolicyHook>::iterator
362trie<FullKey, Payload, PayloadTraits, PolicyHook>
363::find ()
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700364{
365 if (payload_ != PayloadTraits::empty_payload)
366 return this;
367
Alexander Afanasyev9a989702012-06-29 17:44:00 -0700368 typedef trie<FullKey, Payload, PayloadTraits, PolicyHook> trie;
Alexander Afanasyev051d3782012-07-03 10:10:15 -0700369 for (typename trie::unordered_set::iterator subnode = children_.begin ();
370 subnode != children_.end ();
371 subnode++ )
372 // BOOST_FOREACH (trie &subnode, children_)
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700373 {
Alexander Afanasyev051d3782012-07-03 10:10:15 -0700374 iterator value = subnode->find ();
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700375 if (value != 0)
376 return value;
377 }
378
379 return 0;
380}
381
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700382template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700383template<class Predicate>
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700384inline typename trie<FullKey, Payload, PayloadTraits, PolicyHook>::iterator
385trie<FullKey, Payload, PayloadTraits, PolicyHook>
386::find_if (Predicate pred)
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700387{
388 if (payload_ != PayloadTraits::empty_payload && pred (payload_))
389 return this;
390
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700391 typedef trie<FullKey, Payload, PayloadTraits, PolicyHook> trie;
Alexander Afanasyev051d3782012-07-03 10:10:15 -0700392 for (typename trie::unordered_set::iterator subnode = children_.begin ();
393 subnode != children_.end ();
394 subnode++ )
395 // BOOST_FOREACH (const trie &subnode, children_)
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700396 {
Alexander Afanasyev051d3782012-07-03 10:10:15 -0700397 iterator value = subnode->find ();
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700398 if (value != 0)
Alexander Afanasyev051d3782012-07-03 10:10:15 -0700399 return value;
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700400 }
401
402 return 0;
403}
404
405
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700406template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700407inline void
Alexander Afanasyevb0c43892012-06-13 00:52:58 -0700408trie<FullKey, Payload, PayloadTraits, PolicyHook>
409::erase ()
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700410{
411 payload_ = PayloadTraits::empty_payload;
412 prune ();
413}
414
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700415template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700416inline void
Alexander Afanasyevb0c43892012-06-13 00:52:58 -0700417trie<FullKey, Payload, PayloadTraits, PolicyHook>
418::prune ()
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700419{
420 if (payload_ == 0 && children_.size () == 0)
421 {
422 if (parent_ == 0) return;
423
424 trie *parent = parent_;
425 parent->children_.erase_and_dispose (*this, trie_delete_disposer ()); // delete this; basically, committing a suicide
426
427 parent->prune ();
428 }
429}
430
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700431template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700432inline std::ostream&
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700433operator << (std::ostream &os, const trie<FullKey, Payload, PayloadTraits, PolicyHook> &trie_node)
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700434{
435 os << "# " << trie_node.key_ << ((trie_node.payload_ != 0)?"*":"") << std::endl;
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700436 typedef trie<FullKey, Payload, PayloadTraits, PolicyHook> trie;
Alexander Afanasyev051d3782012-07-03 10:10:15 -0700437
438 for (typename trie::unordered_set::const_iterator subnode = trie_node.children_.begin ();
439 subnode != trie_node.children_.end ();
440 subnode++ )
441 // BOOST_FOREACH (const trie &subnode, trie_node.children_)
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700442 {
443 os << "\"" << &trie_node << "\"" << " [label=\"" << trie_node.key_ << ((trie_node.payload_ != 0)?"*":"") << "\"]\n";
Alexander Afanasyev051d3782012-07-03 10:10:15 -0700444 os << "\"" << &(*subnode) << "\"" << " [label=\"" << subnode->key_ << ((subnode->payload_ != 0)?"*":"") << "\"]""\n";
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700445
Alexander Afanasyev051d3782012-07-03 10:10:15 -0700446 os << "\"" << &trie_node << "\"" << " -> " << "\"" << &(*subnode) << "\"" << "\n";
447 os << *subnode;
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700448 }
449
450 return os;
451}
452
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700453template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
454inline void
Alexander Afanasyevb0c43892012-06-13 00:52:58 -0700455trie<FullKey, Payload, PayloadTraits, PolicyHook>
456::PrintStat (std::ostream &os) const
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700457{
458 os << "# " << key_ << ((payload_ != 0)?"*":"") << ": " << children_.size() << " children" << std::endl;
459 for (size_t bucket = 0, maxbucket = children_.bucket_count ();
460 bucket < maxbucket;
461 bucket++)
462 {
463 os << " " << children_.bucket_size (bucket);
464 }
465 os << "\n";
466
467 typedef trie<FullKey, Payload, PayloadTraits, PolicyHook> trie;
Alexander Afanasyev051d3782012-07-03 10:10:15 -0700468 for (typename trie::unordered_set::const_iterator subnode = children_.begin ();
469 subnode != children_.end ();
470 subnode++ )
471 // BOOST_FOREACH (const trie &subnode, children_)
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700472 {
Alexander Afanasyev051d3782012-07-03 10:10:15 -0700473 subnode->PrintStat (os);
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700474 }
475}
476
477
478template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700479inline bool
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700480operator == (const trie<FullKey, Payload, PayloadTraits, PolicyHook> &a,
481 const trie<FullKey, Payload, PayloadTraits, PolicyHook> &b)
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700482{
483 return a.key_ == b.key_;
484}
485
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700486template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700487inline std::size_t
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700488hash_value (const trie<FullKey, Payload, PayloadTraits, PolicyHook> &trie_node)
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700489{
490 return boost::hash_value (trie_node.key_);
491}
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700492
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700493} // ndnSIM
494
Alexander Afanasyev9a989702012-06-29 17:44:00 -0700495#endif // TRIE_H_