sal is overloaded. sal::Bucket
/Object
act as:
- backend storage interfaces,
- handles to generic state, and
- names
early in request processing, we construct s->object
and s->bucket
with just their names, leaving other state uninitialized until later.
there's no explicit way to know whether a handle is initialized yet.
struct rgw_bucket_key
and rgw_obj_key
should be used instead to represent the names
the generic state in sal::StoreBucket
/StoreObject
could be separated from sal entirely
namespace rgw::sal {
// Driver interface is flat. move Bucket/Object functions into Driver
class Driver;
// standalone classes for Object::ReadOp etc (they need to preserve backend state over multiple calls)
class ObjectRead;
class ObjectWrite;
} // namespace rgw::sal
namespace rgw {
// Bucket class in namespace rgw to store the generic state that's currently in sal::StoreBucket
// because it's separated from the sal interface, it can be a non-virtual, moveable/copyable value type
class Bucket {
public:
// explicit uninitialized state. other member functions have precondition: !empty()
bool empty() const;
operator bool() const;
// const and non-const accessors
rgw_bucket_key& key();
RGWBucketInfo& info();
Attrs& attrs();
RGWObjVersionTracker& objv();
// ...
};
auto load_bucket(sal::Driver, rgw_bucket_key)
-> expected<Bucket, int>; // either returns an error or a fully-initialized Bucket
// no Object class? maybe use sal::ObjectRead/ObjectWrite directly
} // namespace rgw
struct req_state {
rgw_bucket_key bucket_key;
rgw_obj_key object_key;
rgw::Bucket bucket; // empty until initialized somewhere like rgw_build_bucket_policies()
};