]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
cls/cas/cls_cas_internal: use DENC for refs_by_hash
authorSage Weil <sage@newdream.net>
Thu, 21 May 2020 18:54:35 +0000 (13:54 -0500)
committerSage Weil <sage@newdream.net>
Wed, 27 May 2020 16:30:35 +0000 (11:30 -0500)
In order to make the refs_t subtypes coexist with different encoding
schemes, I had to move things into the .cc file (probably better anyway)
and make them standalone classes (not subclasses).

Signed-off-by: Sage Weil <sage@newdream.net>
src/cls/CMakeLists.txt
src/cls/cas/cls_cas_internal.cc [new file with mode: 0644]
src/cls/cas/cls_cas_internal.h
src/test/cls_cas/CMakeLists.txt
src/tools/CMakeLists.txt
src/tools/ceph-dencoder/CMakeLists.txt

index 05db7f290823059598ffb6b0e586241abee070dd..cb427482e92ff14c67b85e55c6e238cdd5f1f880 100644 (file)
@@ -251,9 +251,18 @@ set(cls_lua_client_srcs
 add_library(cls_lua_client STATIC ${cls_lua_client_srcs})
 
 # cls_cas
+set(cls_cas_client_srcs
+  cas/cls_cas_client.cc)
+add_library(cls_cas_client STATIC ${cls_cas_client_srcs})
+
+set(cls_cas_internal_srcs
+  cas/cls_cas_internal.cc)
+add_library(cls_cas_internal STATIC ${cls_cas_internal_srcs})
+
 set(cls_cas_srcs 
   cas/cls_cas.cc)
 add_library(cls_cas SHARED ${cls_cas_srcs})
+target_link_libraries(cls_cas cls_cas_internal)
 set_target_properties(cls_cas PROPERTIES
   VERSION "1.0.0"
   SOVERSION "1"
@@ -261,9 +270,6 @@ set_target_properties(cls_cas PROPERTIES
   CXX_VISIBILITY_PRESET hidden)
 install(TARGETS cls_cas DESTINATION ${cls_dir})
 
-set(cls_cas_client_srcs
-  cas/cls_cas_client.cc)
-add_library(cls_cas_client STATIC ${cls_cas_client_srcs})
 
 #cls_queue
 set(cls_queue_srcs
diff --git a/src/cls/cas/cls_cas_internal.cc b/src/cls/cas/cls_cas_internal.cc
new file mode 100644 (file)
index 0000000..9c1deda
--- /dev/null
@@ -0,0 +1,337 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "cls_cas_internal.h"
+
+struct refs_by_object : public chunk_obj_refcount::refs_t {
+  std::set<hobject_t> by_object;
+
+  uint8_t get_type() const {
+    return chunk_obj_refcount::TYPE_BY_OBJECT;
+  }
+  bool empty() const override {
+    return by_object.empty();
+  }
+  uint64_t count() const override {
+    return by_object.size();
+  }
+  bool get(const hobject_t& o) override {
+    if (by_object.count(o)) {
+      return false;
+    }
+    by_object.insert(o);
+    return true;
+  }
+  bool put(const hobject_t& o) override {
+    auto p = by_object.find(o);
+    if (p == by_object.end()) {
+      return false;
+    }
+    by_object.erase(p);
+    return true;
+  }
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    encode(by_object, bl);
+    ENCODE_FINISH(bl);
+  }
+  void decode(bufferlist::const_iterator& p) {
+    DECODE_START(1, p);
+    decode(by_object, p);
+    DECODE_FINISH(p);
+  }
+  void dump(Formatter *f) const override {
+    f->dump_string("type", "by_object");
+    f->dump_unsigned("count", by_object.size());
+    f->open_array_section("refs");
+    for (auto& i : by_object) {
+      f->dump_object("ref", i);
+    }
+    f->close_section();
+  }
+};
+WRITE_CLASS_ENCODER(refs_by_object)
+
+struct refs_by_hash : public chunk_obj_refcount::refs_t {
+  uint64_t total = 0;
+  std::map<std::pair<int64_t,uint32_t>,uint64_t> by_hash;
+
+  refs_by_hash() {}
+  refs_by_hash(const refs_by_object *o) {
+    total = o->count();
+    for (auto& i : o->by_object) {
+      by_hash[make_pair(i.pool, i.get_hash())]++;
+    }
+  }
+
+  uint8_t get_type() const {
+    return chunk_obj_refcount::TYPE_BY_HASH;
+  }
+  bool empty() const override {
+    return by_hash.empty();
+  }
+  uint64_t count() const override {
+    return total;
+  }
+  bool get(const hobject_t& o) override {
+    by_hash[make_pair(o.pool, o.get_hash())]++;
+    ++total;
+    return true;
+  }
+  bool put(const hobject_t& o) override {
+    auto p = by_hash.find(make_pair(o.pool, o.get_hash()));
+    if (p == by_hash.end()) {
+      return false;
+    }
+    if (--p->second == 0) {
+      by_hash.erase(p);
+    }
+    --total;
+    return true;
+  }
+  DENC(refs_by_hash, v, p) {
+    DENC_START(1, 1, p);
+    denc(v.total, p);
+    denc(v.by_hash, p);
+    DENC_FINISH(p);
+  }
+  void dump(Formatter *f) const override {
+    f->dump_string("type", "by_hash");
+    f->dump_unsigned("count", total);
+    f->open_array_section("refs");
+    for (auto& i : by_hash) {
+      f->open_object_section("hash");
+      f->dump_int("pool", i.first.first);
+      f->dump_unsigned("hash", i.first.second);
+      f->dump_unsigned("count", i.second);
+      f->close_section();
+    }
+    f->close_section();
+  }
+};
+WRITE_CLASS_DENC(refs_by_hash)
+
+struct refs_by_pool : public chunk_obj_refcount::refs_t {
+  uint64_t total = 0;
+  map<int64_t,uint64_t> by_pool;
+
+  refs_by_pool() {}
+  refs_by_pool(const refs_by_hash *o) {
+    total = o->count();
+    for (auto& i : o->by_hash) {
+      by_pool[i.first.first] += i.second;
+    }
+  }
+
+  uint8_t get_type() const {
+    return chunk_obj_refcount::TYPE_BY_POOL;
+  }
+  bool empty() const override {
+    return by_pool.empty();
+  }
+  uint64_t count() const override {
+    return total;
+  }
+  bool get(const hobject_t& o) override {
+    ++by_pool[o.pool];
+    ++total;
+    return true;
+  }
+  bool put(const hobject_t& o) override {
+    auto p = by_pool.find(o.pool);
+    if (p == by_pool.end()) {
+      return false;
+    }
+    --p->second;
+    if (p->second == 0) {
+      by_pool.erase(p);
+    }
+    --total;
+    return true;
+  }
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    encode(total, bl);
+    encode(by_pool, bl);
+    ENCODE_FINISH(bl);
+  }
+  void decode(bufferlist::const_iterator& p) {
+    DECODE_START(1, p);
+    decode(total, p);
+    decode(by_pool, p);
+    DECODE_FINISH(p);
+  }
+  void dump(Formatter *f) const override {
+    f->dump_string("type", "by_pool");
+    f->dump_unsigned("count", total);
+    f->open_array_section("pools");
+    for (auto& i : by_pool) {
+      f->open_object_section("pool");
+      f->dump_unsigned("pool_id", i.first);
+      f->dump_unsigned("count", i.second);
+      f->close_section();
+    }
+    f->close_section();
+  }
+};
+WRITE_CLASS_ENCODER(refs_by_pool)
+
+struct refs_count : public chunk_obj_refcount::refs_t {
+  uint64_t total = 0;
+
+  refs_count() {}
+  refs_count(const refs_t *old) {
+    total = old->count();
+  }
+
+  uint8_t get_type() const {
+    return chunk_obj_refcount::TYPE_COUNT;
+  }
+  bool empty() const override {
+    return total == 0;
+  }
+  uint64_t count() const override {
+    return total;
+  }
+  bool get(const hobject_t& o) override {
+    ++total;
+    return true;
+  }
+  bool put(const hobject_t& o) override {
+    if (!total) {
+      return false;
+    }
+    --total;
+    return true;
+  }
+  void encode(bufferlist& bl) const {
+    ENCODE_START(1, 1, bl);
+    encode(total, bl);
+    ENCODE_FINISH(bl);
+  }
+  void decode(bufferlist::const_iterator& p) {
+    DECODE_START(1, p);
+    decode(total, p);
+    DECODE_FINISH(p);
+  }
+  void dump(Formatter *f) const override {
+    f->dump_string("type", "count");
+    f->dump_unsigned("count", total);
+  }
+};
+WRITE_CLASS_ENCODER(refs_count)
+
+
+
+//
+
+void chunk_obj_refcount::clear()
+{
+  // default to most precise impl
+  r.reset(new refs_by_object);
+}
+
+
+void chunk_obj_refcount::encode(ceph::buffer::list& bl) const
+{
+  bufferlist t;
+  _encode_r(t);
+  _encode_final(bl, t);
+}
+
+void chunk_obj_refcount::_encode_r(ceph::bufferlist& bl) const
+{
+  using ceph::encode;
+  switch (r->get_type()) {
+  case TYPE_BY_OBJECT:
+    encode(*(refs_by_object*)r.get(), bl);
+    break;
+  case TYPE_BY_HASH:
+    encode(*(refs_by_hash*)r.get(), bl);
+    break;
+  case TYPE_BY_POOL:
+    encode(*(refs_by_pool*)r.get(), bl);
+    break;
+  case TYPE_COUNT:
+    encode(*(refs_count*)r.get(), bl);
+    break;
+  default:
+    ceph_abort("unrecognized ref type");
+  }
+}
+
+void chunk_obj_refcount::dynamic_encode(ceph::buffer::list& bl, size_t max)
+{
+  bufferlist t;
+  while (true) {
+    _encode_r(t);
+    if (t.length() <= max) {
+      break;
+    }
+    // downgrade resolution
+    std::unique_ptr<refs_t> n;
+    switch (r->get_type()) {
+    case TYPE_BY_OBJECT:
+      n.reset(new refs_by_hash(static_cast<refs_by_object*>(r.get())));
+      break;
+    case TYPE_BY_HASH:
+      n.reset(new refs_by_pool(static_cast<refs_by_hash*>(r.get())));
+      break;
+    case TYPE_BY_POOL:
+      n.reset(new refs_count(r.get()));
+      break;
+    }
+    r.swap(n);
+    t.clear();
+  }
+  _encode_final(bl, t);
+}
+
+void chunk_obj_refcount::_encode_final(bufferlist& bl, bufferlist& t) const
+{
+  ENCODE_START(1, 1, bl);
+  encode(r->get_type(), bl);
+  bl.claim_append(t);
+  ENCODE_FINISH(bl);
+}
+
+void chunk_obj_refcount::decode(ceph::buffer::list::const_iterator& p)
+{
+  DECODE_START(1, p);
+  uint8_t t;
+  decode(t, p);
+  switch (t) {
+  case TYPE_BY_OBJECT:
+    {
+      auto n = new refs_by_object();
+      decode(*n, p);
+      r.reset(n);
+    }
+    break;
+  case TYPE_BY_HASH:
+    {
+      auto n = new refs_by_hash();
+      decode(*n, p);
+      r.reset(n);
+    }
+    break;
+  case TYPE_BY_POOL:
+    {
+      auto n = new refs_by_pool();
+      decode(*n, p);
+      r.reset(n);
+    }
+    break;
+  case TYPE_COUNT:
+    {
+      auto n = new refs_count();
+      decode(*n, p);
+      r.reset(n);
+    }
+    break;
+  default:
+    throw ceph::buffer::malformed_input(
+      "unrecognized chunk ref encoding type "s + stringify((int)t));
+  }
+  DECODE_FINISH(p);
+}
index f0267f8605524acc0214f82e078a5e4023786049..02cbcff560cea052ce9937dd02b23cf80874d051 100644 (file)
@@ -7,6 +7,7 @@
 
 #include "include/stringify.h"
 #include "common/Formatter.h"
+#include "common/hobject.h"
 
 #define CHUNK_REFCOUNT_ATTR "chunk_refcount"
 
@@ -26,242 +27,16 @@ struct chunk_obj_refcount {
     virtual uint64_t count() const = 0;
     virtual bool get(const hobject_t& o) = 0;
     virtual bool put(const hobject_t& o) = 0;
-    virtual void encode(bufferlist& bl) const = 0;
-    virtual void decode(bufferlist::const_iterator& p) = 0;
     virtual void dump(Formatter *f) const = 0;
   };
 
-  struct refs_by_object : public refs_t {
-    std::set<hobject_t> by_object;
-
-    uint8_t get_type() const {
-      return TYPE_BY_OBJECT;
-    }
-    bool empty() const override {
-      return by_object.empty();
-    }
-    uint64_t count() const override {
-      return by_object.size();
-    }
-    bool get(const hobject_t& o) override {
-      if (by_object.count(o)) {
-       return false;
-      }
-      by_object.insert(o);
-      return true;
-    }
-    bool put(const hobject_t& o) override {
-      auto p = by_object.find(o);
-      if (p == by_object.end()) {
-       return false;
-      }
-      by_object.erase(p);
-      return true;
-    }
-    void encode(bufferlist& bl) const override {
-      ENCODE_START(1, 1, bl);
-      encode(by_object, bl);
-      ENCODE_FINISH(bl);
-    }
-    void decode(bufferlist::const_iterator& p) override {
-      DECODE_START(1, p);
-      decode(by_object, p);
-      DECODE_FINISH(p);
-    }
-    void dump(Formatter *f) const override {
-      f->dump_string("type", "by_object");
-      f->dump_unsigned("count", by_object.size());
-      f->open_array_section("refs");
-      for (auto& i : by_object) {
-       f->dump_object("ref", i);
-      }
-      f->close_section();
-    }
-  };
-
-  struct refs_by_hash : public refs_t {
-    uint64_t total = 0;
-    std::map<std::pair<int64_t,uint32_t>,uint64_t> by_hash;
-
-    refs_by_hash() {}
-    refs_by_hash(const refs_by_object *o) {
-      total = o->count();
-      for (auto& i : o->by_object) {
-       by_hash[make_pair(i.pool, i.get_hash())]++;
-      }
-    }
-
-    uint8_t get_type() const {
-      return TYPE_BY_HASH;
-    }
-    bool empty() const override {
-      return by_hash.empty();
-    }
-    uint64_t count() const override {
-      return total;
-    }
-    bool get(const hobject_t& o) override {
-      by_hash[make_pair(o.pool, o.get_hash())]++;
-      ++total;
-      return true;
-    }
-    bool put(const hobject_t& o) override {
-      auto p = by_hash.find(make_pair(o.pool, o.get_hash()));
-      if (p == by_hash.end()) {
-       return false;
-      }
-      if (--p->second == 0) {
-       by_hash.erase(p);
-      }
-      --total;
-      return true;
-    }
-    void encode(bufferlist& bl) const override {
-      ENCODE_START(1, 1, bl);
-      encode(total, bl);
-      encode(by_hash, bl);
-      ENCODE_FINISH(bl);
-    }
-    void decode(bufferlist::const_iterator& p) override {
-      DECODE_START(1, p);
-      decode(total, p);
-      decode(by_hash, p);
-      DECODE_FINISH(p);
-    }
-    void dump(Formatter *f) const override {
-      f->dump_string("type", "by_hash");
-      f->dump_unsigned("count", total);
-      f->open_array_section("refs");
-      for (auto& i : by_hash) {
-       f->open_object_section("hash");
-       f->dump_int("pool", i.first.first);
-       f->dump_unsigned("hash", i.first.second);
-       f->dump_unsigned("count", i.second);
-       f->close_section();
-      }
-      f->close_section();
-    }
-  };
-
-  struct refs_by_pool : public refs_t {
-    uint64_t total = 0;
-    map<int64_t,uint64_t> by_pool;
-
-    refs_by_pool() {}
-    refs_by_pool(const refs_by_hash *o) {
-      total = o->count();
-      for (auto& i : o->by_hash) {
-       by_pool[i.first.first] += i.second;
-      }
-    }
-
-    uint8_t get_type() const {
-      return TYPE_BY_POOL;
-    }
-    bool empty() const override {
-      return by_pool.empty();
-    }
-    uint64_t count() const override {
-      return total;
-    }
-    bool get(const hobject_t& o) override {
-      ++by_pool[o.pool];
-      ++total;
-      return true;
-    }
-    bool put(const hobject_t& o) override {
-      auto p = by_pool.find(o.pool);
-      if (p == by_pool.end()) {
-       return false;
-      }
-      --p->second;
-      if (p->second == 0) {
-       by_pool.erase(p);
-      }
-      --total;
-      return true;
-    }
-    void encode(bufferlist& bl) const override {
-      ENCODE_START(1, 1, bl);
-      encode(total, bl);
-      encode(by_pool, bl);
-      ENCODE_FINISH(bl);
-    }
-    void decode(bufferlist::const_iterator& p) override {
-      DECODE_START(1, p);
-      decode(total, p);
-      decode(by_pool, p);
-      DECODE_FINISH(p);
-    }
-    void dump(Formatter *f) const override {
-      f->dump_string("type", "by_pool");
-      f->dump_unsigned("count", total);
-      f->open_array_section("pools");
-      for (auto& i : by_pool) {
-       f->open_object_section("pool");
-       f->dump_unsigned("pool_id", i.first);
-       f->dump_unsigned("count", i.second);
-       f->close_section();
-      }
-      f->close_section();
-    }
-  };
-
-  struct refs_count : public refs_t {
-    uint64_t total = 0;
-
-    refs_count() {}
-    refs_count(const refs_t *old) {
-      total = old->count();
-    }
-
-    uint8_t get_type() const {
-      return TYPE_COUNT;
-    }
-    bool empty() const override {
-      return total == 0;
-    }
-    uint64_t count() const override {
-      return total;
-    }
-    bool get(const hobject_t& o) override {
-      ++total;
-      return true;
-    }
-    bool put(const hobject_t& o) override {
-      if (!total) {
-       return false;
-      }
-      --total;
-      return true;
-    }
-    void encode(bufferlist& bl) const override {
-      ENCODE_START(1, 1, bl);
-      encode(total, bl);
-      ENCODE_FINISH(bl);
-    }
-    void decode(bufferlist::const_iterator& p) override {
-      DECODE_START(1, p);
-      decode(total, p);
-      DECODE_FINISH(p);
-    }
-    void dump(Formatter *f) const override {
-      f->dump_string("type", "count");
-      f->dump_unsigned("count", total);
-    }
-  };
-
-
   std::unique_ptr<refs_t> r;
 
   chunk_obj_refcount() {
     clear();
   }
 
-  void clear() {
-    // default to most precise impl
-    r.reset(new refs_by_object);
-  }
+  void clear();
 
   int get_type() const {
     return r->get_type();
@@ -286,69 +61,11 @@ struct chunk_obj_refcount {
     return ret;
   }
 
-  void encode(ceph::buffer::list& bl) const {
-    bufferlist t;
-    r->encode(t);
-    _encode(bl, t);
-  }
-
-  void dynamic_encode(ceph::buffer::list& bl, size_t max = 1024) {
-    bufferlist t;
-    while (true) {
-      r->encode(t);
-      if (t.length() <= max) {
-       break;
-      }
-      // downgrade resolution
-      std::unique_ptr<refs_t> n;
-      switch (r->get_type()) {
-      case TYPE_BY_OBJECT:
-       n.reset(new refs_by_hash(static_cast<refs_by_object*>(r.get())));
-       break;
-      case TYPE_BY_HASH:
-       n.reset(new refs_by_pool(static_cast<refs_by_hash*>(r.get())));
-       break;
-      case TYPE_BY_POOL:
-       n.reset(new refs_count(r.get()));
-       break;
-      }
-      r.swap(n);
-      t.clear();
-    }
-    _encode(bl, t);
-  }
-
-  void _encode(bufferlist& bl, bufferlist& t) const {
-    ENCODE_START(1, 1, bl);
-    encode(r->get_type(), bl);
-    bl.claim_append(t);
-    ENCODE_FINISH(bl);
-  }
-
-  void decode(ceph::buffer::list::const_iterator& p) {
-    DECODE_START(1, p);
-    uint8_t t;
-    decode(t, p);
-    switch (t) {
-    case TYPE_BY_OBJECT:
-      r.reset(new refs_by_object());
-      break;
-    case TYPE_BY_HASH:
-      r.reset(new refs_by_hash());
-      break;
-    case TYPE_BY_POOL:
-      r.reset(new refs_by_pool());
-      break;
-    case TYPE_COUNT:
-      r.reset(new refs_count());
-      break;
-    default:
-      throw ceph::buffer::malformed_input(
-       "unrecognized chunk ref encoding type "s + stringify((int)t));
-    }
-    r->decode(p);
-    DECODE_FINISH(p);
-  }
+  void _encode_r(bufferlist& bl) const;
+  void _encode_final(bufferlist& bl, bufferlist& t) const;
+  void dynamic_encode(ceph::buffer::list& bl, size_t max = 1024);
+  void encode(ceph::buffer::list& bl) const;
+  void decode(ceph::buffer::list::const_iterator& p);
 
   void dump(Formatter *f) const {
     r->dump(f);
index 83426bc6068c784f1ed5ad2e40779c37caf856ac..16bff8b3b68f64b9c1b1d80a5c39b644c310e503 100644 (file)
@@ -3,6 +3,7 @@ add_executable(ceph_test_cls_cas
 target_link_libraries(ceph_test_cls_cas
   librados
   cls_cas_client
+  cls_cas_internal
   global
   radostest-cxx
   ${UNITTEST_LIBS}
index f460ce1ae2d18b3d1ad9dd5e1aeb69c3f614f4fa..2f09329b48e7527ddecf969052ccf5390ae4c3c4 100644 (file)
@@ -118,7 +118,11 @@ install(TARGETS ceph-authtool DESTINATION bin)
 if(WITH_TESTS)
 set(ceph_dedup_tool_srcs ceph_dedup_tool.cc)
 add_executable(ceph-dedup-tool ${ceph_dedup_tool_srcs})
-target_link_libraries(ceph-dedup-tool librados global cls_cas_client)
+target_link_libraries(ceph-dedup-tool
+  librados
+  global
+  cls_cas_client
+  cls_cas_internal)
 install(TARGETS ceph-dedup-tool DESTINATION bin)
 endif(WITH_TESTS)
 
index 5f6b426cae6c9e4e0d83a54cf9b369449892926f..4a7b452f71d73bc76c8cbe977c3bbceac162e737 100644 (file)
@@ -71,6 +71,8 @@ target_link_libraries(ceph-dencoder
   cls_user_client
   cls_journal_client
   cls_timeindex_client
+  cls_cas_internal
+  cls_cas_client
   ${EXTRALIBS}
   ${CMAKE_DL_LIBS})
 install(TARGETS ceph-dencoder DESTINATION bin)