]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
neorados: Op builder functions should chain
authorAdam C. Emerson <aemerson@redhat.com>
Mon, 20 Mar 2023 16:20:38 +0000 (12:20 -0400)
committerAdam Emerson <aemerson@redhat.com>
Wed, 6 Dec 2023 20:39:35 +0000 (15:39 -0500)
Make every operation function return the (Read/Write)Op, for chaining.

Signed-off-by: Adam C. Emerson <aemerson@redhat.com>
src/include/neorados/RADOS.hpp
src/neorados/RADOS.cc
src/test/librados_test_stub/NeoradosTestStub.cc

index 9bbe10b6670f2ac2f4202b970951a62ed69df1e9..67a01b43148e700f3cccb9ed2273eab43c21770a 100644 (file)
@@ -16,6 +16,7 @@
 #ifndef NEORADOS_RADOS_HPP
 #define NEORADOS_RADOS_HPP
 
+#include <concepts>
 #include <cstddef>
 #include <memory>
 #include <tuple>
@@ -217,6 +218,71 @@ enum alloc_hint_t {
 };
 }
 
+class Op;
+class ReadOp;
+class WriteOp;
+
+template<std::invocable<Op&> F>
+class ClsOp {
+  F f;
+public:
+  ClsOp(F&& f) : f(std::move(f)) {}
+
+  ReadOp& operator()(ReadOp& op) {
+    std::move(f)(op);
+    return op;
+  }
+
+  ReadOp&& operator()(ReadOp&& op) {
+    std::move(f)(op);
+    return std::move(op);
+  }
+
+  WriteOp& operator()(WriteOp& op) {
+    std::move(f)(op);
+    return op;
+  }
+
+  WriteOp&& operator()(WriteOp&& op) {
+    std::move(f)(op);
+    return std::move(op);
+  }
+};
+
+template<std::invocable<ReadOp&> F>
+class ClsReadOp {
+  F f;
+public:
+  ClsReadOp(F&& f) : f(std::move(f)) {}
+
+  ReadOp& operator()(ReadOp& op) {
+    std::move(f)(op);
+    return op;
+  }
+
+  ReadOp&& operator()(ReadOp&& op) {
+    std::move(f)(op);
+    return std::move(op);
+  }
+};
+
+template<std::invocable<WriteOp&> F>
+class ClsWriteOp {
+  F f;
+public:
+  ClsWriteOp(F&& f) : f(std::move(f)) {}
+
+  WriteOp& operator()(WriteOp& op) {
+    std::move(f)(op);
+    return op;
+  }
+
+  WriteOp&& operator()(WriteOp&& op) {
+    std::move(f)(op);
+    return std::move(op);
+  }
+};
+
 class Op {
   friend RADOS;
 
@@ -242,9 +308,9 @@ public:
   void cmpxattr(std::string_view name, cmpxattr_op op, std::uint64_t val);
   void assert_version(uint64_t ver);
   void assert_exists();
-  void cmp_omap(const boost::container::flat_map<
-                 std::string,
-                 std::pair<ceph::buffer::list, int>>& assertions);
+  void cmp_omap(const boost::container::flat_map<std::string,
+                                                std::pair<ceph::buffer::list,
+                                                          int>>& assertions);
 
   void exec(std::string_view cls, std::string_view method,
            const ceph::buffer::list& inbl,
@@ -302,51 +368,398 @@ public:
   ReadOp& operator =(const ReadOp&) = delete;
   ReadOp& operator =(ReadOp&&) = default;
 
-  void read(size_t off, uint64_t len, ceph::buffer::list* out,
-           boost::system::error_code* ec = nullptr);
-  void get_xattr(std::string_view name, ceph::buffer::list* out,
-                boost::system::error_code* ec = nullptr);
-  void get_omap_header(ceph::buffer::list*,
-                      boost::system::error_code* ec = nullptr);
+  ReadOp& read(size_t off, uint64_t len, ceph::buffer::list* out,
+              boost::system::error_code* ec = nullptr) &;
+  ReadOp&& read(size_t off, uint64_t len, ceph::buffer::list* out,
+               boost::system::error_code* ec = nullptr) && {
+    return std::move(read(off, len, out, ec));
+  }
+  ReadOp& get_xattr(std::string_view name, ceph::buffer::list* out,
+                   boost::system::error_code* ec = nullptr) &;
+  ReadOp&& get_xattr(std::string_view name, ceph::buffer::list* out,
+                    boost::system::error_code* ec = nullptr) && {
+    return std::move(get_xattr(name, out, ec));
+  }
+  ReadOp& get_omap_header(ceph::buffer::list* bl,
+                         boost::system::error_code* ec = nullptr) &;
+  ReadOp&& get_omap_header(ceph::buffer::list* bl,
+                          boost::system::error_code* ec = nullptr) && {
+    return std::move(get_omap_header(bl, ec));
+  }
+  ReadOp& sparse_read(uint64_t off, uint64_t len,
+                     ceph::buffer::list* out,
+                     std::vector<std::pair<std::uint64_t,
+                                           std::uint64_t>>* extents,
+                     boost::system::error_code* ec = nullptr) &;
+  ReadOp&& sparse_read(uint64_t off, uint64_t len,
+                      ceph::buffer::list* out,
+                      std::vector<std::pair<std::uint64_t,
+                                            std::uint64_t>>* extents,
+                      boost::system::error_code* ec = nullptr) && {
+    return std::move(sparse_read(off, len, out, extents, ec));
+  }
 
-  void sparse_read(uint64_t off, uint64_t len,
-                  ceph::buffer::list* out,
-                  std::vector<std::pair<std::uint64_t, std::uint64_t>>* extents,
-                  boost::system::error_code* ec = nullptr);
+  ReadOp& stat(std::uint64_t* size, ceph::real_time* mtime,
+              boost::system::error_code* ec = nullptr) &;
+  ReadOp&& stat(std::uint64_t* size, ceph::real_time* mtime,
+               boost::system::error_code* ec = nullptr) && {
+    return std::move(stat(size, mtime, ec));
+  }
 
-  void stat(std::uint64_t* size, ceph::real_time* mtime,
-           boost::system::error_code* ec = nullptr);
+  ReadOp& get_omap_keys(std::optional<std::string_view> start_after,
+                       std::uint64_t max_return,
+                       boost::container::flat_set<std::string>* keys,
+                       bool* truncated,
+                       boost::system::error_code* ec = nullptr) &;
+  ReadOp&& get_omap_keys(std::optional<std::string_view> start_after,
+                        std::uint64_t max_return,
+                        boost::container::flat_set<std::string>* keys,
+                        bool* truncated,
+                        boost::system::error_code* ec = nullptr) && {
+    return std::move(get_omap_keys(start_after, max_return, keys, truncated, ec));
+  }
 
-  void get_omap_keys(std::optional<std::string_view> start_after,
-                    std::uint64_t max_return,
-                    boost::container::flat_set<std::string>* keys,
-                    bool* truncated,
-                    boost::system::error_code* ec = nullptr);
 
+  ReadOp& get_xattrs(boost::container::flat_map<std::string,
+                                              ceph::buffer::list>* kv,
+                    boost::system::error_code* ec = nullptr) &;
+  ReadOp&& get_xattrs(boost::container::flat_map<std::string,
+                                               ceph::buffer::list>* kv,
+                     boost::system::error_code* ec = nullptr) && {
+    return std::move(get_xattrs(kv, ec));
+  }
 
-  void get_xattrs(boost::container::flat_map<std::string,
-                                            ceph::buffer::list>* kv,
-                    boost::system::error_code* ec = nullptr);
+  ReadOp& get_omap_vals(std::optional<std::string_view> start_after,
+                       std::optional<std::string_view> filter_prefix,
+                       uint64_t max_return,
+                       boost::container::flat_map<std::string,
+                                                  ceph::buffer::list>* kv,
+                       bool* truncated,
+                       boost::system::error_code* ec = nullptr) &;
+  ReadOp&& get_omap_vals(std::optional<std::string_view> start_after,
+                        std::optional<std::string_view> filter_prefix,
+                        uint64_t max_return,
+                        boost::container::flat_map<std::string,
+                                                   ceph::buffer::list>* kv,
+                        bool* truncated,
+                        boost::system::error_code* ec = nullptr) && {
+    return std::move(get_omap_vals(start_after, filter_prefix, max_return, kv,
+                                  truncated, ec));
+  }
 
-  void get_omap_vals(std::optional<std::string_view> start_after,
-                    std::optional<std::string_view> filter_prefix,
-                    uint64_t max_return,
-                    boost::container::flat_map<std::string,
-                                               ceph::buffer::list>* kv,
-                    bool* truncated,
-                    boost::system::error_code* ec = nullptr);
+  ReadOp& get_omap_vals_by_keys(
+    const boost::container::flat_set<std::string>& keys,
+    boost::container::flat_map<std::string, ceph::buffer::list>* kv,
+    boost::system::error_code* ec = nullptr) &;
+  ReadOp&& get_omap_vals_by_keys(
+    const boost::container::flat_set<std::string>& keys,
+    boost::container::flat_map<std::string, ceph::buffer::list>* kv,
+    boost::system::error_code* ec = nullptr) && {
+    return std::move(get_omap_vals_by_keys(keys, kv, ec));
+  }
 
+  ReadOp& list_watchers(std::vector<struct ObjWatcher>* watchers,
+                       boost::system::error_code* ec = nullptr) &;
+  ReadOp&& list_watchers(std::vector<struct ObjWatcher>* watchers,
+                        boost::system::error_code* ec = nullptr) && {
+    return std::move(list_watchers(watchers, ec));
+  }
 
-  void get_omap_vals_by_keys(const boost::container::flat_set<std::string>& keys,
-                            boost::container::flat_map<std::string,
-                                                       ceph::buffer::list>* kv,
-                            boost::system::error_code* ec = nullptr);
+  ReadOp& list_snaps(struct SnapSet* snaps,
+                    boost::system::error_code* ec = nullptr) &;
+  ReadOp&& list_snaps(struct SnapSet* snaps,
+                     boost::system::error_code* ec = nullptr) && {
+    return std::move(list_snaps(snaps, ec));
+  }
 
-  void list_watchers(std::vector<struct ObjWatcher>* watchers,
-                    boost::system::error_code* ec = nullptr);
+  // Chaining versions of functions from Op
+  ReadOp& set_excl() & {
+    Op::set_excl();
+    return *this;
+  }
+  ReadOp&& set_excl() && {
+    Op::set_excl();
+    return std::move(*this);
+  }
+
+  ReadOp& set_failok() & {
+    Op::set_failok();
+    return *this;
+  }
+  ReadOp&& set_failok() && {
+    Op::set_failok();
+    return std::move(*this);
+  }
+
+  ReadOp& set_fadvise_random() & {
+    Op::set_fadvise_random();
+    return *this;
+  }
+  ReadOp&& set_fadvise_random() && {
+    Op::set_fadvise_random();
+    return std::move(*this);
+  }
+
+  ReadOp& set_fadvise_sequential() & {
+    Op::set_fadvise_sequential();
+    return *this;
+  }
+  ReadOp&& set_fadvise_sequential() && {
+    Op::set_fadvise_sequential();
+    return std::move(*this);
+  }
+
+  ReadOp& set_fadvise_willneed() & {
+    Op::set_fadvise_willneed();
+    return *this;
+  }
+  ReadOp&& set_fadvise_willneed() && {
+    Op::set_fadvise_willneed();
+    return std::move(*this);
+  }
 
-  void list_snaps(struct SnapSet* snaps,
-                 boost::system::error_code* ec = nullptr);
+  ReadOp& set_fadvise_dontneed() & {
+    Op::set_fadvise_dontneed();
+    return *this;
+  }
+  ReadOp&& set_fadvise_dontneed() && {
+    Op::set_fadvise_dontneed();
+    return std::move(*this);
+  }
+
+  ReadOp& set_fadvise_nocache() & {
+    Op::set_fadvise_nocache();
+    return *this;
+  }
+  ReadOp&& set_fadvise_nocache() && {
+    Op::set_fadvise_nocache();
+    return std::move(*this);
+  }
+
+  ReadOp& cmpext(uint64_t off, ceph::buffer::list&& cmp_bl, std::size_t* s) & {
+    Op::cmpext(off, std::move(cmp_bl), s);
+    return *this;
+  }
+  ReadOp&& cmpext(uint64_t off, ceph::buffer::list&& cmp_bl, std::size_t* s) && {
+    Op::cmpext(off, std::move(cmp_bl), s);
+    return std::move(*this);
+  }
+
+  ReadOp& cmpxattr(std::string_view name, cmpxattr_op op,
+                  const ceph::buffer::list& val) & {
+    Op::cmpxattr(name, op, val);
+    return *this;
+  }
+  ReadOp&& cmpxattr(std::string_view name, cmpxattr_op op,
+                   const ceph::buffer::list& val) && {
+    Op::cmpxattr(name, op, val);
+    return std::move(*this);
+  }
+
+  ReadOp& cmpxattr(std::string_view name, cmpxattr_op op, std::uint64_t val) & {
+    Op::cmpxattr(name, op, val);
+    return *this;
+  }
+  ReadOp&& cmpxattr(std::string_view name, cmpxattr_op op, std::uint64_t val) && {
+    Op::cmpxattr(name, op, val);
+    return std::move(*this);
+  }
+
+  ReadOp& assert_version(uint64_t ver) & {
+    Op::assert_version(ver);
+    return *this;
+  }
+  ReadOp&& assert_version(uint64_t ver) && {
+    Op::assert_version(ver);
+    return std::move(*this);
+  }
+
+  ReadOp& assert_exists() & {
+    Op::assert_exists();
+    return *this;
+  }
+  ReadOp&& assert_exists() && {
+    Op::assert_exists();
+    return std::move(*this);
+  }
+
+  ReadOp& cmp_omap(
+    const boost::container::flat_map<
+      std::string, std::pair<ceph::buffer::list, int>>& assertions) & {
+    Op::cmp_omap(assertions);
+    return *this;
+  }
+  ReadOp&& cmp_omap(
+    const boost::container::flat_map<
+      std::string, std::pair<ceph::buffer::list, int>>& assertions) && {
+    Op::cmp_omap(assertions);
+    return std::move(*this);
+  }
+
+  ReadOp& exec(std::string_view cls, std::string_view method,
+              const ceph::buffer::list& inbl,
+              ceph::buffer::list* out,
+              boost::system::error_code* ec = nullptr) & {
+    Op::exec(cls, method, inbl, out, ec);
+    return *this;
+  }
+  ReadOp&& exec(std::string_view cls, std::string_view method,
+               const ceph::buffer::list& inbl,
+               ceph::buffer::list* out,
+               boost::system::error_code* ec = nullptr) && {
+    Op::exec(cls, method, inbl, out, ec);
+    return std::move(*this);
+  }
+
+  ReadOp& exec(std::string_view cls, std::string_view method,
+              const ceph::buffer::list& inbl,
+              fu2::unique_function<void(boost::system::error_code,
+                                   const ceph::buffer::list&) &&> f) & {
+    Op::exec(cls, method, inbl, std::move(f));
+    return *this;
+  }
+  ReadOp&& exec(std::string_view cls, std::string_view method,
+               const ceph::buffer::list& inbl,
+               fu2::unique_function<void(boost::system::error_code,
+                                    const ceph::buffer::list&) &&> f) && {
+    Op::exec(cls, method, inbl, std::move(f));
+    return std::move(*this);
+  }
+
+  ReadOp& exec(std::string_view cls, std::string_view method,
+              const ceph::buffer::list& inbl,
+              fu2::unique_function<void(boost::system::error_code, int,
+                                        const ceph::buffer::list&) &&> f) & {
+    Op::exec(cls, method, inbl, std::move(f));
+    return *this;
+  }
+  ReadOp&& exec(std::string_view cls, std::string_view method,
+               const ceph::buffer::list& inbl,
+               fu2::unique_function<void(boost::system::error_code, int,
+                                         const ceph::buffer::list&) &&> f) && {
+    Op::exec(cls, method, inbl, std::move(f));
+    return std::move(*this);
+  }
+
+  ReadOp& exec(std::string_view cls, std::string_view method,
+              const ceph::buffer::list& inbl,
+              boost::system::error_code* ec = nullptr) & {
+    Op::exec(cls, method, inbl, ec);
+    return *this;
+  }
+  ReadOp&& exec(std::string_view cls, std::string_view method,
+               const ceph::buffer::list& inbl,
+               boost::system::error_code* ec = nullptr) && {
+    Op::exec(cls, method, inbl, ec);
+    return std::move(*this);
+  }
+
+  template<typename F>
+  ReadOp& exec(ClsOp<F>&& clsop) & {
+    return clsop(*this);
+  }
+  template<typename F>
+  ReadOp&& exec(ClsOp<F>&& clsop) && {
+    return std::move(clsop(*this));
+  }
+  template<typename F>
+  ReadOp& exec(ClsReadOp<F>&& clsop) & {
+    return clsop(*this);
+  }
+  template<typename F>
+  ReadOp&& exec(ClsReadOp<F>&& clsop) && {
+    return std::move(clsop(*this));
+  }
+
+  // Flags that apply to all ops in the operation vector
+  ReadOp& balance_reads() & {
+    Op::balance_reads();
+    return *this;
+  }
+  ReadOp&& balance_reads() && {
+    Op::balance_reads();
+    return std::move(*this);
+  }
+  ReadOp& localize_reads() & {
+    Op::localize_reads();
+    return *this;
+  }
+  ReadOp&& localize_reads() && {
+    Op::localize_reads();
+    return std::move(*this);
+  }
+  ReadOp& order_reads_writes() & {
+    Op::order_reads_writes();
+    return *this;
+  }
+  ReadOp&& order_reads_writes() && {
+    Op::order_reads_writes();
+    return std::move(*this);
+  }
+  ReadOp& ignore_cache() & {
+    Op::ignore_cache();
+    return *this;
+  }
+  ReadOp&& ignore_cache() && {
+    Op::ignore_cache();
+    return std::move(*this);
+  }
+  ReadOp& skiprwlocks() & {
+    Op::skiprwlocks();
+    return *this;
+  }
+  ReadOp&& skiprwlocks() && {
+    Op::skiprwlocks();
+    return std::move(*this);
+  }
+  ReadOp& ignore_overlay() & {
+    Op::ignore_overlay();
+    return *this;
+  }
+  ReadOp&& ignore_overlay() && {
+    Op::ignore_overlay();
+    return std::move(*this);
+  }
+  ReadOp& full_try() & {
+    Op::full_try();
+    return *this;
+  }
+  ReadOp&& full_try() && {
+    Op::full_try();
+    return std::move(*this);
+  }
+  ReadOp& full_force() & {
+    Op::full_force();
+    return *this;
+  }
+  ReadOp&& full_force() && {
+    Op::full_force();
+    return std::move(*this);
+  }
+  ReadOp& ignore_redirect() & {
+    Op::ignore_redirect();
+    return *this;
+  }
+  ReadOp&& ignore_redirect() && {
+    Op::ignore_redirect();
+    return std::move(*this);
+  }
+  ReadOp& ordersnap() & {
+    Op::ordersnap();
+    return *this;
+  }
+  ReadOp&& ordersnap() && {
+    Op::ordersnap();
+    return std::move(*this);
+  }
+  ReadOp& returnvec() & {
+    Op::returnvec();
+    return *this;
+  }
+  ReadOp&& returnvec() && {
+    Op::returnvec();
+    return std::move(*this);
+  }
 };
 
 class WriteOp final : public Op {
@@ -360,28 +773,376 @@ public:
   WriteOp& operator =(const WriteOp&) = delete;
   WriteOp& operator =(WriteOp&&) = default;
 
-  void set_mtime(ceph::real_time t);
-  void create(bool exclusive);
-  void write(uint64_t off, ceph::buffer::list&& bl);
-  void write_full(ceph::buffer::list&& bl);
-  void writesame(std::uint64_t off, std::uint64_t write_len,
-                ceph::buffer::list&& bl);
-  void append(ceph::buffer::list&& bl);
-  void remove();
-  void truncate(uint64_t off);
-  void zero(uint64_t off, uint64_t len);
-  void rmxattr(std::string_view name);
-  void setxattr(std::string_view name,
-               ceph::buffer::list&& bl);
-  void rollback(uint64_t snapid);
-  void set_omap(const boost::container::flat_map<std::string,
-                                                ceph::buffer::list>& map);
-  void set_omap_header(ceph::buffer::list&& bl);
-  void clear_omap();
-  void rm_omap_keys(const boost::container::flat_set<std::string>& to_rm);
-  void set_alloc_hint(uint64_t expected_object_size,
-                     uint64_t expected_write_size,
-                     alloc_hint::alloc_hint_t flags);
+  WriteOp& set_mtime(ceph::real_time t) &;
+  WriteOp&& set_mtime(ceph::real_time t) && {
+    return std::move(set_mtime(t));
+  }
+  WriteOp& create(bool exclusive) &;
+  WriteOp&& create(bool exclusive) && {
+    return std::move(create(exclusive));
+  }
+  WriteOp& write(uint64_t off, ceph::buffer::list&& bl) &;
+  WriteOp&& write(uint64_t off, ceph::buffer::list&& bl) && {
+    return std::move(write(off, std::move(bl)));
+  }
+  WriteOp& write_full(ceph::buffer::list&& bl) &;
+  WriteOp&& write_full(ceph::buffer::list&& bl) && {
+    return std::move(write_full(std::move(bl)));
+  }
+  WriteOp& writesame(std::uint64_t off, std::uint64_t write_len,
+                    ceph::buffer::list&& bl) &;
+  WriteOp&& writesame(std::uint64_t off, std::uint64_t write_len,
+                     ceph::buffer::list&& bl) && {
+    return std::move(writesame(off, write_len, std::move(bl)));
+  }
+  WriteOp& append(ceph::buffer::list&& bl) &;
+  WriteOp&& append(ceph::buffer::list&& bl) && {
+    return std::move(append(std::move(bl)));
+  }
+  WriteOp& remove() &;
+  WriteOp&& remove() && {
+    return std::move(remove());
+  }
+  WriteOp& truncate(uint64_t off) &;
+  WriteOp&& truncate(uint64_t off) && {
+    return std::move(truncate(off));
+  }
+  WriteOp& zero(uint64_t off, uint64_t len) &;
+  WriteOp&& zero(uint64_t off, uint64_t len) && {
+    return std::move(zero(off, len));
+  }
+  WriteOp& rmxattr(std::string_view name) &;
+  WriteOp&& rmxattr(std::string_view name) && {
+    return std::move(rmxattr(name));
+  }
+  WriteOp& setxattr(std::string_view name,
+                   ceph::buffer::list&& bl) &;
+  WriteOp&& setxattr(std::string_view name,
+                    ceph::buffer::list&& bl) && {
+    return std::move(setxattr(name, std::move(bl)));
+  }
+  WriteOp& rollback(uint64_t snapid) &;
+  WriteOp&& rollback(uint64_t snapid) && {
+    return std::move(rollback(snapid));
+  }
+  WriteOp& set_omap(
+    const boost::container::flat_map<std::string, ceph::buffer::list>& map) &;
+  WriteOp&& set_omap(
+    const boost::container::flat_map<std::string, ceph::buffer::list>& map) && {
+    return std::move(set_omap(map));
+  }
+  WriteOp& set_omap_header(ceph::buffer::list&& bl) &;
+  WriteOp&& set_omap_header(ceph::buffer::list&& bl) && {
+    return std::move(set_omap_header(std::move(bl)));
+  }
+  WriteOp& clear_omap() &;
+  WriteOp&& clear_omap() && {
+    return std::move(clear_omap());
+  }
+  WriteOp& rm_omap_keys(const boost::container::flat_set<std::string>& to_rm) &;
+  WriteOp&& rm_omap_keys(const boost::container::flat_set<std::string>& to_rm) && {
+    return std::move(rm_omap_keys(to_rm));
+  }
+  WriteOp& set_alloc_hint(uint64_t expected_object_size,
+                         uint64_t expected_write_size,
+                         alloc_hint::alloc_hint_t flags) &;
+  WriteOp&& set_alloc_hint(uint64_t expected_object_size,
+                          uint64_t expected_write_size,
+                          alloc_hint::alloc_hint_t flags) && {
+    return std::move(set_alloc_hint(expected_object_size,
+                                   expected_write_size,
+                                   flags));
+  }
+
+  // Chaining versions of functions from Op
+  WriteOp& set_excl() & {
+    Op::set_excl();
+    return *this;
+  }
+  WriteOp&& set_excl() && {
+    Op::set_excl();
+    return std::move(*this);
+  }
+
+  WriteOp& set_failok() & {
+    Op::set_failok();
+    return *this;
+  }
+  WriteOp&& set_failok() && {
+    Op::set_failok();
+    return std::move(*this);
+  }
+
+  WriteOp& set_fadvise_random() & {
+    Op::set_fadvise_random();
+    return *this;
+  }
+  WriteOp&& set_fadvise_random() && {
+    Op::set_fadvise_random();
+    return std::move(*this);
+  }
+
+  WriteOp& set_fadvise_sequential() & {
+    Op::set_fadvise_sequential();
+    return *this;
+  }
+  WriteOp&& set_fadvise_sequential() && {
+    Op::set_fadvise_sequential();
+    return std::move(*this);
+  }
+
+  WriteOp& set_fadvise_willneed() & {
+    Op::set_fadvise_willneed();
+    return *this;
+  }
+  WriteOp&& set_fadvise_willneed() && {
+    Op::set_fadvise_willneed();
+    return std::move(*this);
+  }
+
+  WriteOp& set_fadvise_dontneed() & {
+    Op::set_fadvise_dontneed();
+    return *this;
+  }
+  WriteOp&& set_fadvise_dontneed() && {
+    Op::set_fadvise_dontneed();
+    return std::move(*this);
+  }
+
+  WriteOp& set_fadvise_nocache() & {
+    Op::set_fadvise_nocache();
+    return *this;
+  }
+  WriteOp&& set_fadvise_nocache() && {
+    Op::set_fadvise_nocache();
+    return std::move(*this);
+  }
+
+  WriteOp& cmpext(uint64_t off, ceph::buffer::list&& cmp_bl, std::size_t* s) & {
+    Op::cmpext(off, std::move(cmp_bl), s);
+    return *this;
+  }
+  WriteOp&& cmpext(uint64_t off, ceph::buffer::list&& cmp_bl, std::size_t* s) && {
+    Op::cmpext(off, std::move(cmp_bl), s);
+    return std::move(*this);
+  }
+
+  WriteOp& cmpxattr(std::string_view name, cmpxattr_op op,
+                  const ceph::buffer::list& val) & {
+    Op::cmpxattr(name, op, val);
+    return *this;
+  }
+  WriteOp&& cmpxattr(std::string_view name, cmpxattr_op op,
+                   const ceph::buffer::list& val) && {
+    Op::cmpxattr(name, op, val);
+    return std::move(*this);
+  }
+
+  WriteOp& cmpxattr(std::string_view name, cmpxattr_op op, std::uint64_t val) & {
+    Op::cmpxattr(name, op, val);
+    return *this;
+  }
+  WriteOp&& cmpxattr(std::string_view name, cmpxattr_op op, std::uint64_t val) && {
+    Op::cmpxattr(name, op, val);
+    return std::move(*this);
+  }
+
+  WriteOp& assert_version(uint64_t ver) & {
+    Op::assert_version(ver);
+    return *this;
+  }
+  WriteOp&& assert_version(uint64_t ver) && {
+    Op::assert_version(ver);
+    return std::move(*this);
+  }
+
+  WriteOp& assert_exists() & {
+    Op::assert_exists();
+    return *this;
+  }
+  WriteOp&& assert_exists() && {
+    Op::assert_exists();
+    return std::move(*this);
+  }
+
+  WriteOp& cmp_omap(
+    const boost::container::flat_map<
+      std::string, std::pair<ceph::buffer::list, int>>& assertions) & {
+    Op::cmp_omap(assertions);
+    return *this;
+  }
+  WriteOp&& cmp_omap(
+    const boost::container::flat_map<
+      std::string, std::pair<ceph::buffer::list, int>>& assertions) && {
+    Op::cmp_omap(assertions);
+    return std::move(*this);
+  }
+
+  WriteOp& exec(std::string_view cls, std::string_view method,
+              const ceph::buffer::list& inbl,
+              ceph::buffer::list* out,
+              boost::system::error_code* ec = nullptr) & {
+    Op::exec(cls, method, inbl, out, ec);
+    return *this;
+  }
+  WriteOp&& exec(std::string_view cls, std::string_view method,
+               const ceph::buffer::list& inbl,
+               ceph::buffer::list* out,
+               boost::system::error_code* ec = nullptr) && {
+    Op::exec(cls, method, inbl, out, ec);
+    return std::move(*this);
+  }
+
+  WriteOp& exec(std::string_view cls, std::string_view method,
+              const ceph::buffer::list& inbl,
+              fu2::unique_function<void(boost::system::error_code,
+                                   const ceph::buffer::list&) &&> f) & {
+    Op::exec(cls, method, inbl, std::move(f));
+    return *this;
+  }
+  WriteOp&& exec(std::string_view cls, std::string_view method,
+               const ceph::buffer::list& inbl,
+               fu2::unique_function<void(boost::system::error_code,
+                                    const ceph::buffer::list&) &&> f) && {
+    Op::exec(cls, method, inbl, std::move(f));
+    return std::move(*this);
+  }
+
+  WriteOp& exec(std::string_view cls, std::string_view method,
+              const ceph::buffer::list& inbl,
+              fu2::unique_function<void(boost::system::error_code, int,
+                                        const ceph::buffer::list&) &&> f) & {
+    Op::exec(cls, method, inbl, std::move(f));
+    return *this;
+  }
+  WriteOp&& exec(std::string_view cls, std::string_view method,
+               const ceph::buffer::list& inbl,
+               fu2::unique_function<void(boost::system::error_code, int,
+                                         const ceph::buffer::list&) &&> f) && {
+    Op::exec(cls, method, inbl, std::move(f));
+    return std::move(*this);
+  }
+
+  WriteOp& exec(std::string_view cls, std::string_view method,
+              const ceph::buffer::list& inbl,
+              boost::system::error_code* ec = nullptr) & {
+    Op::exec(cls, method, inbl, ec);
+    return *this;
+  }
+  WriteOp&& exec(std::string_view cls, std::string_view method,
+               const ceph::buffer::list& inbl,
+               boost::system::error_code* ec = nullptr) && {
+    Op::exec(cls, method, inbl, ec);
+    return std::move(*this);
+  }
+
+  template<typename F>
+  WriteOp& exec(ClsOp<F>&& clsop) & {
+    return clsop(*this);
+  }
+  template<typename F>
+  WriteOp&& exec(ClsOp<F>&& clsop) && {
+    return std::move(clsop(*this));
+  }
+  template<typename F>
+  WriteOp& exec(ClsWriteOp<F>&& clsop) & {
+    return clsop(*this);
+  }
+  template<typename F>
+  WriteOp&& exec(ClsWriteOp<F>&& clsop) && {
+    return std::move(clsop(*this));
+  }
+
+
+  // Flags that apply to all ops in the operation vector
+  WriteOp& balance_reads() & {
+    Op::balance_reads();
+    return *this;
+  }
+  WriteOp&& balance_reads() && {
+    Op::balance_reads();
+    return std::move(*this);
+  }
+  WriteOp& localize_reads() & {
+    Op::localize_reads();
+    return *this;
+  }
+  WriteOp&& localize_reads() && {
+    Op::localize_reads();
+    return std::move(*this);
+  }
+  WriteOp& order_reads_writes() & {
+    Op::order_reads_writes();
+    return *this;
+  }
+  WriteOp&& order_reads_writes() && {
+    Op::order_reads_writes();
+    return std::move(*this);
+  }
+  WriteOp& ignore_cache() & {
+    Op::ignore_cache();
+    return *this;
+  }
+  WriteOp&& ignore_cache() && {
+    Op::ignore_cache();
+    return std::move(*this);
+  }
+  WriteOp& skiprwlocks() & {
+    Op::skiprwlocks();
+    return *this;
+  }
+  WriteOp&& skiprwlocks() && {
+    Op::skiprwlocks();
+    return std::move(*this);
+  }
+  WriteOp& ignore_overlay() & {
+    Op::ignore_overlay();
+    return *this;
+  }
+  WriteOp&& ignore_overlay() && {
+    Op::ignore_overlay();
+    return std::move(*this);
+  }
+  WriteOp& full_try() & {
+    Op::full_try();
+    return *this;
+  }
+  WriteOp&& full_try() && {
+    Op::full_try();
+    return std::move(*this);
+  }
+  WriteOp& full_force() & {
+    Op::full_force();
+    return *this;
+  }
+  WriteOp&& full_force() && {
+    Op::full_force();
+    return std::move(*this);
+  }
+  WriteOp& ignore_redirect() & {
+    Op::ignore_redirect();
+    return *this;
+  }
+  WriteOp&& ignore_redirect() && {
+    Op::ignore_redirect();
+    return std::move(*this);
+  }
+  WriteOp& ordersnap() & {
+    Op::ordersnap();
+    return *this;
+  }
+  WriteOp&& ordersnap() && {
+    Op::ordersnap();
+    return std::move(*this);
+  }
+  WriteOp& returnvec() & {
+    Op::returnvec();
+    return *this;
+  }
+  WriteOp&& returnvec() && {
+    Op::returnvec();
+    return std::move(*this);
+  }
 };
 
 
index 1a7c5cd37db3cbd7d61242ce0c8a02606d0efac7..026f77043dc97b77474fb76b950a8450143a5d9b 100644 (file)
@@ -523,149 +523,173 @@ std::ostream& operator <<(std::ostream& m, const Op& o) {
 
 // ReadOp / WriteOp
 
-void ReadOp::read(size_t off, uint64_t len, cb::list* out,
-                 bs::error_code* ec) {
+ReadOp& ReadOp::read(size_t off, uint64_t len, cb::list* out,
+                     bs::error_code* ec) & {
   reinterpret_cast<OpImpl*>(&impl)->op.read(off, len, ec, out);
+  return *this;
 }
 
-void ReadOp::get_xattr(std::string_view name, cb::list* out,
-                      bs::error_code* ec) {
+ReadOp& ReadOp::get_xattr(std::string_view name, cb::list* out,
+                         bs::error_code* ec) & {
   reinterpret_cast<OpImpl*>(&impl)->op.getxattr(name, ec, out);
+  return *this;
 }
 
-void ReadOp::get_omap_header(cb::list* out,
-                            bs::error_code* ec) {
+ReadOp& ReadOp::get_omap_header(cb::list* out,
+                               bs::error_code* ec) & {
   reinterpret_cast<OpImpl*>(&impl)->op.omap_get_header(ec, out);
+  return *this;
 }
 
-void ReadOp::sparse_read(uint64_t off, uint64_t len, cb::list* out,
-                        std::vector<std::pair<std::uint64_t,
-                        std::uint64_t>>* extents,
-                        bs::error_code* ec) {
+ReadOp& ReadOp::sparse_read(uint64_t off, uint64_t len, cb::list* out,
+                           std::vector<std::pair<std::uint64_t,
+                           std::uint64_t>>* extents,
+                           bs::error_code* ec) & {
   reinterpret_cast<OpImpl*>(&impl)->op.sparse_read(off, len, ec, extents, out);
+  return *this;
 }
 
-void ReadOp::stat(std::uint64_t* size, ceph::real_time* mtime,
-                 bs::error_code* ec) {
+ReadOp& ReadOp::stat(std::uint64_t* size, ceph::real_time* mtime,
+                    bs::error_code* ec) & {
   reinterpret_cast<OpImpl*>(&impl)->op.stat(size, mtime, ec);
+  return *this;
 }
 
-void ReadOp::get_omap_keys(std::optional<std::string_view> start_after,
-                          std::uint64_t max_return,
-                          bc::flat_set<std::string>* keys,
-                          bool* done,
-                          bs::error_code* ec) {
+ReadOp& ReadOp::get_omap_keys(std::optional<std::string_view> start_after,
+                             std::uint64_t max_return,
+                             bc::flat_set<std::string>* keys,
+                             bool* done,
+                             bs::error_code* ec) & {
   reinterpret_cast<OpImpl*>(&impl)->op.omap_get_keys(start_after, max_return,
                                                     ec, keys, done);
+  return *this;
 }
 
-void ReadOp::get_xattrs(bc::flat_map<std::string,
-                       cb::list>* kv,
-                       bs::error_code* ec) {
+ReadOp& ReadOp::get_xattrs(bc::flat_map<std::string, cb::list>* kv,
+                          bs::error_code* ec) & {
   reinterpret_cast<OpImpl*>(&impl)->op.getxattrs(ec, kv);
+  return *this;
 }
 
-void ReadOp::get_omap_vals(std::optional<std::string_view> start_after,
-                          std::optional<std::string_view> filter_prefix,
-                          uint64_t max_return,
-                          bc::flat_map<std::string,
-                          cb::list>* kv,
-                          bool* done,
-                          bs::error_code* ec) {
+ReadOp& ReadOp::get_omap_vals(std::optional<std::string_view> start_after,
+                             std::optional<std::string_view> filter_prefix,
+                             uint64_t max_return,
+                             bc::flat_map<std::string, cb::list>* kv,
+                             bool* done,
+                             bs::error_code* ec) & {
   reinterpret_cast<OpImpl*>(&impl)->op.omap_get_vals(start_after, filter_prefix,
                                                     max_return, ec, kv, done);
+  return *this;
 }
 
-void ReadOp::get_omap_vals_by_keys(
+ReadOp& ReadOp::get_omap_vals_by_keys(
   const bc::flat_set<std::string>& keys,
   bc::flat_map<std::string, cb::list>* kv,
-  bs::error_code* ec) {
+  bs::error_code* ec) {
   reinterpret_cast<OpImpl*>(&impl)->op.omap_get_vals_by_keys(keys, ec, kv);
+  return *this;
 }
 
-void ReadOp::list_watchers(std::vector<ObjWatcher>* watchers,
-                          bs::error_code* ec) {
+ReadOp& ReadOp::list_watchers(std::vector<ObjWatcher>* watchers,
+                             bs::error_code* ec) & {
   reinterpret_cast<OpImpl*>(&impl)-> op.list_watchers(watchers, ec);
+  return *this;
 }
 
-void ReadOp::list_snaps(SnapSet* snaps,
-                       bs::error_code* ec) {
+ReadOp& ReadOp::list_snaps(SnapSet* snaps,
+                          bs::error_code* ec) & {
   reinterpret_cast<OpImpl*>(&impl)->op.list_snaps(snaps, nullptr, ec);
+  return *this;
 }
 
 // WriteOp
 
-void WriteOp::set_mtime(ceph::real_time t) {
+WriteOp& WriteOp::set_mtime(ceph::real_time t) & {
   auto o = reinterpret_cast<OpImpl*>(&impl);
   o->mtime = t;
+  return *this;
 }
 
-void WriteOp::create(bool exclusive) {
+WriteOp& WriteOp::create(bool exclusive) & {
   reinterpret_cast<OpImpl*>(&impl)->op.create(exclusive);
+  return *this;
 }
 
-void WriteOp::write(uint64_t off, bufferlist&& bl) {
+WriteOp& WriteOp::write(uint64_t off, bufferlist&& bl) & {
   reinterpret_cast<OpImpl*>(&impl)->op.write(off, bl);
+  return *this;
 }
 
-void WriteOp::write_full(bufferlist&& bl) {
+WriteOp& WriteOp::write_full(bufferlist&& bl) & {
   reinterpret_cast<OpImpl*>(&impl)->op.write_full(bl);
+  return *this;
 }
 
-void WriteOp::writesame(uint64_t off, uint64_t write_len, bufferlist&& bl) {
+WriteOp& WriteOp::writesame(uint64_t off, uint64_t write_len, bufferlist&& bl) & {
   reinterpret_cast<OpImpl*>(&impl)->op.writesame(off, write_len, bl);
+  return *this;
 }
 
-void WriteOp::append(bufferlist&& bl) {
+WriteOp& WriteOp::append(bufferlist&& bl) & {
   reinterpret_cast<OpImpl*>(&impl)->op.append(bl);
+  return *this;
 }
 
-void WriteOp::remove() {
+WriteOp& WriteOp::remove() & {
   reinterpret_cast<OpImpl*>(&impl)->op.remove();
+  return *this;
 }
 
-void WriteOp::truncate(uint64_t off) {
+WriteOp& WriteOp::truncate(uint64_t off) & {
   reinterpret_cast<OpImpl*>(&impl)->op.truncate(off);
+  return *this;
 }
 
-void WriteOp::zero(uint64_t off, uint64_t len) {
+WriteOp& WriteOp::zero(uint64_t off, uint64_t len) & {
   reinterpret_cast<OpImpl*>(&impl)->op.zero(off, len);
+  return *this;
 }
 
-void WriteOp::rmxattr(std::string_view name) {
+WriteOp& WriteOp::rmxattr(std::string_view name) & {
   reinterpret_cast<OpImpl*>(&impl)->op.rmxattr(name);
+  return *this;
 }
 
-void WriteOp::setxattr(std::string_view name,
-                       bufferlist&& bl) {
+WriteOp& WriteOp::setxattr(std::string_view name,
+                          bufferlist&& bl) & {
   reinterpret_cast<OpImpl*>(&impl)->op.setxattr(name, bl);
+  return *this;
 }
 
-void WriteOp::rollback(uint64_t snapid) {
+WriteOp& WriteOp::rollback(uint64_t snapid) & {
   reinterpret_cast<OpImpl*>(&impl)->op.rollback(snapid);
+  return *this;
 }
 
-void WriteOp::set_omap(
-  const bc::flat_map<std::string, cb::list>& map) {
+WriteOp& WriteOp::set_omap(
+  const bc::flat_map<std::string, cb::list>& map) {
   reinterpret_cast<OpImpl*>(&impl)->op.omap_set(map);
+  return *this;
 }
 
-void WriteOp::set_omap_header(bufferlist&& bl) {
+WriteOp& WriteOp::set_omap_header(bufferlist&& bl) & {
   reinterpret_cast<OpImpl*>(&impl)->op.omap_set_header(bl);
+  return *this;
 }
 
-void WriteOp::clear_omap() {
+WriteOp& WriteOp::clear_omap() & {
   reinterpret_cast<OpImpl*>(&impl)->op.omap_clear();
+  return *this;
 }
 
-void WriteOp::rm_omap_keys(
-  const bc::flat_set<std::string>& to_rm) {
+WriteOp& WriteOp::rm_omap_keys(const bc::flat_set<std::string>& to_rm) & {
   reinterpret_cast<OpImpl*>(&impl)->op.omap_rm_keys(to_rm);
+  return *this;
 }
 
-void WriteOp::set_alloc_hint(uint64_t expected_object_size,
-                            uint64_t expected_write_size,
-                            alloc_hint::alloc_hint_t flags) {
+WriteOp& WriteOp::set_alloc_hint(uint64_t expected_object_size,
+                                uint64_t expected_write_size,
+                                alloc_hint::alloc_hint_t flags) & {
   using namespace alloc_hint;
   static_assert(sequential_write ==
                static_cast<int>(CEPH_OSD_ALLOC_HINT_FLAG_SEQUENTIAL_WRITE));
@@ -691,6 +715,7 @@ void WriteOp::set_alloc_hint(uint64_t expected_object_size,
   reinterpret_cast<OpImpl*>(&impl)->op.set_alloc_hint(expected_object_size,
                                                      expected_write_size,
                                                      flags);
+  return *this;
 }
 
 // RADOS
index e6a87c1617b510c64ee7babfd6e31d98f2d5477b..8e2a864f9b892523b9bd3502bbc1abe60c16c560 100644 (file)
@@ -411,8 +411,8 @@ void Op::exec(std::string_view cls, std::string_view method,
   o->ops.push_back(op);
 }
 
-void ReadOp::read(size_t off, uint64_t len, ceph::buffer::list* out,
-                 boost::system::error_code* ec) {
+ReadOp& ReadOp::read(size_t off, uint64_t len, ceph::buffer::list* out,
+                    boost::system::error_code* ec) & {
   auto o = *reinterpret_cast<librados::TestObjectOperationImpl**>(&impl);
   librados::ObjectOperationTestImpl op;
   if (out != nullptr) {
@@ -428,13 +428,14 @@ void ReadOp::read(size_t off, uint64_t len, ceph::buffer::list* out,
       save_operation_ec, std::bind(op, _1, _2, _3, _4, _5, _6), ec);
   }
   o->ops.push_back(op);
+  return *this;
 }
 
-void ReadOp::sparse_read(uint64_t off, uint64_t len,
-                        ceph::buffer::list* out,
-                        std::vector<std::pair<std::uint64_t,
-                                               std::uint64_t>>* extents,
-                        boost::system::error_code* ec) {
+ReadOp& ReadOp::sparse_read(uint64_t off, uint64_t len,
+                           ceph::buffer::list* out,
+                           std::vector<std::pair<std::uint64_t,
+                                                  std::uint64_t>>* extents,
+                           boost::system::error_code* ec) & {
   auto o = *reinterpret_cast<librados::TestObjectOperationImpl**>(&impl);
   librados::ObjectOperationTestImpl op =
     [off, len, out, extents]
@@ -454,9 +455,10 @@ void ReadOp::sparse_read(uint64_t off, uint64_t len,
                      std::bind(op, _1, _2, _3, _4, _5, _6), ec);
   }
   o->ops.push_back(op);
+  return *this;
 }
 
-void ReadOp::list_snaps(SnapSet* snaps, bs::error_code* ec) {
+ReadOp& ReadOp::list_snaps(SnapSet* snaps, bs::error_code* ec) & {
   auto o = *reinterpret_cast<librados::TestObjectOperationImpl**>(&impl);
   librados::ObjectOperationTestImpl op =
     [snaps]
@@ -484,55 +486,64 @@ void ReadOp::list_snaps(SnapSet* snaps, bs::error_code* ec) {
                    std::bind(op, _1, _2, _3, _4, _5, _6), ec);
   }
   o->ops.push_back(op);
+  return *this;
 }
 
-void WriteOp::create(bool exclusive) {
+WriteOp& WriteOp::create(bool exclusive) & {
   auto o = *reinterpret_cast<librados::TestObjectOperationImpl**>(&impl);
   o->ops.push_back(std::bind(
     &librados::TestIoCtxImpl::create, _1, _2, exclusive, _5));
+  return *this;
 }
 
-void WriteOp::write(uint64_t off, ceph::buffer::list&& bl) {
+WriteOp& WriteOp::write(uint64_t off, ceph::buffer::list&& bl) & {
   auto o = *reinterpret_cast<librados::TestObjectOperationImpl**>(&impl);
   o->ops.push_back(std::bind(
     &librados::TestIoCtxImpl::write, _1, _2, bl, bl.length(), off, _5));
+  return *this;
 }
 
-void WriteOp::write_full(ceph::buffer::list&& bl) {
+WriteOp& WriteOp::write_full(ceph::buffer::list&& bl) & {
   auto o = *reinterpret_cast<librados::TestObjectOperationImpl**>(&impl);
   o->ops.push_back(std::bind(
     &librados::TestIoCtxImpl::write_full, _1, _2, bl, _5));
+  return *this;
 }
 
-void WriteOp::remove() {
+WriteOp& WriteOp::remove() & {
   auto o = *reinterpret_cast<librados::TestObjectOperationImpl**>(&impl);
   o->ops.push_back(std::bind(
     &librados::TestIoCtxImpl::remove, _1, _2, _5));
+  return *this;
 }
 
-void WriteOp::truncate(uint64_t off) {
+WriteOp& WriteOp::truncate(uint64_t off) & {
   auto o = *reinterpret_cast<librados::TestObjectOperationImpl**>(&impl);
   o->ops.push_back(std::bind(
     &librados::TestIoCtxImpl::truncate, _1, _2, off, _5));
+  return *this;
 }
 
-void WriteOp::zero(uint64_t off, uint64_t len) {
+WriteOp& WriteOp::zero(uint64_t off, uint64_t len) & {
   auto o = *reinterpret_cast<librados::TestObjectOperationImpl**>(&impl);
   o->ops.push_back(std::bind(
     &librados::TestIoCtxImpl::zero, _1, _2, off, len, _5));
+  return *this;
 }
 
-void WriteOp::writesame(std::uint64_t off, std::uint64_t write_len,
-                        ceph::buffer::list&& bl) {
+WriteOp& WriteOp::writesame(std::uint64_t off, std::uint64_t write_len,
+                           ceph::buffer::list&& bl) & {
   auto o = *reinterpret_cast<librados::TestObjectOperationImpl**>(&impl);
   o->ops.push_back(std::bind(
     &librados::TestIoCtxImpl::writesame, _1, _2, bl, write_len, off, _5));
+  return *this;
 }
 
-void WriteOp::set_alloc_hint(uint64_t expected_object_size,
-                            uint64_t expected_write_size,
-                            alloc_hint::alloc_hint_t flags) {
+WriteOp& WriteOp::set_alloc_hint(uint64_t expected_object_size,
+                                uint64_t expected_write_size,
+                                alloc_hint::alloc_hint_t flags) & {
   // no-op
+  return *this;
 }
 
 RADOS::RADOS() = default;