1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
20 #include "os/filestore/FileStore.h"
21 #include "include/Context.h"
22 #include "common/ceph_argparse.h"
23 #include "global/global_init.h"
24 #include "common/Mutex.h"
25 #include "common/Cond.h"
26 #include <boost/scoped_ptr.hpp>
27 #include <boost/random/mersenne_twister.hpp>
28 #include <boost/random/uniform_int.hpp>
29 #include <boost/random/binomial_distribution.hpp>
30 #include <gtest/gtest.h>
32 #include "include/unordered_map.h"
34 void usage(const string
&name
) {
35 std::cerr
<< "Usage: " << name
<< " [xattr|omap] store_path store_journal"
39 const int THREADS
= 5;
42 typename
T::iterator
rand_choose(T
&cont
) {
43 if (cont
.size() == 0) {
46 int index
= rand() % cont
.size();
47 typename
T::iterator retval
= cont
.begin();
49 for (; index
> 0; --index
) ++retval
;
53 class OnApplied
: public Context
{
58 ObjectStore::Transaction
*t
;
59 OnApplied(Mutex
*lock
,
62 ObjectStore::Transaction
*t
)
63 : lock(lock
), cond(cond
),
64 in_progress(in_progress
), t(t
) {
65 Mutex::Locker
l(*lock
);
69 void finish(int r
) override
{
70 Mutex::Locker
l(*lock
);
82 double print_time(uint64_t ms
) {
83 return ((double)ms
)/1000;
86 uint64_t do_run(ObjectStore
*store
, int attrsize
, int numattrs
,
88 int transsize
, int ops
,
93 ObjectStore::Sequencer
osr(__func__
);
94 ObjectStore::Transaction t
;
95 map
<coll_t
, pair
<set
<string
>, ObjectStore::Sequencer
*> > collections
;
96 for (int i
= 0; i
< 3*THREADS
; ++i
) {
97 coll_t
coll(spg_t(pg_t(0, i
+ 1000*run
), shard_id_t::NO_SHARD
));
98 t
.create_collection(coll
, 0);
100 for (int i
= 0; i
< transsize
; ++i
) {
101 stringstream obj_str
;
104 ghobject_t(hobject_t(sobject_t(obj_str
.str(), CEPH_NOSNAP
))));
105 objects
.insert(obj_str
.str());
107 collections
[coll
] = make_pair(objects
, new ObjectStore::Sequencer(coll
.to_str()));
109 store
->queue_transaction(&osr
, std::move(t
));
112 for (int i
= 0; i
< attrsize
; ++i
) {
116 uint64_t start
= get_time();
117 for (int i
= 0; i
< ops
; ++i
) {
119 Mutex::Locker
l(lock
);
120 while (in_flight
>= THREADS
)
123 ObjectStore::Transaction
*t
= new ObjectStore::Transaction
;
124 map
<coll_t
, pair
<set
<string
>, ObjectStore::Sequencer
*> >::iterator iter
=
125 rand_choose(collections
);
126 for (set
<string
>::iterator obj
= iter
->second
.first
.begin();
127 obj
!= iter
->second
.first
.end();
129 for (int j
= 0; j
< numattrs
; ++j
) {
131 ss
<< i
<< ", " << j
<< ", " << *obj
;
132 t
->setattr(iter
->first
,
133 ghobject_t(hobject_t(sobject_t(*obj
, CEPH_NOSNAP
))),
138 store
->queue_transaction(iter
->second
.second
, std::move(*t
),
139 new OnApplied(&lock
, &cond
, &in_flight
,
144 Mutex::Locker
l(lock
);
148 return get_time() - start
;
151 int main(int argc
, char **argv
) {
152 vector
<const char*> args
;
153 argv_to_vec(argc
, (const char **)argv
, args
);
155 cerr
<< argv
[0] << ": -h or --help for usage" << std::endl
;
158 if (ceph_argparse_need_usage(args
)) {
163 auto cct
= global_init(0, args
, CEPH_ENTITY_TYPE_CLIENT
,
164 CODE_ENVIRONMENT_UTILITY
,
165 CINIT_FLAG_NO_DEFAULT_CONFIG_FILE
);
166 common_init_finish(g_ceph_context
);
168 std::cerr
<< "args: " << args
<< std::endl
;
169 if (args
.size() < 3) {
174 string
store_path(args
[1]);
175 string
store_dev(args
[2]);
177 boost::scoped_ptr
<ObjectStore
> store(new FileStore(cct
.get(), store_path
,
180 std::cerr
<< "mkfs starting" << std::endl
;
181 ceph_assert(!store
->mkfs());
182 ceph_assert(!store
->mount());
183 std::cerr
<< "mounted" << std::endl
;
185 std::cerr
<< "attrsize\tnumattrs\ttranssize\tops\ttime" << std::endl
;
188 for (int i
= 6; i
< total_size
; ++i
) {
189 for (int j
= (total_size
- i
); j
>= 0; --j
) {
190 std::cerr
<< "starting run " << runs
<< std::endl
;
192 uint64_t time
= do_run(store
.get(), (1 << i
), (1 << j
), runs
,
195 std::cout
<< (1 << i
) << "\t"
199 << print_time(time
) << std::endl
;