]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/objectstore/TestObjectStoreState.cc
import quincy beta 17.1.0
[ceph.git] / ceph / src / test / objectstore / TestObjectStoreState.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3/*
4* Ceph - scalable distributed file system
5*
6* Copyright (C) 2012 New Dream Network
7*
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.
12*/
13#include <stdio.h>
14#include <string.h>
15#include <iostream>
16#include <time.h>
17#include <stdlib.h>
18#include <signal.h>
19#include "os/ObjectStore.h"
20#include "common/ceph_argparse.h"
21#include "global/global_init.h"
22#include "common/debug.h"
23#include <boost/scoped_ptr.hpp>
24#include <boost/lexical_cast.hpp>
25#include "TestObjectStoreState.h"
11fdf7f2 26#include "include/ceph_assert.h"
7c673cae
FG
27
28#define dout_context g_ceph_context
29#define dout_subsys ceph_subsys_filestore
30#undef dout_prefix
31#define dout_prefix *_dout << "ceph_test_objectstore_state "
32
20effc67
TL
33using namespace std;
34
7c673cae
FG
35void TestObjectStoreState::init(int colls, int objs)
36{
37 dout(5) << "init " << colls << " colls " << objs << " objs" << dendl;
38
7c673cae 39 ObjectStore::Transaction t;
11fdf7f2 40 auto meta_ch = m_store->create_new_collection(coll_t::meta());
7c673cae 41 t.create_collection(coll_t::meta(), 0);
11fdf7f2 42 m_store->queue_transaction(meta_ch, std::move(t));
7c673cae
FG
43
44 wait_for_ready();
45
46 int baseid = 0;
47 for (int i = 0; i < colls; i++) {
11fdf7f2
TL
48 spg_t pgid(pg_t(i, 1), shard_id_t::NO_SHARD);
49 coll_t cid(pgid);
50 auto ch = m_store->create_new_collection(cid);
51 coll_entry_t *entry = coll_create(pgid, ch);
52 dout(5) << "init create collection " << entry->m_cid
7c673cae
FG
53 << " meta " << entry->m_meta_obj << dendl;
54
55 ObjectStore::Transaction *t = new ObjectStore::Transaction;
11fdf7f2 56 t->create_collection(entry->m_cid, 32);
7c673cae
FG
57 bufferlist hint;
58 uint32_t pg_num = colls;
59 uint64_t num_objs = uint64_t(objs / colls);
11fdf7f2
TL
60 encode(pg_num, hint);
61 encode(num_objs, hint);
62 t->collection_hint(entry->m_cid, ObjectStore::Transaction::COLL_HINT_EXPECTED_NUM_OBJECTS, hint);
7c673cae 63 dout(5) << "give collection hint, number of objects per collection: " << num_objs << dendl;
11fdf7f2 64 t->touch(cid, entry->m_meta_obj);
7c673cae
FG
65
66 for (int i = 0; i < objs; i++) {
67 hobject_t *obj = entry->touch_obj(i + baseid);
11fdf7f2 68 t->touch(entry->m_cid, ghobject_t(*obj));
7c673cae
FG
69 ceph_assert(i + baseid == m_num_objects);
70 m_num_objects++;
71 }
72 baseid += objs;
73
11fdf7f2
TL
74 t->register_on_commit(new C_OnFinished(this));
75 m_store->queue_transaction(entry->m_ch, std::move(*t), nullptr);
76
7c673cae
FG
77 delete t;
78 inc_in_flight();
79
11fdf7f2
TL
80 m_collections.insert(make_pair(cid, entry));
81 rebuild_id_vec();
7c673cae
FG
82 m_next_coll_nr++;
83 }
31f18b77 84 dout(5) << "init has " << m_in_flight.load() << "in-flight transactions" << dendl;
7c673cae
FG
85 wait_for_done();
86 dout(5) << "init finished" << dendl;
87}
88
11fdf7f2
TL
89TestObjectStoreState::coll_entry_t *TestObjectStoreState::coll_create(
90 spg_t pgid, ObjectStore::CollectionHandle ch)
7c673cae 91{
7c673cae 92 char meta_buf[100];
7c673cae 93 memset(meta_buf, 0, 100);
11fdf7f2
TL
94 snprintf(meta_buf, 100, "pglog_0_head");
95 return (new coll_entry_t(pgid, ch, meta_buf));
7c673cae
FG
96}
97
98TestObjectStoreState::coll_entry_t*
11fdf7f2 99TestObjectStoreState::get_coll(coll_t cid, bool erase)
7c673cae 100{
11fdf7f2 101 dout(5) << "get_coll id " << cid << dendl;
7c673cae
FG
102
103 coll_entry_t *entry = NULL;
11fdf7f2 104 auto it = m_collections.find(cid);
7c673cae
FG
105 if (it != m_collections.end()) {
106 entry = it->second;
107 if (erase) {
108 m_collections.erase(it);
11fdf7f2 109 rebuild_id_vec();
7c673cae
FG
110 }
111 }
112
11fdf7f2 113 dout(5) << "get_coll id " << cid;
7c673cae
FG
114 if (!entry)
115 *_dout << " non-existent";
116 else
11fdf7f2 117 *_dout << " name " << entry->m_cid;
7c673cae
FG
118 *_dout << dendl;
119 return entry;
120}
121
122TestObjectStoreState::coll_entry_t*
123TestObjectStoreState::get_coll_at(int pos, bool erase)
124{
125 dout(5) << "get_coll_at pos " << pos << dendl;
126
127 if (m_collections.empty())
128 return NULL;
129
11fdf7f2 130 ceph_assert((size_t) pos < m_collections_ids.size());
7c673cae 131
11fdf7f2
TL
132 coll_t cid = m_collections_ids[pos];
133 coll_entry_t *entry = m_collections[cid];
7c673cae
FG
134
135 if (entry == NULL) {
136 dout(5) << "get_coll_at pos " << pos << " non-existent" << dendl;
137 return NULL;
138 }
139
140 if (erase) {
11fdf7f2
TL
141 m_collections.erase(cid);
142 rebuild_id_vec();
7c673cae
FG
143 }
144
145 dout(5) << "get_coll_at pos " << pos << ": "
11fdf7f2 146 << entry->m_cid << "(removed: " << erase << ")" << dendl;
7c673cae
FG
147
148 return entry;
149}
150
151TestObjectStoreState::coll_entry_t::~coll_entry_t()
152{
153 if (m_objects.size() > 0) {
154 map<int, hobject_t*>::iterator it = m_objects.begin();
155 for (; it != m_objects.end(); ++it) {
156 hobject_t *obj = it->second;
157 if (obj) {
158 delete obj;
159 }
160 }
161 m_objects.clear();
162 }
163}
164
165bool TestObjectStoreState::coll_entry_t::check_for_obj(int id)
166{
167 if (m_objects.count(id))
168 return true;
169 return false;
170}
171
172hobject_t *TestObjectStoreState::coll_entry_t::touch_obj(int id)
173{
174 map<int, hobject_t*>::iterator it = m_objects.find(id);
175 if (it != m_objects.end()) {
11fdf7f2 176 dout(5) << "touch_obj coll id " << m_cid
7c673cae
FG
177 << " name " << it->second->oid.name << dendl;
178 return it->second;
179 }
180
181 char buf[100];
182 memset(buf, 0, 100);
183 snprintf(buf, 100, "obj%d", id);
184
185 hobject_t *obj = new hobject_t(sobject_t(object_t(buf), CEPH_NOSNAP));
11fdf7f2
TL
186 obj->set_hash(m_pgid.ps());
187 obj->pool = m_pgid.pool();
7c673cae
FG
188 m_objects.insert(make_pair(id, obj));
189
11fdf7f2 190 dout(5) << "touch_obj coll id " << m_cid << " name " << buf << dendl;
7c673cae
FG
191 return obj;
192}
193
194hobject_t *TestObjectStoreState::coll_entry_t::get_obj(int id)
195{
196 return get_obj(id, false);
197}
198
199/**
200 * remove_obj - Removes object without freeing it.
201 * @param id Object's id in the map.
202 * @return The object or NULL in case of error.
203 */
204hobject_t *TestObjectStoreState::coll_entry_t::remove_obj(int id)
205{
206 return get_obj(id, true);
207}
208
209hobject_t *TestObjectStoreState::coll_entry_t::get_obj(int id, bool remove)
210{
211 map<int, hobject_t*>::iterator it = m_objects.find(id);
212 if (it == m_objects.end()) {
11fdf7f2 213 dout(5) << "get_obj coll " << m_cid
7c673cae
FG
214 << " obj #" << id << " non-existent" << dendl;
215 return NULL;
216 }
217
218 hobject_t *obj = it->second;
219 if (remove)
220 m_objects.erase(it);
221
11fdf7f2 222 dout(5) << "get_obj coll " << m_cid << " id " << id
7c673cae
FG
223 << ": " << obj->oid.name << "(removed: " << remove << ")" << dendl;
224
225 return obj;
226}
227
228hobject_t *TestObjectStoreState::coll_entry_t::get_obj_at(int pos, int *key)
229{
230 return get_obj_at(pos, false, key);
231}
232
233/**
234 * remove_obj_at - Removes object without freeing it.
235 * @param pos The map's position in which the object lies.
236 * @return The object or NULL in case of error.
237 */
238hobject_t *TestObjectStoreState::coll_entry_t::remove_obj_at(int pos, int *key)
239{
240 return get_obj_at(pos, true, key);
241}
242
243hobject_t *TestObjectStoreState::coll_entry_t::get_obj_at(int pos,
244 bool remove, int *key)
245{
246 if (m_objects.empty()) {
11fdf7f2 247 dout(5) << "get_obj_at coll " << m_cid << " pos " << pos
7c673cae
FG
248 << " in an empty collection" << dendl;
249 return NULL;
250 }
251
252 hobject_t *ret = NULL;
253 map<int, hobject_t*>::iterator it = m_objects.begin();
254 for (int i = 0; it != m_objects.end(); ++it, i++) {
255 if (i == pos) {
256 ret = it->second;
257 break;
258 }
259 }
260
261 if (ret == NULL) {
11fdf7f2 262 dout(5) << "get_obj_at coll " << m_cid << " pos " << pos
7c673cae
FG
263 << " non-existent" << dendl;
264 return NULL;
265 }
266
267 if (key != NULL)
268 *key = it->first;
269
270 if (remove)
271 m_objects.erase(it);
272
11fdf7f2 273 dout(5) << "get_obj_at coll id " << m_cid << " pos " << pos
7c673cae
FG
274 << ": " << ret->oid.name << "(removed: " << remove << ")" << dendl;
275
276 return ret;
277}
278
279hobject_t*
280TestObjectStoreState::coll_entry_t::replace_obj(int id, hobject_t *obj) {
281 hobject_t *old_obj = remove_obj(id);
282 m_objects.insert(make_pair(id, obj));
283 return old_obj;
284}
285
286int TestObjectStoreState::coll_entry_t::get_random_obj_id(rngen_t& gen)
287{
288 ceph_assert(!m_objects.empty());
289
290 boost::uniform_int<> orig_obj_rng(0, m_objects.size()-1);
291 int pos = orig_obj_rng(gen);
292 map<int, hobject_t*>::iterator it = m_objects.begin();
293 for (int i = 0; it != m_objects.end(); ++it, i++) {
294 if (i == pos) {
295 return it->first;
296 }
297 }
11fdf7f2 298 ceph_abort_msg("INTERNAL ERROR");
7c673cae 299}