Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / bench / bencher.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2
3 #ifndef BENCHERH
4 #define BENCHERH
5
6 #include <utility>
7 #include "distribution.h"
8 #include "stat_collector.h"
9 #include "backend.h"
10 #include <boost/scoped_ptr.hpp>
11 #include "common/Mutex.h"
12 #include "common/Cond.h"
13 #include "common/Thread.h"
14
15 struct OnWriteApplied;
16 struct OnWriteCommit;
17 struct OnReadComplete;
18 struct Cleanup;
19
20 class Bencher : public Thread {
21 public:
22   enum OpType {
23     WRITE,
24     READ
25   };
26
27 private:
28   boost::scoped_ptr<
29     Distribution<boost::tuple<std::string,uint64_t,uint64_t, OpType> > > op_dist;
30   ceph::shared_ptr<StatCollector> stat_collector;
31   boost::scoped_ptr<Backend> backend;
32   const uint64_t max_in_flight;
33   const uint64_t max_duration;
34   const uint64_t max_ops;
35
36   Mutex lock;
37   Cond open_ops_cond;
38   uint64_t open_ops;
39   void start_op();
40   void drain_ops();
41   void complete_op();
42 public:
43   Bencher(
44     Distribution<boost::tuple<std::string, uint64_t, uint64_t, OpType> > *op_gen,
45     ceph::shared_ptr<StatCollector> stat_collector,
46     Backend *backend,
47     uint64_t max_in_flight,
48     uint64_t max_duration,
49     uint64_t max_ops) :
50     op_dist(op_gen),
51     stat_collector(stat_collector),
52     backend(backend),
53     max_in_flight(max_in_flight),
54     max_duration(max_duration),
55     max_ops(max_ops),
56     lock("Bencher::lock"),
57     open_ops(0)
58   {}
59   Bencher(
60     Distribution<boost::tuple<std::string, uint64_t, uint64_t, OpType> > *op_gen,
61     StatCollector *stat_collector,
62     Backend *backend,
63     uint64_t max_in_flight,
64     uint64_t max_duration,
65     uint64_t max_ops) :
66     op_dist(op_gen),
67     stat_collector(stat_collector),
68     backend(backend),
69     max_in_flight(max_in_flight),
70     max_duration(max_duration),
71     max_ops(max_ops),
72     lock("Bencher::lock"),
73     open_ops(0)
74   {}
75   Bencher(
76     Distribution<std::string> *object_gen,
77     Distribution<uint64_t> *offset_gen,
78     Distribution<uint64_t> *length_gen,
79     Distribution<OpType> *op_type_gen,
80     StatCollector *stat_collector,
81     Backend *backend,
82     uint64_t max_in_flight,
83     uint64_t max_duration,
84     uint64_t max_ops) :
85     op_dist(
86       new FourTupleDist<std::string, uint64_t, uint64_t, OpType>(
87         object_gen, offset_gen, length_gen, op_type_gen)),
88     stat_collector(stat_collector),
89     backend(backend),
90     max_in_flight(max_in_flight),
91     max_duration(max_duration),
92     max_ops(max_ops),
93     lock("Bencher::lock"),
94     open_ops(0)
95   {}
96
97   void init(
98     const set<std::string> &objects,
99     uint64_t size,
100     std::ostream *out
101     );
102
103   void run_bench();
104   void *entry() override {
105     run_bench();
106     return 0;
107   }
108   friend struct OnWriteApplied;
109   friend struct OnWriteCommit;
110   friend struct OnReadComplete;
111   friend struct Cleanup;
112 };
113
114 class SequentialLoad :
115   public Distribution<
116   boost::tuple<string, uint64_t, uint64_t, Bencher::OpType> > {
117   set<string> objects;
118   uint64_t size;
119   uint64_t length;
120   set<string>::iterator object_pos;
121   uint64_t cur_pos;
122   boost::scoped_ptr<Distribution<Bencher::OpType> > op_dist;
123   SequentialLoad(const SequentialLoad &other);
124 public:
125   SequentialLoad(
126     const set<string> &_objects, uint64_t size,
127     uint64_t length,
128     Distribution<Bencher::OpType> *op_dist)
129     : objects(_objects), size(size), length(length),
130       object_pos(objects.begin()), cur_pos(0),
131       op_dist(op_dist) {}
132
133   boost::tuple<string, uint64_t, uint64_t, Bencher::OpType>
134   operator()() override {
135     boost::tuple<string, uint64_t, uint64_t, Bencher::OpType> ret =
136       boost::make_tuple(*object_pos, cur_pos, length, (*op_dist)());
137     cur_pos += length;
138     if (cur_pos >= size) {
139       cur_pos = 0;
140       ++object_pos;
141     }
142     if (object_pos == objects.end())
143       object_pos = objects.begin();
144     return ret;
145   }
146 };
147 #endif