Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / bench / distribution.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2
3 #ifndef DISTIRITBIONHPP
4 #define DISTIRITBIONHPP
5
6 #include <map>
7 #include <set>
8 #include <utility>
9 #include <vector>
10 #include <boost/random/mersenne_twister.hpp>
11 #include <boost/random/uniform_int.hpp>
12 #include <boost/random/uniform_real.hpp>
13 #include <boost/scoped_ptr.hpp>
14 #include <boost/tuple/tuple.hpp>
15
16 typedef boost::mt11213b rngen_t;
17
18 template <typename T>
19 class Distribution {
20 public:
21   virtual T operator()() = 0;
22   virtual ~Distribution() {}
23 };
24
25 template <typename T, typename U, typename V, typename W>
26 class FourTupleDist : public Distribution<boost::tuple<T, U, V, W> > {
27   boost::scoped_ptr<Distribution<T> > t;
28   boost::scoped_ptr<Distribution<U> > u;
29   boost::scoped_ptr<Distribution<V> > v;
30   boost::scoped_ptr<Distribution<W> > w;
31 public:
32   FourTupleDist(
33     Distribution<T> *t,
34     Distribution<U> *u,
35     Distribution<V> *v,
36     Distribution<W> *w)
37     : t(t), u(u), v(v), w(w) {}
38   boost::tuple<T, U, V, W> operator()() override {
39     return boost::make_tuple((*t)(), (*u)(), (*v)(), (*w)());
40   }
41 };
42
43 template <typename T>
44 class RandomDist : public Distribution<T> {
45   rngen_t rng;
46   std::map<uint64_t, T> contents;
47 public:
48   RandomDist(const rngen_t &rng, std::set<T> &initial) : rng(rng) {
49     uint64_t count = 0;
50     for (typename std::set<T>::iterator i = initial.begin();
51          i != initial.end();
52          ++i, ++count) {
53       contents.insert(std::make_pair(count, *i));
54     }
55   }
56   T operator()() override {
57     assert(contents.size());
58     boost::uniform_int<> value(0, contents.size() - 1);
59     return contents.find(value(rng))->second;
60   }
61 };
62
63 template <typename T>
64 class WeightedDist : public Distribution<T> {
65   rngen_t rng;
66   double total;
67   std::map<double, T> contents;
68 public:
69   WeightedDist(const rngen_t &rng, const std::set<std::pair<double, T> > &initial)
70     : rng(rng), total(0) {
71     for (typename std::set<std::pair<double, T> >::const_iterator i =
72            initial.begin();
73          i != initial.end();
74          ++i) {
75       total += i->first;
76       contents.insert(std::make_pair(total, i->second));
77     }
78   }
79   T operator()() override {
80     return contents.lower_bound(
81       boost::uniform_real<>(0, total)(rng))->second;
82   }
83 };
84
85 template <typename T, typename U>
86 class SequentialDist : public Distribution<T> {
87   rngen_t rng;
88   std::vector<T> contents;
89   typename std::vector<T>::iterator cur;
90 public:
91   SequentialDist(rngen_t rng, U &initial) : rng(rng) {
92     contents.insert(initial.begin(), initial.end());
93     cur = contents.begin();
94   }
95   virtual T operator()() {
96     assert(contents.size());
97     if (cur == contents.end())
98       cur = contents.begin();
99     return *(cur++);
100   }
101 };
102
103 class UniformRandom : public Distribution<uint64_t> {
104   rngen_t rng;
105   uint64_t min;
106   uint64_t max;
107 public:
108   UniformRandom(const rngen_t &rng, uint64_t min, uint64_t max) :
109     rng(rng), min(min), max(max) {}
110   uint64_t operator()() override {
111     return boost::uniform_int<uint64_t>(min, max)(rng);
112   }
113 };
114
115 class Align : public Distribution<uint64_t> {
116   boost::scoped_ptr<Distribution<uint64_t> > dist;
117   uint64_t align;
118 public:
119   Align(Distribution<uint64_t> *dist, uint64_t align) :
120     dist(dist), align(align) {}
121   uint64_t operator()() override {
122     uint64_t ret = (*dist)();
123     return ret - (ret % align);
124   }
125 };
126
127 class Uniform : public Distribution<uint64_t> {
128   uint64_t val;
129 public:
130   explicit Uniform(uint64_t val) : val(val) {}
131   uint64_t operator()() override {
132     return val;
133   }
134 };
135
136 #endif