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->apply_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 auto cct = global_init(0, args, CEPH_ENTITY_TYPE_CLIENT,
156 CODE_ENVIRONMENT_UTILITY, 0);
157 common_init_finish(g_ceph_context);
159 std::cerr << "args: " << args << std::endl;
160 if (args.size() < 3) {
165 string store_path(args[1]);
166 string store_dev(args[2]);
168 boost::scoped_ptr<ObjectStore> store(new FileStore(cct.get(), store_path,
171 std::cerr << "mkfs starting" << std::endl;
172 assert(!store->mkfs());
173 assert(!store->mount());
174 std::cerr << "mounted" << std::endl;
176 std::cerr << "attrsize\tnumattrs\ttranssize\tops\ttime" << std::endl;
179 for (int i = 6; i < total_size; ++i) {
180 for (int j = (total_size - i); j >= 0; --j) {
181 std::cerr << "starting run " << runs << std::endl;
183 uint64_t time = do_run(store.get(), (1 << i), (1 << j), runs,
186 std::cout << (1 << i) << "\t"
190 << print_time(time) << std::endl;