Making policy container more flexible
diff --git a/examples/trie.cc b/examples/trie.cc
index 3e77a4f..2c35ac4 100644
--- a/examples/trie.cc
+++ b/examples/trie.cc
@@ -21,6 +21,10 @@
#include "ns3/core-module.h"
#include "ns3/ndnSIM-module.h"
#include "../utils/trie-with-policy.h"
+#include "../utils/lru-policy.h"
+#include "../utils/random-policy.h"
+#include "../utils/fifo-policy.h"
+#include <boost/intrusive/parent_from_member.hpp>
using namespace ns3;
@@ -43,38 +47,269 @@
return os;
}
+template<class Policy1, class Policy2>
+struct multi_policy_hook
+{
+ Policy1 hook1_;
+ Policy2 hook2_;
+};
+
+template<class Base, class Container1, class Container2>
+struct multi_policy_container
+{
+ typedef Container1 nth_container1;
+ typedef Container2 nth_container2;
+
+ multi_policy_container (Base &base)
+ : container1_ (base)
+ , container2_ (base)
+ {
+ }
+
+ nth_container1 container1_;
+ nth_container2 container2_;
+};
+
+template<class BaseHook, class ValueType, class HookType>
+struct Functor1
+{
+ typedef HookType hook_type;
+ typedef hook_type* hook_ptr;
+ typedef const hook_type* const_hook_ptr;
+
+ typedef ValueType value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+
+ //Required static functions
+ static hook_ptr to_hook_ptr (value_type &value)
+ { return &value.policy_hook_.hook1_; }
+
+ static const_hook_ptr to_hook_ptr(const value_type &value)
+ { return &value.policy_hook_.hook1_; }
+
+ static pointer to_value_ptr(hook_ptr n)
+ {
+ return bi::get_parent_from_member<value_type>
+ (bi::get_parent_from_member<BaseHook >
+ (n, &BaseHook::hook1_)
+ , &value_type::policy_hook_
+ );
+ }
+ static const_pointer to_value_ptr(const_hook_ptr n)
+ {
+ return bi::get_parent_from_member<value_type>
+ (bi::get_parent_from_member<BaseHook>
+ (n, &BaseHook::hook1_)
+ , &value_type::policy_hook_
+ );
+ }
+};
+
+template<class BaseHook, class ValueType, class HookType>
+struct Functor2
+{
+ typedef HookType hook_type;
+ typedef hook_type* hook_ptr;
+ typedef const hook_type* const_hook_ptr;
+
+ typedef ValueType value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+
+ //Required static functions
+ static hook_ptr to_hook_ptr (value_type &value)
+ { return &value.policy_hook_.hook2_; }
+
+ static const_hook_ptr to_hook_ptr(const value_type &value)
+ { return &value.policy_hook_.hook2_; }
+
+ static pointer to_value_ptr(hook_ptr n)
+ {
+ return bi::get_parent_from_member<value_type>
+ (bi::get_parent_from_member<BaseHook >
+ (n, &BaseHook::hook2_)
+ , &value_type::policy_hook_
+ );
+ }
+ static const_pointer to_value_ptr(const_hook_ptr n)
+ {
+ return bi::get_parent_from_member<value_type>
+ (bi::get_parent_from_member<BaseHook>
+ (n, &BaseHook::hook2_)
+ , &value_type::policy_hook_
+ );
+ }
+};
+
+
+struct multi_policy_traits
+{
+ typedef multi_policy_hook< lru_policy_traits::policy_hook_type
+ ,
+ random_policy_traits::policy_hook_type
+ > policy_hook_type;
+
+ template<class Container>
+ struct container_hook
+ {
+ struct type
+ {
+ typedef bi::function_hook< Functor1 <policy_hook_type,
+ Container,
+ typename lru_policy_traits::policy_hook_type> > hook1;
+
+ struct hook2
+ {
+ typedef bi::function_hook< Functor2 <policy_hook_type,
+ Container,
+ typename random_policy_traits::policy_hook_type> > hook_type;
+
+ static uint32_t& get_order (typename Container::iterator item)
+ {
+ return item->policy_hook_.hook2_.randomOrder;
+ }
+
+ static const uint32_t& get_order (typename Container::const_iterator item)
+ {
+ return item->policy_hook_.hook2_.randomOrder;
+ }
+ };
+
+ };
+ };
+
+ template<class Base,
+ class Container,
+ class Hook>
+ struct policy
+ {
+ typedef multi_policy_container <
+ Base,
+ typename lru_policy_traits::policy< Base, Container, typename Hook::hook1 >::type
+ ,
+ typename random_policy_traits::policy< Base, Container, typename Hook::hook2 >::type
+ > policy_container;
+
+ class type : public policy_container
+ {
+ public:
+ typedef Container parent_trie;
+
+ type (Base &base)
+ : policy_container (base)
+ {
+ }
+
+ inline void
+ update (typename parent_trie::iterator item)
+ {
+ this->container1_.update (item);
+ this->container2_.update (item);
+ }
+
+ inline bool
+ insert (typename parent_trie::iterator item)
+ {
+ bool ok;
+ ok = this->container1_.insert (item);
+ if (!ok)
+ {
+ // nothing to undo. just return false
+ return false;
+ }
+
+ ok = this->container2_.insert (item);
+ if (!ok)
+ {
+ // undo and return false
+ this->container1_.erase (item);
+ return false;
+ }
+ return true;
+ }
+
+ inline void
+ lookup (typename parent_trie::iterator item)
+ {
+ this->container1_.lookup (item);
+ this->container2_.lookup (item);
+ }
+
+ inline void
+ erase (typename parent_trie::iterator item)
+ {
+ this->container1_.erase (item);
+ this->container2_.erase (item);
+ }
+
+ inline typename policy_container::nth_container1 &
+ get1 ()
+ {
+ return this->container1_;
+ }
+
+ inline typename policy_container::nth_container2 &
+ get2 ()
+ {
+ return this->container2_;
+ }
+ // template<>
+ // inline typename policy_container::container1_type &
+ // get<1> ()
+ // {
+ // return this->container1_;
+ // }
+ // inline void
+ // set_max_size (size_t max_size)
+ // {
+ // this->container1_.set_max_size (max_size);
+ // this->container2_.set_max_size (max_size);
+ // }
+
+ // inline size_t
+ // get_max_size () const
+ // {
+ // return this->container1_.get_max_size ();
+ // }
+ };
+ };
+};
+
int
main (int argc, char *argv[])
{
- typedef trie_with_policy<ns3::CcnxNameComponents,
- Integer,
- smart_pointer_payload_traits<Integer>,
- lru_policy_traits<CcnxNameComponents,
- Integer,
- smart_pointer_payload_traits<Integer> >
- > trie;
+ CommandLine args;
+ args.Parse (argc, argv);
+
+ typedef trie_with_policy<
+ ns3::CcnxNameComponents,
+ smart_pointer_payload_traits<Integer>,
+ multi_policy_traits > trie;
+
trie x;
- x.getPolicy ().set_max_size (100);
+ x.getPolicy ().get1 ().set_max_size (10);
+ x.getPolicy ().get2 ().set_max_size (3);
// x.getTrie ().PrintStat (std::cout);
ns3::CcnxNameComponents n1,n2,n3,n4;
- n1("a")("b")("c");
- n2("a")("b")("d");
- n3("a")("b")("f");
- n4("a")("b");
+ // n1("a")("b")("c");
+ // n2("a")("b")("d");
+ // n3("a")("b")("f");
+ // n4("a")("b");
- ns3::Ptr<Integer> i = ns3::Create<Integer> (1);
- x.insert (n4, ns3::Create<Integer> (4));
-
- x.insert (n3, ns3::Create<Integer> (3));
-
- std::pair< trie::iterator, bool > item =
- x.insert (n2, ns3::Create<Integer> (2));
- // x.erase (item.first);
+ n1("a");
+ n2("b");
+ n3("c");
+ n4("d");
x.insert (n1, ns3::Create<Integer> (1));
+ x.insert (n2, ns3::Create<Integer> (2));
+ x.longest_prefix_match (n1);
+ x.insert (n3, ns3::Create<Integer> (3));
x.insert (n4, ns3::Create<Integer> (4));
+ // x.insert (n4, ns3::Create<Integer> (4));
std::cout << "digraph trie {\n";
std::cout << x.getTrie ();