#ifndef CEPH_OSDMAP_H
#define CEPH_OSDMAP_H
+#include "include/cpp-btree/btree_map.h"
+
/*
* describe properties of the OSD cluster.
* disks, disk groups, total # osds,
struct PGTempMap {
+#if 1
+ bufferlist data;
+ typedef btree::btree_map<pg_t,int32_t*> map_t;
+ map_t map;
+
+ void encode(bufferlist& bl) const {
+ uint32_t n = map.size();
+ ::encode(n, bl);
+ for (auto &p : map) {
+ ::encode(p.first, bl);
+ bl.append((char*)p.second, (*p.second + 1) * sizeof(int32_t));
+ }
+ }
+ void decode(bufferlist::iterator& p) {
+ data.clear();
+ map.clear();
+ uint32_t n;
+ ::decode(n, p);
+ if (!n)
+ return;
+ bufferlist::iterator pstart = p;
+ size_t start_off = pstart.get_off();
+ vector<pair<pg_t,size_t>> offsets;
+ offsets.resize(n);
+ for (unsigned i=0; i<n; ++i) {
+ pg_t pgid;
+ ::decode(pgid, p);
+ offsets[i].first = pgid;
+ offsets[i].second = p.get_off() - start_off;
+ uint32_t vn;
+ ::decode(vn, p);
+ p.advance(vn * sizeof(int32_t));
+ }
+ size_t len = p.get_off() - start_off;
+ pstart.copy(len, data);
+ if (data.get_num_buffers() > 1) {
+ data.rebuild();
+ }
+ //map.reserve(n);
+ char *start = data.c_str();
+ for (auto i : offsets) {
+ map.insert(map.end(), make_pair(i.first, (int32_t*)(start + i.second)));
+ }
+ }
+ void rebuild() {
+ bufferlist bl;
+ encode(bl);
+ auto p = bl.begin();
+ decode(p);
+ }
+ friend bool operator==(const PGTempMap& l, const PGTempMap& r) {
+ return
+ l.map.size() == r.map.size() &&
+ l.data.contents_equal(r.data);
+ }
+
+ class iterator {
+ map_t::const_iterator it;
+ map_t::const_iterator end;
+ pair<pg_t,vector<int32_t>> current;
+ void init_current() {
+ if (it != end) {
+ current.first = it->first;
+ assert(it->second);
+ current.second.resize(*it->second);
+ int32_t *p = it->second + 1;
+ for (int n = 0; n < *it->second; ++n, ++p) {
+ current.second[n] = *p;
+ }
+ }
+ }
+ public:
+ iterator(map_t::const_iterator p,
+ map_t::const_iterator e)
+ : it(p), end(e) {
+ init_current();
+ }
+
+ const pair<pg_t,vector<int32_t>>& operator*() const {
+ return current;
+ }
+ const pair<pg_t,vector<int32_t>>* operator->() const {
+ return ¤t;
+ }
+ friend bool operator==(const iterator& l, const iterator& r) {
+ return l.it == r.it;
+ }
+ friend bool operator!=(const iterator& l, const iterator& r) {
+ return l.it != r.it;
+ }
+ iterator& operator++() {
+ ++it;
+ if (it != end)
+ init_current();
+ return *this;
+ }
+ iterator operator++(int) {
+ iterator r = *this;
+ ++it;
+ if (it != end)
+ init_current();
+ return r;
+ }
+ };
+ iterator begin() const {
+ return iterator(map.begin(), map.end());
+ }
+ iterator end() const {
+ return iterator(map.end(), map.end());
+ }
+ iterator find(pg_t pgid) const {
+ return iterator(map.find(pgid), map.end());
+ }
+ size_t size() const {
+ return map.size();
+ }
+ size_t count(pg_t pgid) const {
+ return map.count(pgid);
+ }
+ void erase(pg_t pgid) {
+ map.erase(pgid);
+ }
+ void clear() {
+ map.clear();
+ data.clear();
+ }
+ void set(pg_t pgid, const mempool::osdmap::vector<int32_t>& v) {
+ size_t need = sizeof(int32_t) * (1 + v.size());
+ if (need < data.get_append_buffer_unused_tail_length()) {
+ bufferptr z(data.get_append_buffer_unused_tail_length());
+ z.zero();
+ data.append(z.c_str(), z.length());
+ }
+ ::encode(v, data);
+ map[pgid] = (int32_t*)(data.back().end_c_str()) - (1 + v.size());
+ }
+ mempool::osdmap::vector<int32_t> get(pg_t pgid) {
+ mempool::osdmap::vector<int32_t> v;
+ int32_t *p = map[pgid];
+ size_t n = *p++;
+ v.resize(n);
+ for (size_t i = 0; i < n; ++i, ++p) {
+ v[i] = *p;
+ }
+ return v;
+ }
+#else
+ // trivial implementation
mempool::osdmap::map<pg_t,mempool::osdmap::vector<int32_t> > pg_temp;
void encode(bufferlist& bl) const {
const mempool::osdmap::vector<int32_t>& get(pg_t pgid) {
return pg_temp.at(pgid);
}
+#endif
void dump(Formatter *f) const {
for (const auto &pg : *this) {
f->open_object_section("osds");