blob: 47e62e5a93adb2d5e4b54d06753634bb3c0bd5e0 [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 Afanasyevfd0c41c2012-06-11 22:15:49 -070032
Alexander Afanasyev30cb1172012-07-06 10:47:39 -070033namespace ndnSIM
34{
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070035
36/////////////////////////////////////////////////////
37// Allow customization for payload
38//
39template<typename Payload>
40struct pointer_payload_traits
41{
Alexander Afanasyev9e96e362012-07-02 23:04:39 -070042 typedef Payload payload_type;
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070043 typedef Payload* pointer_type;
44 typedef const Payload* const_pointer_type;
45
46 static const Payload* empty_payload;
47};
48
49template<typename Payload>
50const Payload*
51pointer_payload_traits<Payload>::empty_payload = 0;
52
53template<typename Payload>
54struct smart_pointer_payload_traits
55{
Alexander Afanasyev9e96e362012-07-02 23:04:39 -070056 typedef Payload payload_type;
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070057 typedef ns3::Ptr<Payload> pointer_type;
58 typedef ns3::Ptr<const Payload> const_pointer_type;
59
60 static const ns3::Ptr<const Payload> empty_payload;
61};
62
63template<typename Payload>
64const ns3::Ptr<const Payload>
65smart_pointer_payload_traits<Payload>::empty_payload = 0;
66
67
68////////////////////////////////////////////////////
69// forward declarations
70//
Alexander Afanasyev89fb5352012-06-12 22:43:16 -070071template<typename FullKey,
72 typename Payload,
Alexander Afanasyev9a989702012-06-29 17:44:00 -070073 typename PayloadTraits,
74 typename PolicyHook >
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070075class trie;
76
Alexander Afanasyev89fb5352012-06-12 22:43:16 -070077template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070078inline std::ostream&
Alexander Afanasyev89fb5352012-06-12 22:43:16 -070079operator << (std::ostream &os,
80 const trie<FullKey, Payload, PayloadTraits, PolicyHook> &trie_node);
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070081
Alexander Afanasyev89fb5352012-06-12 22:43:16 -070082template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070083bool
Alexander Afanasyev89fb5352012-06-12 22:43:16 -070084operator== (const trie<FullKey, Payload, PayloadTraits, PolicyHook> &a,
85 const trie<FullKey, Payload, PayloadTraits, PolicyHook> &b);
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070086
Alexander Afanasyev89fb5352012-06-12 22:43:16 -070087template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook >
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070088std::size_t
Alexander Afanasyev89fb5352012-06-12 22:43:16 -070089hash_value (const trie<FullKey, Payload, PayloadTraits, PolicyHook> &trie_node);
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070090
91///////////////////////////////////////////////////
92// actual definition
93//
94
95
96template<typename FullKey,
Alexander Afanasyev89fb5352012-06-12 22:43:16 -070097 typename Payload, typename PayloadTraits,
98 typename PolicyHook >
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070099class trie
100{
101public:
102 typedef typename FullKey::partial_type Key;
103
104 typedef trie* iterator;
105 typedef const trie* const_iterator;
106
107 inline
108 trie (const Key &key, size_t bucketSize = 10, size_t bucketIncrement = 10);
109
110 inline
111 ~trie ();
112
113 // actual entry
114 friend bool
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700115 operator== <> (const trie<FullKey, Payload, PayloadTraits, PolicyHook> &a,
116 const trie<FullKey, Payload, PayloadTraits, PolicyHook> &b);
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700117
118 friend std::size_t
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700119 hash_value <> (const trie<FullKey, Payload, PayloadTraits, PolicyHook> &trie_node);
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700120
121 inline std::pair<iterator, bool>
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700122 insert (const FullKey &key,
123 typename PayloadTraits::const_pointer_type payload);
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700124
125 /**
126 * @brief Removes payload (if it exists) and if there are no children, prunes parents trie
127 */
128 inline void
129 erase ();
130
131 /**
132 * @brief Do exactly as erase, but without erasing the payload
133 */
134 inline void
135 prune ();
136
137 /**
138 * @brief Perform the longest prefix match
139 * @param key the key for which to perform the longest prefix match
140 *
141 * @return ->second is true if prefix in ->first is longer than key
142 */
143 inline boost::tuple<iterator, bool, iterator>
144 find (const FullKey &key);
145
146 /**
147 * @brief Find next payload of the sub-trie
148 * @returns end() or a valid iterator pointing to the trie leaf (order is not defined, enumeration )
149 */
150 inline iterator
151 find ();
152
153 /**
154 * @brief Find next payload of the sub-trie satisfying the predicate
155 * @param pred predicate
156 * @returns end() or a valid iterator pointing to the trie leaf (order is not defined, enumeration )
157 */
158 template<class Predicate>
159 inline iterator
160 find_if (Predicate pred);
161
162 iterator end ()
163 {
164 return 0;
165 }
166
167 const_iterator end () const
168 {
169 return 0;
170 }
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700171
172 typename PayloadTraits::const_pointer_type
173 payload () const
174 {
175 return payload_;
176 }
177
178 void
179 set_payload (typename PayloadTraits::const_pointer_type payload)
180 {
181 payload_ = payload;
182 }
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700183
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700184 inline void
185 PrintStat (std::ostream &os) const;
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700186
187private:
188 //The disposer object function
189 struct trie_delete_disposer
190 {
191 void operator() (trie *delete_this)
192 {
193 // std::cout << "Deleting " << delete_this << "\n";
194 delete delete_this;
195 }
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700196 };
197
198 template<class D>
199 struct array_disposer
200 {
201 void operator() (D *array)
202 {
203 delete [] array;
204 }
205 };
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700206
207 friend
208 std::ostream&
209 operator<< < > (std::ostream &os, const trie &trie_node);
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700210
211public:
212 PolicyHook policy_hook_;
213
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700214private:
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700215 boost::intrusive::unordered_set_member_hook<> unordered_set_member_hook_;
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700216
217 // necessary typedefs
218 typedef trie self_type;
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700219 typedef boost::intrusive::member_hook< trie,
220 boost::intrusive::unordered_set_member_hook< >,
221 &trie::unordered_set_member_hook_ > member_hook;
222 typedef boost::intrusive::unordered_set< trie, member_hook > unordered_set;
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700223 typedef typename unordered_set::bucket_type bucket_type;
224 typedef typename unordered_set::bucket_traits bucket_traits;
225
226 ////////////////////////////////////////////////
227 // Actual data
228 ////////////////////////////////////////////////
229
230 Key key_; ///< name component
231
232 size_t initialBucketSize_;
233 size_t bucketIncrement_;
234
235 size_t bucketSize_;
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700236 typedef boost::interprocess::unique_ptr< bucket_type, array_disposer<bucket_type> > buckets_array;
237 buckets_array buckets_;
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700238 unordered_set children_;
239
240 typename PayloadTraits::const_pointer_type payload_;
241 trie *parent_; // to make cleaning effective
242};
243
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700244template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
245trie<FullKey, Payload, PayloadTraits, PolicyHook>
246::trie (const trie::Key &key, size_t bucketSize, size_t bucketIncrement)
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700247 : key_ (key)
248 , initialBucketSize_ (bucketSize)
249 , bucketIncrement_ (bucketIncrement)
250 , bucketSize_ (initialBucketSize_)
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700251 , buckets_ (new bucket_type [bucketSize_]) //cannot use normal pointer, because lifetime of buckets should be larger than lifetime of the container
252 , children_ (bucket_traits (buckets_.get (), bucketSize_))
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700253 , payload_ (PayloadTraits::empty_payload)
254 , parent_ (0)
255{
256}
257
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700258template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
259trie<FullKey, Payload, PayloadTraits, PolicyHook>
260::~trie ()
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700261{
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700262 payload_ = PayloadTraits::empty_payload; // necessary for smart pointers...
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700263 children_.clear_and_dispose (trie_delete_disposer ());
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700264}
265
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700266template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700267inline
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700268std::pair<typename trie<FullKey, Payload, PayloadTraits, PolicyHook>::iterator, bool>
269trie<FullKey, Payload, PayloadTraits, PolicyHook>
270::insert (const FullKey &key, typename PayloadTraits::const_pointer_type payload)
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700271{
272 trie *trieNode = this;
273
274 BOOST_FOREACH (const Key &subkey, key)
275 {
276 typename unordered_set::iterator item = trieNode->children_.find (subkey);
277 if (item == trieNode->children_.end ())
278 {
279 trie *newNode = new trie (subkey, initialBucketSize_, bucketIncrement_);
280 // std::cout << "new " << newNode << "\n";
281 newNode->parent_ = trieNode;
282
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700283 if (trieNode->children_.size () >= trieNode->bucketSize_)
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700284 {
285 trieNode->bucketSize_ += trieNode->bucketIncrement_;
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700286 buckets_array newBuckets (new bucket_type [trieNode->bucketSize_]);
287 trieNode->children_.rehash (bucket_traits (newBuckets.get (), trieNode->bucketSize_));
288 trieNode->buckets_.swap (newBuckets);
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700289 }
290
291 std::pair< typename unordered_set::iterator, bool > ret =
292 trieNode->children_.insert (*newNode);
293
294 trieNode = &(*ret.first);
295 }
296 else
297 trieNode = &(*item);
298 }
299
300 if (trieNode->payload_ == 0)
301 {
302 trieNode->payload_ = payload;
303 return std::make_pair (trieNode, true);
304 }
305 else
306 return std::make_pair (trieNode, false);
307}
308
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700309template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700310inline
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700311boost::tuple<typename trie<FullKey, Payload, PayloadTraits, PolicyHook>::iterator,
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700312 bool,
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700313 typename trie<FullKey, Payload, PayloadTraits, PolicyHook>::iterator>
314trie<FullKey, Payload, PayloadTraits, PolicyHook>
315::find (const FullKey &key)
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700316{
317 trie *trieNode = this;
318 iterator foundNode = (payload_ != PayloadTraits::empty_payload) ? this : 0;
319 bool reachLast = true;
320
321 BOOST_FOREACH (const Key &subkey, key)
322 {
323 typename unordered_set::iterator item = trieNode->children_.find (subkey);
324 if (item == trieNode->children_.end ())
325 {
326 reachLast = false;
327 break;
328 }
329 else
330 {
331 trieNode = &(*item);
332
333 if (trieNode->payload_ != PayloadTraits::empty_payload)
334 foundNode = trieNode;
335 }
336 }
337
338 return boost::make_tuple (foundNode, reachLast, trieNode);
339}
340
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700341template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
342inline typename trie<FullKey, Payload, PayloadTraits, PolicyHook>::iterator
343trie<FullKey, Payload, PayloadTraits, PolicyHook>
344::find ()
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700345{
346 if (payload_ != PayloadTraits::empty_payload)
347 return this;
348
Alexander Afanasyev9a989702012-06-29 17:44:00 -0700349 typedef trie<FullKey, Payload, PayloadTraits, PolicyHook> trie;
Alexander Afanasyev051d3782012-07-03 10:10:15 -0700350 for (typename trie::unordered_set::iterator subnode = children_.begin ();
351 subnode != children_.end ();
352 subnode++ )
353 // BOOST_FOREACH (trie &subnode, children_)
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700354 {
Alexander Afanasyev051d3782012-07-03 10:10:15 -0700355 iterator value = subnode->find ();
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700356 if (value != 0)
357 return value;
358 }
359
360 return 0;
361}
362
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700363template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700364template<class Predicate>
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700365inline typename trie<FullKey, Payload, PayloadTraits, PolicyHook>::iterator
366trie<FullKey, Payload, PayloadTraits, PolicyHook>
367::find_if (Predicate pred)
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700368{
369 if (payload_ != PayloadTraits::empty_payload && pred (payload_))
370 return this;
371
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700372 typedef trie<FullKey, Payload, PayloadTraits, PolicyHook> trie;
Alexander Afanasyev051d3782012-07-03 10:10:15 -0700373 for (typename trie::unordered_set::iterator subnode = children_.begin ();
374 subnode != children_.end ();
375 subnode++ )
376 // BOOST_FOREACH (const trie &subnode, children_)
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700377 {
Alexander Afanasyev051d3782012-07-03 10:10:15 -0700378 iterator value = subnode->find ();
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700379 if (value != 0)
Alexander Afanasyev051d3782012-07-03 10:10:15 -0700380 return value;
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700381 }
382
383 return 0;
384}
385
386
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700387template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700388inline void
Alexander Afanasyevb0c43892012-06-13 00:52:58 -0700389trie<FullKey, Payload, PayloadTraits, PolicyHook>
390::erase ()
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700391{
392 payload_ = PayloadTraits::empty_payload;
393 prune ();
394}
395
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700396template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700397inline void
Alexander Afanasyevb0c43892012-06-13 00:52:58 -0700398trie<FullKey, Payload, PayloadTraits, PolicyHook>
399::prune ()
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700400{
401 if (payload_ == 0 && children_.size () == 0)
402 {
403 if (parent_ == 0) return;
404
405 trie *parent = parent_;
406 parent->children_.erase_and_dispose (*this, trie_delete_disposer ()); // delete this; basically, committing a suicide
407
408 parent->prune ();
409 }
410}
411
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700412template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700413inline std::ostream&
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700414operator << (std::ostream &os, const trie<FullKey, Payload, PayloadTraits, PolicyHook> &trie_node)
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700415{
416 os << "# " << trie_node.key_ << ((trie_node.payload_ != 0)?"*":"") << std::endl;
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700417 typedef trie<FullKey, Payload, PayloadTraits, PolicyHook> trie;
Alexander Afanasyev051d3782012-07-03 10:10:15 -0700418
419 for (typename trie::unordered_set::const_iterator subnode = trie_node.children_.begin ();
420 subnode != trie_node.children_.end ();
421 subnode++ )
422 // BOOST_FOREACH (const trie &subnode, trie_node.children_)
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700423 {
424 os << "\"" << &trie_node << "\"" << " [label=\"" << trie_node.key_ << ((trie_node.payload_ != 0)?"*":"") << "\"]\n";
Alexander Afanasyev051d3782012-07-03 10:10:15 -0700425 os << "\"" << &(*subnode) << "\"" << " [label=\"" << subnode->key_ << ((subnode->payload_ != 0)?"*":"") << "\"]""\n";
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700426
Alexander Afanasyev051d3782012-07-03 10:10:15 -0700427 os << "\"" << &trie_node << "\"" << " -> " << "\"" << &(*subnode) << "\"" << "\n";
428 os << *subnode;
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700429 }
430
431 return os;
432}
433
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700434template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
435inline void
Alexander Afanasyevb0c43892012-06-13 00:52:58 -0700436trie<FullKey, Payload, PayloadTraits, PolicyHook>
437::PrintStat (std::ostream &os) const
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700438{
439 os << "# " << key_ << ((payload_ != 0)?"*":"") << ": " << children_.size() << " children" << std::endl;
440 for (size_t bucket = 0, maxbucket = children_.bucket_count ();
441 bucket < maxbucket;
442 bucket++)
443 {
444 os << " " << children_.bucket_size (bucket);
445 }
446 os << "\n";
447
448 typedef trie<FullKey, Payload, PayloadTraits, PolicyHook> trie;
Alexander Afanasyev051d3782012-07-03 10:10:15 -0700449 for (typename trie::unordered_set::const_iterator subnode = children_.begin ();
450 subnode != children_.end ();
451 subnode++ )
452 // BOOST_FOREACH (const trie &subnode, children_)
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700453 {
Alexander Afanasyev051d3782012-07-03 10:10:15 -0700454 subnode->PrintStat (os);
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700455 }
456}
457
458
459template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700460inline bool
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700461operator == (const trie<FullKey, Payload, PayloadTraits, PolicyHook> &a,
462 const trie<FullKey, Payload, PayloadTraits, PolicyHook> &b)
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700463{
464 return a.key_ == b.key_;
465}
466
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700467template<typename FullKey, typename Payload, typename PayloadTraits, typename PolicyHook>
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700468inline std::size_t
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700469hash_value (const trie<FullKey, Payload, PayloadTraits, PolicyHook> &trie_node)
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700470{
471 return boost::hash_value (trie_node.key_);
472}
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700473
Alexander Afanasyev30cb1172012-07-06 10:47:39 -0700474} // ndnSIM
475
Alexander Afanasyev9a989702012-06-29 17:44:00 -0700476#endif // TRIE_H_