Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / osd / HitSet.cc
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) 2013 Inktank <info@inktank.com>
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  */
14
15 #include "HitSet.h"
16 #include "common/Formatter.h"
17
18 // -- HitSet --
19
20 HitSet::HitSet(const HitSet::Params& params)
21   : sealed(false)
22 {
23   switch (params.get_type()) {
24   case TYPE_BLOOM:
25     {
26       BloomHitSet::Params *p =
27         static_cast<BloomHitSet::Params*>(params.impl.get());
28       impl.reset(new BloomHitSet(p));
29     }
30     break;
31
32   case TYPE_EXPLICIT_HASH:
33     impl.reset(new ExplicitHashHitSet(static_cast<ExplicitHashHitSet::Params*>(params.impl.get())));
34     break;
35
36   case TYPE_EXPLICIT_OBJECT:
37     impl.reset(new ExplicitObjectHitSet(static_cast<ExplicitObjectHitSet::Params*>(params.impl.get())));
38     break;
39
40   default:
41     assert (0 == "unknown HitSet type");
42   }
43 }
44
45 void HitSet::encode(bufferlist &bl) const
46 {
47   ENCODE_START(1, 1, bl);
48   ::encode(sealed, bl);
49   if (impl) {
50     ::encode((__u8)impl->get_type(), bl);
51     impl->encode(bl);
52   } else {
53     ::encode((__u8)TYPE_NONE, bl);
54   }
55   ENCODE_FINISH(bl);
56 }
57
58 void HitSet::decode(bufferlist::iterator &bl)
59 {
60   DECODE_START(1, bl);
61   ::decode(sealed, bl);
62   __u8 type;
63   ::decode(type, bl);
64   switch ((impl_type_t)type) {
65   case TYPE_EXPLICIT_HASH:
66     impl.reset(new ExplicitHashHitSet);
67     break;
68   case TYPE_EXPLICIT_OBJECT:
69     impl.reset(new ExplicitObjectHitSet);
70     break;
71   case TYPE_BLOOM:
72     impl.reset(new BloomHitSet);
73     break;
74   case TYPE_NONE:
75     impl.reset(NULL);
76     break;
77   default:
78     throw buffer::malformed_input("unrecognized HitMap type");
79   }
80   if (impl)
81     impl->decode(bl);
82   DECODE_FINISH(bl);
83 }
84
85 void HitSet::dump(Formatter *f) const
86 {
87   f->dump_string("type", get_type_name());
88   f->dump_string("sealed", sealed ? "yes" : "no");
89   if (impl)
90     impl->dump(f);
91 }
92
93 void HitSet::generate_test_instances(list<HitSet*>& o)
94 {
95   o.push_back(new HitSet);
96   o.push_back(new HitSet(new BloomHitSet(10, .1, 1)));
97   o.back()->insert(hobject_t());
98   o.back()->insert(hobject_t("asdf", "", CEPH_NOSNAP, 123, 1, ""));
99   o.back()->insert(hobject_t("qwer", "", CEPH_NOSNAP, 456, 1, ""));
100   o.push_back(new HitSet(new ExplicitHashHitSet));
101   o.back()->insert(hobject_t());
102   o.back()->insert(hobject_t("asdf", "", CEPH_NOSNAP, 123, 1, ""));
103   o.back()->insert(hobject_t("qwer", "", CEPH_NOSNAP, 456, 1, ""));
104   o.push_back(new HitSet(new ExplicitObjectHitSet));
105   o.back()->insert(hobject_t());
106   o.back()->insert(hobject_t("asdf", "", CEPH_NOSNAP, 123, 1, ""));
107   o.back()->insert(hobject_t("qwer", "", CEPH_NOSNAP, 456, 1, ""));
108 }
109
110 HitSet::Params::Params(const Params& o)
111 {
112   if (o.get_type() != TYPE_NONE) {
113     create_impl(o.get_type());
114     // it's annoying to write virtual operator= methods; use encode/decode
115     // instead.
116     bufferlist bl;
117     o.impl->encode(bl);
118     bufferlist::iterator p = bl.begin();
119     impl->decode(p);
120   } // else we don't need to do anything
121 }
122
123 const HitSet::Params& HitSet::Params::operator=(const Params& o)
124 {
125   create_impl(o.get_type());
126   if (o.impl) {
127     // it's annoying to write virtual operator= methods; use encode/decode
128     // instead.
129     bufferlist bl;
130     o.impl->encode(bl);
131     bufferlist::iterator p = bl.begin();
132     impl->decode(p);
133   }
134   return *this;
135 }
136
137 void HitSet::Params::encode(bufferlist &bl) const
138 {
139   ENCODE_START(1, 1, bl);
140   if (impl) {
141     ::encode((__u8)impl->get_type(), bl);
142     impl->encode(bl);
143   } else {
144     ::encode((__u8)TYPE_NONE, bl);
145   }
146   ENCODE_FINISH(bl);
147 }
148
149 bool HitSet::Params::create_impl(impl_type_t type)
150 {
151   switch ((impl_type_t)type) {
152   case TYPE_EXPLICIT_HASH:
153     impl.reset(new ExplicitHashHitSet::Params);
154     break;
155   case TYPE_EXPLICIT_OBJECT:
156     impl.reset(new ExplicitObjectHitSet::Params);
157     break;
158   case TYPE_BLOOM:
159     impl.reset(new BloomHitSet::Params);
160     break;
161   case TYPE_NONE:
162     impl.reset(NULL);
163     break;
164   default:
165     return false;
166   }
167   return true;
168 }
169
170 void HitSet::Params::decode(bufferlist::iterator &bl)
171 {
172   DECODE_START(1, bl);
173   __u8 type;
174   ::decode(type, bl);
175   if (!create_impl((impl_type_t)type))
176     throw buffer::malformed_input("unrecognized HitMap type");
177   if (impl)
178     impl->decode(bl);
179   DECODE_FINISH(bl);
180 }
181
182 void HitSet::Params::dump(Formatter *f) const
183 {
184   f->dump_string("type", HitSet::get_type_name(get_type()));
185   if (impl)
186     impl->dump(f);
187 }
188
189 void HitSet::Params::generate_test_instances(list<HitSet::Params*>& o)
190 {
191 #define loop_hitset_params(kind) \
192 { \
193   list<kind::Params*> params; \
194   kind::Params::generate_test_instances(params); \
195   for (list<kind::Params*>::iterator i = params.begin(); \
196   i != params.end(); ++i) \
197     o.push_back(new Params(*i)); \
198 }
199   o.push_back(new Params);
200   o.push_back(new Params(new BloomHitSet::Params));
201   loop_hitset_params(BloomHitSet);
202   o.push_back(new Params(new ExplicitHashHitSet::Params));
203   loop_hitset_params(ExplicitHashHitSet);
204   o.push_back(new Params(new ExplicitObjectHitSet::Params));
205   loop_hitset_params(ExplicitObjectHitSet);
206 }
207
208 ostream& operator<<(ostream& out, const HitSet::Params& p) {
209   out << HitSet::get_type_name(p.get_type());
210   if (p.impl) {
211     out << "{";
212     p.impl->dump_stream(out);
213   }
214   out << "}";
215   return out;
216 }
217
218
219 void ExplicitHashHitSet::dump(Formatter *f) const {
220   f->dump_unsigned("insert_count", count);
221   f->open_array_section("hash_set");
222   for (ceph::unordered_set<uint32_t>::const_iterator p = hits.begin();
223        p != hits.end();
224        ++p)
225     f->dump_unsigned("hash", *p);
226   f->close_section();
227 }
228
229 void ExplicitObjectHitSet::dump(Formatter *f) const {
230   f->dump_unsigned("insert_count", count);
231   f->open_array_section("set");
232   for (ceph::unordered_set<hobject_t>::const_iterator p = hits.begin();
233        p != hits.end();
234        ++p) {
235     f->open_object_section("object");
236     p->dump(f);
237     f->close_section();
238   }
239   f->close_section();
240 }
241
242 void BloomHitSet::Params::dump(Formatter *f) const {
243   f->dump_float("false_positive_probability", get_fpp());
244   f->dump_int("target_size", target_size);
245   f->dump_int("seed", seed);
246 }
247
248 void BloomHitSet::dump(Formatter *f) const {
249   f->open_object_section("bloom_filter");
250   bloom.dump(f);
251   f->close_section();
252 }