]>
git.proxmox.com Git - ceph.git/blob - ceph/src/test/bench/distribution.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
3 #ifndef DISTIRITBIONHPP
4 #define DISTIRITBIONHPP
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>
16 typedef boost::mt11213b rngen_t
;
21 virtual T
operator()() = 0;
22 virtual ~Distribution() {}
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
;
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
)());
44 class RandomDist
: public Distribution
<T
> {
46 std::map
<uint64_t, T
> contents
;
48 RandomDist(const rngen_t
&rng
, std::set
<T
> &initial
) : rng(rng
) {
50 for (typename
std::set
<T
>::iterator i
= initial
.begin();
53 contents
.insert(std::make_pair(count
, *i
));
56 T
operator()() override
{
57 assert(contents
.size());
58 boost::uniform_int
<> value(0, contents
.size() - 1);
59 return contents
.find(value(rng
))->second
;
64 class WeightedDist
: public Distribution
<T
> {
67 std::map
<double, T
> contents
;
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
=
76 contents
.insert(std::make_pair(total
, i
->second
));
79 T
operator()() override
{
80 return contents
.lower_bound(
81 boost::uniform_real
<>(0, total
)(rng
))->second
;
85 template <typename T
, typename U
>
86 class SequentialDist
: public Distribution
<T
> {
88 std::vector
<T
> contents
;
89 typename
std::vector
<T
>::iterator cur
;
91 SequentialDist(rngen_t rng
, U
&initial
) : rng(rng
) {
92 contents
.insert(initial
.begin(), initial
.end());
93 cur
= contents
.begin();
95 virtual T
operator()() {
96 assert(contents
.size());
97 if (cur
== contents
.end())
98 cur
= contents
.begin();
103 class UniformRandom
: public Distribution
<uint64_t> {
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
);
115 class Align
: public Distribution
<uint64_t> {
116 boost::scoped_ptr
<Distribution
<uint64_t> > dist
;
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
);
127 class Uniform
: public Distribution
<uint64_t> {
130 explicit Uniform(uint64_t val
) : val(val
) {}
131 uint64_t operator()() override
{