1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
|
/*
* Generate latency statistics for a configurable number of object map write
* operations of configurable size.
*
* Created on: May 21, 2012
* Author: Eleanor Cawthon
*
* This is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software
* Foundation. See file COPYING.
*/
#ifndef OMAP_BENCH_HPP_
#define OMAP_BENCH_HPP_
#include "common/ceph_mutex.h"
#include "common/Cond.h"
#include "include/rados/librados.hpp"
#include <string>
#include <map>
#include <cfloat>
using ceph::bufferlist;
struct o_bench_data {
double avg_latency;
double min_latency;
double max_latency;
double total_latency;
int started_ops;
int completed_ops;
std::map<int,int> freq_map;
std::pair<int,int> mode;
o_bench_data()
: avg_latency(0.0), min_latency(DBL_MAX), max_latency(0.0),
total_latency(0.0),
started_ops(0), completed_ops(0)
{}
};
class OmapBench;
typedef int (*omap_generator_t)(const int omap_entries, const int key_size,
const int value_size,
std::map<std::string,bufferlist> *out_omap);
typedef int (OmapBench::*test_t)(omap_generator_t omap_gen);
class Writer{
protected:
std::string oid;
utime_t begin_time;
utime_t end_time;
std::map<std::string,bufferlist> omap;
OmapBench *ob;
friend class OmapBench;
public:
Writer(OmapBench *omap_bench);
virtual ~Writer(){};
virtual void start_time();
virtual void stop_time();
virtual double get_time();
virtual std::string get_oid();
virtual std::map<std::string,bufferlist> & get_omap();
};
class AioWriter : public Writer{
protected:
librados::AioCompletion * aioc;
friend class OmapBench;
public:
AioWriter(OmapBench *omap_bench);
~AioWriter() override;
virtual librados::AioCompletion * get_aioc();
virtual void set_aioc(librados::callback_t complete);
};
class OmapBench{
protected:
librados::IoCtx io_ctx;
librados::Rados rados;
struct o_bench_data data;
test_t test;
omap_generator_t omap_generator;
//aio things
ceph::condition_variable thread_is_free;
ceph::mutex thread_is_free_lock =
ceph::make_mutex("OmapBench::thread_is_free_lock");
ceph::mutex data_lock =
ceph::make_mutex("OmapBench::data_lock");
int busythreads_count;
librados::callback_t comp;
std::string pool_name;
std::string rados_id;
std::string prefix;
int threads;
int objects;
int entries_per_omap;
int key_size;
int value_size;
double increment;
friend class Writer;
friend class AioWriter;
public:
OmapBench()
: test(&OmapBench::test_write_objects_in_parallel),
omap_generator(generate_uniform_omap),
busythreads_count(0),
comp(aio_is_complete),
pool_name("rbd"),
rados_id("admin"),
prefix(rados_id+".obj."),
threads(3), objects(100), entries_per_omap(10), key_size(10),
value_size(100), increment(10)
{}
/**
* Parses command line args, initializes rados and ioctx
*/
int setup(int argc, const char** argv);
/**
* Callback for when an AioCompletion (called from an AioWriter)
* is complete. deletes the AioWriter that called it,
* Updates data, updates busythreads, and signals thread_is_free.
*
* @param c provided by aio_write - not used
* @param arg the AioWriter that contains this AioCompletion
*/
static void aio_is_complete(rados_completion_t c, void *arg);
/**
* Generates a random string len characters long
*/
static std::string random_string(int len);
/*
* runs the test specified by test using the omap generator specified by
* omap_generator
*
* @return error code
*/
int run();
/*
* Prints all keys and values for all omap entries for all objects
*/
int print_written_omap();
/*
* Displays relevant constants and the histogram generated through a test
*/
void print_results();
/**
* Writes an object with the specified AioWriter.
*
* @param aiow the AioWriter to write with
* @param omap the omap to write
* @post: an asynchronous omap_set is launched
*/
int write_omap_asynchronously(AioWriter *aiow,
const std::map<std::string,bufferlist> &map);
/**
* Generates an omap with omap_entries entries, each with keys key_size
* characters long and with string values value_size characters long.
*
* @param out_map pointer to the map to be created
* @return error code
*/
static int generate_uniform_omap(const int omap_entries, const int key_size,
const int value_size, std::map<std::string,bufferlist> * out_omap);
/**
* The same as generate_uniform_omap except that string lengths are picked
* randomly between 1 and the int arguments
*/
static int generate_non_uniform_omap(const int omap_entries,
const int key_size,
const int value_size, std::map<std::string,bufferlist> * out_omap);
static int generate_small_non_random_omap(const int omap_entries,
const int key_size, const int value_size,
std::map<std::string,bufferlist> * out_omap);
/*
* Uses aio_write to write omaps generated by omap_gen to OBJECTS objects
* using THREADS AioWriters at a time.
*
* @param omap_gen the method used to generate the omaps.
*/
int test_write_objects_in_parallel(omap_generator_t omap_gen);
};
#endif /* OMAP_BENCH_HPP_ */
|