blob: d896e89069b09860ced023995431d253ef4d1bd8 [file] [log] [blame]
Jeff Thompsonfa306642013-06-17 15:06:57 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2013, Regents of the University of California
4 * Alexander Afanasyev
5 *
6 * BSD license, See the LICENSE file for more information
7 *
8 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
9 */
10
11#ifndef RANDOM_POLICY_H_
12#define RANDOM_POLICY_H_
13
14#include "ns3/random-variable.h"
15
16#include <boost/intrusive/options.hpp>
17#include <boost/intrusive/set.hpp>
18
19namespace ndn {
20namespace trie {
21
22/**
23 * @brief Traits for random replacement policy
24 */
25struct random_policy_traits
26{
27 /// @brief Name that can be used to identify the policy (e.g., for logging)
28 static std::string GetName () { return "Random"; }
29
30 struct policy_hook_type : public boost::intrusive::set_member_hook<> { uint32_t randomOrder; };
31
32 template<class Container>
33 struct container_hook
34 {
35 typedef boost::intrusive::member_hook< Container,
36 policy_hook_type,
37 &Container::policy_hook_ > type;
38 };
39
40 template<class Base,
41 class Container,
42 class Hook>
43 struct policy
44 {
45 static uint32_t& get_order (typename Container::iterator item)
46 {
47 return static_cast<typename policy_container::value_traits::hook_type*>
48 (policy_container::value_traits::to_node_ptr(*item))->randomOrder;
49 }
50
51 static const uint32_t& get_order (typename Container::const_iterator item)
52 {
53 return static_cast<const typename policy_container::value_traits::hook_type*>
54 (policy_container::value_traits::to_node_ptr(*item))->randomOrder;
55 }
56
57 template<class Key>
58 struct MemberHookLess
59 {
60 bool operator () (const Key &a, const Key &b) const
61 {
62 return get_order (&a) < get_order (&b);
63 }
64 };
65
66 typedef boost::intrusive::multiset< Container,
67 boost::intrusive::compare< MemberHookLess< Container > >,
68 Hook > policy_container;
69
70 // could be just typedef
71 class type : public policy_container
72 {
73 public:
74 typedef policy policy_base; // to get access to get_order methods from outside
75 typedef Container parent_trie;
76
77 type (Base &base)
78 : base_ (base)
79 , u_rand (0, std::numeric_limits<uint32_t>::max ())
80 , max_size_ (100)
81 {
82 }
83
84 inline void
85 update (typename parent_trie::iterator item)
86 {
87 // do nothing. it's random policy
88 }
89
90 inline bool
91 insert (typename parent_trie::iterator item)
92 {
93 get_order (item) = u_rand.GetValue ();
94
95 if (max_size_ != 0 && policy_container::size () >= max_size_)
96 {
97 if (MemberHookLess<Container>() (*item, *policy_container::begin ()))
98 {
99 // std::cout << "Cannot add. Signaling fail\n";
100 // just return false. Indicating that insert "failed"
101 return false;
102 }
103 else
104 {
105 // removing some random element
106 base_.erase (&(*policy_container::begin ()));
107 }
108 }
109
110 policy_container::insert (*item);
111 return true;
112 }
113
114 inline void
115 lookup (typename parent_trie::iterator item)
116 {
117 // do nothing. it's random policy
118 }
119
120 inline void
121 erase (typename parent_trie::iterator item)
122 {
123 policy_container::erase (policy_container::s_iterator_to (*item));
124 }
125
126 inline void
127 clear ()
128 {
129 policy_container::clear ();
130 }
131
132 inline void
133 set_max_size (size_t max_size)
134 {
135 max_size_ = max_size;
136 }
137
138 inline size_t
139 get_max_size () const
140 {
141 return max_size_;
142 }
143
144 private:
145 type () : base_(*((Base*)0)) { };
146
147 private:
148 Base &base_;
149 ns3::UniformVariable u_rand;
150 size_t max_size_;
151 };
152 };
153};
154
155} // trie
156} // ndn
157
158#endif // RANDOM_POLICY_H