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