blob: fb10fc4d32d725e8cfe67129c981387d909d2e35 [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) 2012 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
21#include "ns3/core-module.h"
22#include "ns3/ndnSIM-module.h"
Alexander Afanasyev9a989702012-06-29 17:44:00 -070023#include "../utils/trie-with-policy.h"
Alexander Afanasyev9e96e362012-07-02 23:04:39 -070024#include "../utils/lru-policy.h"
25#include "../utils/random-policy.h"
26#include "../utils/fifo-policy.h"
27#include <boost/intrusive/parent_from_member.hpp>
Alexander Afanasyev903062f2012-07-04 18:25:26 -070028#include <boost/mpl/vector.hpp>
29#include <boost/mpl/inherit.hpp>
30#include <boost/mpl/assert.hpp>
31#include <boost/type_traits.hpp>
32#include <boost/mpl/inherit_linearly.hpp>
33#include <boost/mpl/range_c.hpp>
34#include <boost/mpl/copy.hpp>
35#include <boost/mpl/vector_c.hpp>
36#include <boost/mpl/clear.hpp>
37#include <boost/mpl/sequence_tag.hpp>
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070038
39using namespace ns3;
Alexander Afanasyev903062f2012-07-04 18:25:26 -070040namespace mpl = boost::mpl;
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070041
42NS_LOG_COMPONENT_DEFINE ("Trie");
43
44class Integer : public ns3::SimpleRefCount<Integer>
45{
46public:
47 Integer (int value) : value_ (value) {}
Alexander Afanasyev89fb5352012-06-12 22:43:16 -070048
49 operator int () const { return value_; }
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -070050private:
51 int value_;
52};
53
Alexander Afanasyev89fb5352012-06-12 22:43:16 -070054std::ostream &
55operator << (std::ostream &os, const Integer &i)
56{
57 os << (int)i;
58 return os;
59}
60
Alexander Afanasyev903062f2012-07-04 18:25:26 -070061template <class T>
62struct wrap
Alexander Afanasyev9e96e362012-07-02 23:04:39 -070063{
Alexander Afanasyev903062f2012-07-04 18:25:26 -070064 T value_;
Alexander Afanasyev9e96e362012-07-02 23:04:39 -070065};
66
Alexander Afanasyev903062f2012-07-04 18:25:26 -070067template< class Vector >
68struct multi_type_container
69 : public mpl::inherit_linearly< Vector, mpl::inherit<wrap<mpl::_2>, mpl::_1 >
70 >::type
71{
72 template<int N>
73 struct index
74 {
75 typedef typename mpl::at_c<Vector, N>::type type;
76 };
77
78 template<class T>
79 T &
80 get ()
81 {
82 return static_cast< wrap<T> &> (*this).value_;
83 }
84
85 template<class T>
86 const T &
87 get () const
88 {
89 return static_cast< const wrap<T> &> (*this).value_;
90 }
91
92 template<int N>
93 typename mpl::at_c<Vector, N>::type &
94 get ()
95 {
96 typedef typename mpl::at_c<Vector, N>::type T;
97 return static_cast< wrap<T> &> (*this).value_;
98 }
99
100 template<int N>
101 const typename mpl::at_c<Vector, N>::type &
102 get () const
103 {
104 typedef typename mpl::at_c<Vector, N>::type T;
105 return static_cast< const wrap<T> &> (*this).value_;
106 }
107};
108
109///////////////////////////////////////////////////////////////////////////
110///////////////////////////////////////////////////////////////////////////
111///////////////////////////////////////////////////////////////////////////
112
113template< class Base, class Value >
114struct policy_wrap
115{
116 typedef Value value_type;
117
118 policy_wrap (Base &base)
119 : value_ (base)
120 { }
121
122 Value value_;
123};
124
125template< class Base, class Super/*empy_wrap/previous level*/, class Value/*policy_wrap< element in vector >*/ >
126struct inherit_with_base : Super, Value
127{
128 inherit_with_base (Base &base)
129 : Super (base), Value (base)
130 { }
131
132 void
133 update (typename Base::iterator item)
134 {
135 Value::value_.update (item);
136 Super::update (item);
137 }
138
139 bool
140 insert (typename Base::iterator item)
141 {
142 // BOOST_MPL_ASSERT ((boost::is_same<Item,typename Base::iterator>));
143 bool ok = Value::value_.insert (item);
144 if (!ok)
145 return false;
146
147 ok = Super::insert (item);
148 if (!ok)
149 {
150 Value::value_.erase (item);
151 return false;
152 }
153 return true;
154 }
155
156 void
157 lookup (typename Base::iterator item)
158 {
159 Value::value_.lookup (item);
160 Super::lookup (item);
161 }
162
163 void
164 erase (typename Base::iterator item)
165 {
166 Value::value_.erase (item);
167 Super::erase (item);
168 }
169};
170
171template< class Base >
172struct empty_policy_wrap
173{
174 empty_policy_wrap (Base &base) { }
175
176 void update (typename Base::iterator item) {}
177 bool insert (typename Base::iterator item) { return true; }
178 void lookup (typename Base::iterator item) {}
179 void erase (typename Base::iterator item) {}
180};
181
182template< class Base, class Vector >
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700183struct multi_policy_container
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700184 : public mpl::fold< Vector,
185 empty_policy_wrap<Base>,
186 inherit_with_base<Base,
187 mpl::_1/*empty/previous*/,
188 policy_wrap<Base, mpl::_2>/*element in vector*/>
189 >::type
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700190{
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700191 typedef typename mpl::fold< Vector,
192 empty_policy_wrap<Base>,
193 inherit_with_base<Base,
194 mpl::_1/*empty/previous*/,
195 policy_wrap<Base, mpl::_2>/*element in vector*/>
196 >::type super;
197
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700198 multi_policy_container (Base &base)
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700199 : super (base)
200 { }
201
202 template<int N>
203 struct index
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700204 {
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700205 typedef typename mpl::at_c<Vector, N>::type type;
206 };
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700207
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700208 template<class T>
209 T &
210 get ()
211 {
212 return static_cast< policy_wrap<Base, T> &> (*this).value_;
213 }
214
215 template<class T>
216 const T &
217 get () const
218 {
219 return static_cast< const policy_wrap<Base, T> &> (*this).value_;
220 }
221
222 template<int N>
223 typename mpl::at_c<Vector, N>::type &
224 get ()
225 {
226 typedef typename mpl::at_c<Vector, N>::type T;
227 return static_cast< policy_wrap<Base, T> &> (*this).value_;
228 }
229
230 template<int N>
231 const typename mpl::at_c<Vector, N>::type &
232 get () const
233 {
234 typedef typename mpl::at_c<Vector, N>::type T;
235 return static_cast< const policy_wrap<Base, T> &> (*this).value_;
236 }
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700237};
238
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700239
240template<class BaseHook, class ValueType, int N>
241struct FunctorHook
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700242{
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700243 typedef typename BaseHook::template index<N>::type hook_type;
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700244 typedef hook_type* hook_ptr;
245 typedef const hook_type* const_hook_ptr;
246
247 typedef ValueType value_type;
248 typedef value_type* pointer;
249 typedef const value_type* const_pointer;
250
251 //Required static functions
252 static hook_ptr to_hook_ptr (value_type &value)
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700253 { return &value.policy_hook_.template get<N> (); }
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700254
255 static const_hook_ptr to_hook_ptr(const value_type &value)
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700256 { return &value.policy_hook_.template get<N> (); }
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700257
258 static pointer to_value_ptr(hook_ptr n)
259 {
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700260 return
261 bi::get_parent_from_member<value_type>
262 (static_cast<BaseHook*> (bi::get_parent_from_member< wrap<hook_type> >(n, &wrap<hook_type>::value_)),
263 &value_type::policy_hook_);
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700264 }
265 static const_pointer to_value_ptr(const_hook_ptr n)
266 {
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700267 return
268 bi::get_parent_from_member<value_type>
269 (static_cast<const BaseHook*> (bi::get_parent_from_member< wrap<hook_type> >(n, &wrap<hook_type>::value_)),
270 &value_type::policy_hook_);
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700271 }
272};
273
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700274template<typename Policies> // e.g., mpl::vector1< lru_policy_traits >
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700275struct multi_policy_traits
276{
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700277 typedef Policies policy_traits;
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700278
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700279 struct getHook
280 {
281 template<class Item>
282 struct apply
283 {
284 typedef typename Item::policy_hook_type type;
285 };
286 };
287
288 typedef multi_type_container< typename mpl::transform1<policy_traits, getHook>::type > policy_hook_type;
289 typedef mpl::range_c<int, 0, mpl::size<policy_traits>::type::value> policies_range;
290
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700291 template<class Container>
292 struct container_hook
293 {
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700294 typedef void type;
295 // struct getFunctionHook
296 // {
297 // template<class Number>
298 // struct apply
299 // {
300 // // typedef void type;
301 // typedef bi::function_hook< FunctorHook <policy_hook_type,
302 // Container,
303 // Number::value> > type;
304 // };
305 // };
306
307 // struct type
308 // {
309 // typedef
310 // typename mpl::transform1<policies_range,
311 // getFunctionHook,
312 // mpl::back_inserter< mpl::vector0<> > >::type hooks;
313 // };
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700314 };
315
316 template<class Base,
317 class Container,
318 class Hook>
319 struct policy
320 {
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700321 // 1 hooks
322 // 2 actual policies
323
324 // struct getPolicy
325 // {
326 // template<class Item>
327 // struct apply
328 // {
329 // typedef typename Item::template policy<Base,
330 // Container,
331 // typename mpl::at_c<typename Hook::hooks,0>::type >::type type;
332 // };
333 // };
334
335 // typedef typename mpl::transform1<policy_traits, getPolicy>::type policies;
336
337 struct getPolicy
338 {
339 template<class Number>
340 struct apply
341 {
342 typedef
343 typename mpl::at_c<policy_traits, Number::value>::type::
344 template policy<Base,
345 Container,
346 bi::function_hook< FunctorHook <policy_hook_type,
347 Container,
348 Number::value> > >::type
349 type;
350 };
351 };
352
353 typedef
354 typename mpl::transform1<policies_range,
355 getPolicy,
356 mpl::back_inserter< mpl::vector0<> > >::type policies;
357
358
359 typedef multi_policy_container< Base, policies > policy_container;
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700360
361 class type : public policy_container
362 {
363 public:
364 typedef Container parent_trie;
365
366 type (Base &base)
367 : policy_container (base)
368 {
369 }
370
371 inline void
372 update (typename parent_trie::iterator item)
373 {
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700374 policy_container::update (item);
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700375 }
376
377 inline bool
378 insert (typename parent_trie::iterator item)
379 {
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700380 return policy_container::insert (item);
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700381 }
382
383 inline void
384 lookup (typename parent_trie::iterator item)
385 {
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700386 policy_container::lookup (item);
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700387 }
388
389 inline void
390 erase (typename parent_trie::iterator item)
391 {
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700392 policy_container::erase (item);
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700393 }
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700394 };
395 };
396};
397
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700398
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700399int
400main (int argc, char *argv[])
401{
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700402 CommandLine args;
403 args.Parse (argc, argv);
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700404
405 // typedef multi_policy_traits<lru_policy_traits> traits;
406 // // traits::policy<traits::hook>
407 // traits::policy<Bla1,Bla2, traits::container_hook<Bla2>::type> x;
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700408
409 typedef trie_with_policy<
410 ns3::CcnxNameComponents,
411 smart_pointer_payload_traits<Integer>,
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700412 multi_policy_traits<
413 mpl::vector2<lru_policy_traits,fifo_policy_traits>
414 // mpl::vector1<lru_policy_traits>
415 > > trie;
416 // // multi_policy_traits<lru_policy_traits, random_policy_traits> > trie;
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700417
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700418 trie x;
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700419 x.getPolicy ().get<0> ().set_max_size (3);
420 x.getPolicy ().get<1> ().set_max_size (100);
421 // // x.getPolicy ().get<1> ().set_max_size (3);
422 // // // x.getPolicy ().get1 ().set_max_size (10);
423 // // // x.getPolicy ().get2 ().set_max_size (3);
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700424
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700425 // // // x.getTrie ().PrintStat (std::cout);
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700426
427 ns3::CcnxNameComponents n1,n2,n3,n4;
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700428 // // // n1("a")("b")("c");
429 // // // n2("a")("b")("d");
430 // // // n3("a")("b")("f");
431 // // // n4("a")("b");
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700432
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700433 n1("a");
434 n2("b");
435 n3("c");
436 n4("d");
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700437
438 x.insert (n1, ns3::Create<Integer> (1));
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700439 x.insert (n2, ns3::Create<Integer> (2));
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700440 // // // x.longest_prefix_match (n1);
Alexander Afanasyev9e96e362012-07-02 23:04:39 -0700441 x.insert (n3, ns3::Create<Integer> (3));
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700442 x.insert (n4, ns3::Create<Integer> (4));
Alexander Afanasyev903062f2012-07-04 18:25:26 -0700443 x.insert (n4, ns3::Create<Integer> (4));
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700444
Alexander Afanasyev9a989702012-06-29 17:44:00 -0700445 std::cout << "digraph trie {\n";
446 std::cout << x.getTrie ();
447 std::cout << "}\n";
448
449 // BOOST_FOREACH (const trie::parent_trie &item, x.getPolicy ())
450 // {
451 // std::cout << *item.payload () << " " << std::endl;
452 // }
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700453
454 // ns3::CcnxNameComponents n4;
455 // n4("a")("c");
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700456
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700457 // // std::cout << *x->find (n4).get<0> ();
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700458
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700459 // x->prune ();
460 // // x->find (n5).get<0> ()->erase ();
461 // x->find (n1).get<0> ()->erase ();
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700462
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700463 // std::cout << "digraph trie {\n";
464 // std::cout << *x;
465 // std::cout << "}\n";
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700466
Alexander Afanasyev89fb5352012-06-12 22:43:16 -0700467 // x->PrintStat (std::cout);
468
469 // delete x;
Alexander Afanasyevfd0c41c2012-06-11 22:15:49 -0700470
471 return 0;
472}
473