File indexing completed on 2025-01-18 10:10:37
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef ROOT7_RDaos
0017 #define ROOT7_RDaos
0018
0019 #include <string_view>
0020 #include <ROOT/TypeTraits.hxx>
0021 #include <ROOT/RSpan.hxx>
0022
0023 #include <daos.h>
0024
0025 #include <cstdint>
0026 #include <functional>
0027 #include <memory>
0028 #include <string>
0029 #include <type_traits>
0030 #include <vector>
0031 #include <optional>
0032 #include <unordered_map>
0033
0034 #ifndef DAOS_UUID_STR_SIZE
0035 #define DAOS_UUID_STR_SIZE 37
0036 #endif
0037
0038 namespace ROOT {
0039
0040 namespace Experimental {
0041 namespace Internal {
0042
0043 struct RDaosEventQueue {
0044 daos_handle_t fQueue;
0045 RDaosEventQueue();
0046 ~RDaosEventQueue();
0047
0048
0049
0050
0051 static int WaitOnParentBarrier(daos_event_t *ev_ptr);
0052
0053
0054 int InitializeEvent(daos_event_t *ev_ptr, daos_event_t *parent_ptr = nullptr) const;
0055
0056
0057 static int FinalizeEvent(daos_event_t *ev_ptr);
0058 };
0059
0060 class RDaosContainer;
0061
0062
0063
0064
0065
0066 class RDaosPool {
0067 friend class RDaosContainer;
0068 private:
0069 daos_handle_t fPoolHandle{};
0070 uuid_t fPoolUuid{};
0071 std::string fPoolLabel{};
0072 std::unique_ptr<RDaosEventQueue> fEventQueue;
0073
0074 public:
0075 RDaosPool(const RDaosPool&) = delete;
0076 RDaosPool(std::string_view poolId);
0077 ~RDaosPool();
0078
0079 RDaosPool& operator=(const RDaosPool&) = delete;
0080 std::string GetPoolUuid();
0081 };
0082
0083
0084
0085
0086
0087 class RDaosObject {
0088 private:
0089 daos_handle_t fObjectHandle;
0090 public:
0091 using DistributionKey_t = std::uint64_t;
0092 using AttributeKey_t = std::uint64_t;
0093
0094
0095 struct ObjClassId {
0096 daos_oclass_id_t fCid;
0097
0098 ObjClassId(daos_oclass_id_t cid) : fCid(cid) {}
0099 ObjClassId(const std::string &name) : fCid(daos_oclass_name2id(name.data())) {}
0100
0101 bool IsUnknown() const { return fCid == OC_UNKNOWN; }
0102 std::string ToString() const;
0103
0104
0105
0106
0107
0108 static constexpr std::size_t kOCNameMaxLength = 64;
0109 };
0110
0111
0112 struct RAkeyRequest {
0113 AttributeKey_t fAkey{};
0114 std::vector<d_iov_t> fIovs{};
0115
0116 RAkeyRequest(const AttributeKey_t a, const std::vector<d_iov_t> &iovs) : fAkey(a), fIovs(iovs){};
0117 RAkeyRequest(const AttributeKey_t a, std::vector<d_iov_t> &&iovs) : fAkey(a), fIovs(std::move(iovs)){};
0118 };
0119
0120
0121 struct FetchUpdateArgs {
0122 FetchUpdateArgs() = default;
0123 FetchUpdateArgs(const FetchUpdateArgs &) = delete;
0124 FetchUpdateArgs(FetchUpdateArgs &&fua) noexcept;
0125 FetchUpdateArgs(DistributionKey_t d, std::span<RAkeyRequest> rs, bool is_async = false);
0126 FetchUpdateArgs &operator=(const FetchUpdateArgs &) = delete;
0127 daos_event_t *GetEventPointer();
0128
0129
0130
0131 DistributionKey_t fDkey{};
0132
0133
0134 std::span<RAkeyRequest> fRequests{};
0135
0136
0137 daos_key_t fDistributionKey{};
0138 std::vector<daos_iod_t> fIods{};
0139 std::vector<d_sg_list_t> fSgls{};
0140 std::optional<daos_event_t> fEvent{};
0141 };
0142
0143 RDaosObject() = delete;
0144
0145
0146 RDaosObject(RDaosContainer &container, daos_obj_id_t oid, ObjClassId cid = OC_UNKNOWN);
0147 ~RDaosObject();
0148
0149 int Fetch(FetchUpdateArgs &args);
0150 int Update(FetchUpdateArgs &args);
0151 };
0152
0153
0154
0155
0156
0157 class RDaosContainer {
0158 friend class RDaosObject;
0159 public:
0160 using DistributionKey_t = RDaosObject::DistributionKey_t;
0161 using AttributeKey_t = RDaosObject::AttributeKey_t;
0162 using ObjClassId_t = RDaosObject::ObjClassId;
0163
0164
0165
0166 struct ROidDkeyPair {
0167 daos_obj_id_t oid{};
0168 DistributionKey_t dkey{};
0169
0170 inline bool operator==(const ROidDkeyPair &other) const
0171 {
0172 return this->oid.lo == other.oid.lo && this->oid.hi == other.oid.hi && this->dkey == other.dkey;
0173 }
0174
0175 struct Hash {
0176 auto operator()(const ROidDkeyPair &x) const
0177 {
0178
0179
0180 auto seed = std::hash<uint64_t>{}(x.oid.hi);
0181 seed ^= std::hash<uint64_t>{}(x.oid.lo) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
0182 seed ^= std::hash<DistributionKey_t>{}(x.dkey) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
0183 return seed;
0184 }
0185 };
0186 };
0187
0188
0189
0190 struct RWOperation {
0191 RWOperation() = default;
0192 RWOperation(daos_obj_id_t o, DistributionKey_t d, std::vector<RDaosObject::RAkeyRequest> &&rs)
0193 : fOid(o), fDistributionKey(d), fDataRequests(std::move(rs))
0194 {
0195 for (unsigned i = 0; i < fDataRequests.size(); i++)
0196 fIndices.emplace(fDataRequests[i].fAkey, i);
0197 };
0198 explicit RWOperation(ROidDkeyPair &k) : fOid(k.oid), fDistributionKey(k.dkey){};
0199 daos_obj_id_t fOid{};
0200 DistributionKey_t fDistributionKey{};
0201 std::vector<RDaosObject::RAkeyRequest> fDataRequests{};
0202 std::unordered_map<AttributeKey_t, unsigned> fIndices{};
0203
0204 void Insert(AttributeKey_t attr, const d_iov_t &iov)
0205 {
0206 auto [it, ret] = fIndices.emplace(attr, fDataRequests.size());
0207 unsigned attrIndex = it->second;
0208
0209 if (attrIndex == fDataRequests.size()) {
0210 fDataRequests.emplace_back(attr, std::initializer_list<d_iov_t>{iov});
0211 } else {
0212 fDataRequests[attrIndex].fIovs.emplace_back(iov);
0213 }
0214 }
0215
0216 void Insert(AttributeKey_t attr, std::vector<d_iov_t> &iovs)
0217 {
0218 auto [it, ret] = fIndices.emplace(attr, fDataRequests.size());
0219 unsigned attrIndex = it->second;
0220
0221 if (attrIndex == fDataRequests.size()) {
0222 fDataRequests.emplace_back(attr, iovs);
0223 } else {
0224 fDataRequests[attrIndex].fIovs.insert(std::end(fDataRequests[attrIndex].fIovs),
0225 std::make_move_iterator(std::begin(iovs)),
0226 std::make_move_iterator(std::end(iovs)));
0227 }
0228 }
0229 };
0230
0231 using MultiObjectRWOperation_t = std::unordered_map<ROidDkeyPair, RWOperation, ROidDkeyPair::Hash>;
0232
0233 std::string GetContainerUuid();
0234
0235 private:
0236 daos_handle_t fContainerHandle{};
0237 uuid_t fContainerUuid{};
0238 std::string fContainerLabel{};
0239 std::shared_ptr<RDaosPool> fPool;
0240 ObjClassId_t fDefaultObjectClass{OC_SX};
0241
0242
0243
0244
0245
0246
0247
0248
0249 int VectorReadWrite(MultiObjectRWOperation_t &map, ObjClassId_t cid,
0250 int (RDaosObject::*fn)(RDaosObject::FetchUpdateArgs &));
0251
0252 public:
0253 RDaosContainer(std::shared_ptr<RDaosPool> pool, std::string_view containerId, bool create = false);
0254 ~RDaosContainer();
0255
0256 ObjClassId_t GetDefaultObjectClass() const { return fDefaultObjectClass; }
0257 void SetDefaultObjectClass(const ObjClassId_t cid) { fDefaultObjectClass = cid; }
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269 int ReadSingleAkey(void *buffer, std::size_t length, daos_obj_id_t oid,
0270 DistributionKey_t dkey, AttributeKey_t akey, ObjClassId_t cid);
0271 int ReadSingleAkey(void *buffer, std::size_t length, daos_obj_id_t oid,
0272 DistributionKey_t dkey, AttributeKey_t akey)
0273 { return ReadSingleAkey(buffer, length, oid, dkey, akey, fDefaultObjectClass); }
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285 int WriteSingleAkey(const void *buffer, std::size_t length, daos_obj_id_t oid,
0286 DistributionKey_t dkey, AttributeKey_t akey, ObjClassId_t cid);
0287 int WriteSingleAkey(const void *buffer, std::size_t length, daos_obj_id_t oid,
0288 DistributionKey_t dkey, AttributeKey_t akey)
0289 { return WriteSingleAkey(buffer, length, oid, dkey, akey, fDefaultObjectClass); }
0290
0291
0292
0293
0294
0295
0296
0297 int ReadV(MultiObjectRWOperation_t &map, ObjClassId_t cid) { return VectorReadWrite(map, cid, &RDaosObject::Fetch); }
0298 int ReadV(MultiObjectRWOperation_t &map) { return ReadV(map, fDefaultObjectClass); }
0299
0300
0301
0302
0303
0304
0305
0306 int WriteV(MultiObjectRWOperation_t &map, ObjClassId_t cid)
0307 {
0308 return VectorReadWrite(map, cid, &RDaosObject::Update);
0309 }
0310 int WriteV(MultiObjectRWOperation_t &map) { return WriteV(map, fDefaultObjectClass); }
0311 };
0312
0313 }
0314
0315 }
0316 }
0317
0318 #endif