install(TARGETS ceph_test_alloc_replay
DESTINATION bin)
endif()
+
+add_library(ObjectStoreImitator OBJECT ObjectStoreImitator.cc)
+
+add_executable(ceph_test_fragmentation_sim
+ Fragmentation_simulator.cc
+ $<TARGET_OBJECTS:ObjectStoreImitator>)
+add_ceph_unittest(ceph_test_fragmentation_sim)
+target_link_libraries(ceph_test_fragmentation_sim os global)
// vim: ts=8 sw=2 smarttab
/*
* Fragmentation Simulator
- * Author: Tri Dao, tri.dao@uwaterloo.ca
+ * Author: Tri Dao, daominhtri0503@gmail.com
*/
+#include "common/ceph_argparse.h"
+#include "common/common_init.h"
#include "common/hobject.h"
+#include "global/global_init.h"
#include "os/ObjectStore.h"
#include "test/objectstore/ObjectStoreImitator.h"
+#include <gtest/gtest.h>
+#include <iostream>
+
+#define dout_context g_ceph_context
class FragmentationSimulator {
public:
ObjectStoreImitator *os) = 0;
virtual std::string name() = 0;
- WorkloadGenerator();
- virtual ~WorkloadGenerator();
+ WorkloadGenerator() {}
+ virtual ~WorkloadGenerator() {}
};
- using WorkloadGeneratorRef = std::unique_ptr<WorkloadGenerator>;
+ using WorkloadGeneratorRef = std::shared_ptr<WorkloadGenerator>;
std::vector<WorkloadGeneratorRef> generators;
+ void add_generator(WorkloadGeneratorRef gen) {
+ std::cout << "Generator: " << gen->name() << " added\n";
+ generators.push_back(gen);
+ }
int begin_simulation_with_generators() {
for (auto &g : generators) {
return 0;
}
+ FragmentationSimulator() {
+ std::cout << "Initializing simulator\n" << std::endl;
+ os = new ObjectStoreImitator(g_ceph_context, "", 4096);
+ os->init_alloc("btree", 1024 * 1024 * 1024, 4096);
+ }
+ ~FragmentationSimulator() { delete os; }
+
private:
ObjectStoreImitator *os;
};
return 0;
}
};
+
+TEST(FragmentationSimulator, simple) {
+ auto sim = FragmentationSimulator();
+ sim.add_generator(std::make_shared<SimpleCWGenerator>());
+ sim.begin_simulation_with_generators();
+}
+
+int main(int argc, char **argv) {
+ auto args = argv_to_vec(argc, argv);
+ auto cct =
+ global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY,
+ CINIT_FLAG_NO_DEFAULT_CONFIG_FILE);
+ common_init_finish(g_ceph_context);
+
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Fragmentation Simulator
+ * Author: Tri Dao, daominhtri0503@gmail.com
+ */
#include "test/objectstore/ObjectStoreImitator.h"
#include "common/errno.h"
}
}
+int ObjectStoreImitator::read(CollectionHandle &c_, const ghobject_t &oid,
+ uint64_t offset, size_t length, bufferlist &bl,
+ uint32_t op_flags) {
+
+ Collection *c = static_cast<Collection *>(c_.get());
+ if (!c->exists)
+ return -ENOENT;
+
+ bl.clear();
+ int r;
+ {
+ std::shared_lock l(c->lock);
+ ObjectRef o = c->get_obj(oid, false);
+ if (!o || !o->exists) {
+ r = -ENOENT;
+ goto out;
+ }
+
+ if (offset == length && offset == 0)
+ length = o->size;
+
+ r = _do_read(c, o, offset, length, bl, op_flags);
+ }
+
+out:
+ return r;
+}
+
// ------- Helpers -------
void ObjectStoreImitator::_assign_nid(ObjectRef &o) {
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Fragmentation Simulator
+ * Author: Tri Dao, daominhtri0503@gmail.com
+ */
#pragma once
+#include "include/common_fwd.h"
#include "os/ObjectStore.h"
#include "os/bluestore/Allocator.h"
#include "os/bluestore/bluestore_types.h"
+#include <boost/smart_ptr/intrusive_ptr.hpp>
/**
* ObjectStoreImitator will simulate how BlueStore does IO (as of the time
class Collection;
typedef boost::intrusive_ptr<Collection> CollectionRef;
- struct Object {
+ struct Object : public RefCountedObject {
Collection *c;
ghobject_t oid;
bool exists;
}
auto o = objects.find(oid);
- if (o->second)
+ if (o != objects.end())
return o->second;
- auto on = new Object(this, oid);
- return objects[oid] = on;
+ if (!create)
+ return nullptr;
+
+ return objects[oid] = new Object(this, oid);
}
bool flush_commit(Context *c) override { return false; }
int _clone(CollectionRef &c, ObjectRef &oldo, ObjectRef &newo);
int _clone_range(CollectionRef &c, ObjectRef &oldo, ObjectRef &newo,
uint64_t srcoff, uint64_t length, uint64_t dstoff);
+ int read(CollectionHandle &c, const ghobject_t &oid, uint64_t offset,
+ size_t len, ceph::buffer::list &bl, uint32_t op_flags = 0) override;
// Helpers
void set_collection_commit_queue(const coll_t &cid,
ContextQueue *commit_queue) override;
bool exists(CollectionHandle &c, const ghobject_t &old) override;
+ int set_collection_opts(CollectionHandle &c,
+ const pool_opts_t &opts) override;
int list_collections(std::vector<coll_t> &ls) override;
bool collection_exists(const coll_t &c) override;
bool *per_pool_omap) override {
return 0;
}
- int set_collection_opts(CollectionHandle &c,
- const pool_opts_t &opts) override;
int stat(CollectionHandle &c, const ghobject_t &oid, struct stat *st,
bool allow_eio = false) override {
return 0;
}
void set_fsid(uuid_d u) override {}
uuid_d get_fsid() override { return {}; }
- uint64_t estimate_objects_overhead(uint64_t num_objects) override;
+ uint64_t estimate_objects_overhead(uint64_t num_objects) override {
+ return num_objects * 300;
+ }
objectstore_perf_stat_t get_cur_stats() override { return {}; }
const PerfCounters *get_perf_counters() const override { return nullptr; };
};