Logo ROOT  
Reference Guide
Loading...
Searching...
No Matches
RDaos.hxx
Go to the documentation of this file.
1/// \file ROOT/RDaos.hxx
2/// \author Javier Lopez-Gomez <j.lopez@cern.ch>
3/// \date 2020-11-14
4/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
5/// is welcome!
6
7/*************************************************************************
8 * Copyright (C) 1995-2021, Rene Brun and Fons Rademakers. *
9 * All rights reserved. *
10 * *
11 * For the licensing terms see $ROOTSYS/LICENSE. *
12 * For the list of contributors see $ROOTSYS/README/CREDITS. *
13 *************************************************************************/
14
15#ifndef ROOT_RDaos
16#define ROOT_RDaos
17
18#include <string_view>
19#include <ROOT/TypeTraits.hxx>
20#include <ROOT/RSpan.hxx>
21
22#include <daos.h>
23
24#include <cstdint>
25#include <functional>
26#include <memory>
27#include <string>
28#include <type_traits>
29#include <vector>
30#include <optional>
31#include <unordered_map>
32
33#ifndef DAOS_UUID_STR_SIZE
34#define DAOS_UUID_STR_SIZE 37
35#endif
36
37namespace ROOT {
38
39namespace Experimental {
40namespace Internal {
41
46
47 /// \brief Sets event barrier for a given parent event and waits for the completion of all children launched before
48 /// the barrier (must have at least one child).
49 /// \return 0 on success; a DAOS error code otherwise (< 0).
50 static int WaitOnParentBarrier(daos_event_t *ev_ptr);
51 /// \brief Reserve event in queue, optionally tied to a parent event.
52 /// \return 0 on success; a DAOS error code otherwise (< 0).
53 int InitializeEvent(daos_event_t *ev_ptr, daos_event_t *parent_ptr = nullptr) const;
54 /// \brief Release event data from queue.
55 /// \return 0 on success; a DAOS error code otherwise (< 0).
56 static int FinalizeEvent(daos_event_t *ev_ptr);
57};
58
59class RDaosContainer;
60
61/**
62 \class RDaosPool
63 \brief A RDaosPool provides access to containers in a specific DAOS pool.
64 */
65class RDaosPool {
66 friend class RDaosContainer;
67private:
69 uuid_t fPoolUuid{};
70 std::string fPoolLabel{};
71 std::unique_ptr<RDaosEventQueue> fEventQueue;
72
73public:
74 RDaosPool(const RDaosPool&) = delete;
75 RDaosPool(std::string_view poolId);
76 ~RDaosPool();
77
78 RDaosPool& operator=(const RDaosPool&) = delete;
79 std::string GetPoolUuid();
80};
81
82/**
83 \class RDaosObject
84 \brief Provides low-level access to DAOS objects in a container.
85 */
87private:
89public:
90 using DistributionKey_t = std::uint64_t;
91 using AttributeKey_t = std::uint64_t;
92 /// \brief Wrap around a `daos_oclass_id_t`. An object class describes the schema of data distribution
93 /// and protection.
94 struct ObjClassId {
96
98 ObjClassId(const std::string &name) : fCid(daos_oclass_name2id(name.data())) {}
99
100 bool IsUnknown() const { return fCid == OC_UNKNOWN; }
101 std::string ToString() const;
102
103 /// This limit is currently not defined in any header and any call to
104 /// `daos_oclass_id2name()` within DAOS uses a stack-allocated buffer
105 /// whose length varies from 16 to 50, e.g. `https://github.com/daos-stack/daos/blob/master/src/utils/daos_dfs_hdlr.c#L78`.
106 /// As discussed with the development team, 64 is a reasonable limit.
107 static constexpr std::size_t kOCNameMaxLength = 64;
108 };
109
110 /// \brief Contains an attribute key and the associated IOVs for a single scatter-gather I/O request.
113 std::vector<d_iov_t> fIovs{};
114
115 RAkeyRequest(const AttributeKey_t a, const std::vector<d_iov_t> &iovs) : fAkey(a), fIovs(iovs){};
116 RAkeyRequest(const AttributeKey_t a, std::vector<d_iov_t> &&iovs) : fAkey(a), fIovs(std::move(iovs)){};
117 };
118
119 /// \brief Contains required information for a single fetch/update operation.
121 FetchUpdateArgs() = default;
123 FetchUpdateArgs(FetchUpdateArgs &&fua) noexcept;
124 FetchUpdateArgs(DistributionKey_t d, std::span<RAkeyRequest> rs, bool is_async = false);
127
128 /// \brief A `daos_key_t` is a type alias of `d_iov_t`. This type stores a pointer and a length.
129 /// In order for `fDistributionKey` to point to memory that we own, `fDkey` holds the distribution key.
131 /// \brief `fRequests` is a sequential container assumed to remain valid throughout the fetch/update operation,
132 /// holding a list of `RAkeyRequest`-typed elements.
133 std::span<RAkeyRequest> fRequests{};
134
135 /// \brief The distribution key, as used by the `daos_obj_{fetch,update}` functions.
137 std::vector<daos_iod_t> fIods{};
138 std::vector<d_sg_list_t> fSgls{};
139 std::optional<daos_event_t> fEvent{};
140 };
141
142 RDaosObject() = delete;
143 /// Provides low-level access to an object. If `cid` is OC_UNKNOWN, the user is responsible for
144 /// calling `daos_obj_generate_oid()` to fill the reserved bits in `oid` before calling this constructor.
146 ~RDaosObject();
147
148 int Fetch(FetchUpdateArgs &args);
149 int Update(FetchUpdateArgs &args);
150};
151
152/**
153 \class RDaosContainer
154 \brief A RDaosContainer provides read/write access to objects in a given container.
155 */
157 friend class RDaosObject;
158public:
162
163 /// \brief A pair of <object ID, distribution key> that can be used to issue a fetch/update request for multiple
164 /// attribute keys.
168
169 inline bool operator==(const ROidDkeyPair &other) const
170 {
171 return this->oid.lo == other.oid.lo && this->oid.hi == other.oid.hi && this->dkey == other.dkey;
172 }
173
174 struct Hash {
175 auto operator()(const ROidDkeyPair &x) const
176 {
177 /// Implementation borrowed from `boost::hash_combine`. Comparable to initial seeding with `oid.hi` followed
178 /// by two subsequent hash calls for `oid.lo` and `dkey`.
179 auto seed = std::hash<uint64_t>{}(x.oid.hi);
180 seed ^= std::hash<uint64_t>{}(x.oid.lo) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
181 seed ^= std::hash<DistributionKey_t>{}(x.dkey) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
182 return seed;
183 }
184 };
185 };
186
187 /// \brief Describes a read/write operation on multiple attribute keys under the same object ID and distribution key,
188 /// see the `ReadV`/`WriteV` functions.
189 struct RWOperation {
190 RWOperation() = default;
191 RWOperation(daos_obj_id_t o, DistributionKey_t d, std::vector<RDaosObject::RAkeyRequest> &&rs)
192 : fOid(o), fDistributionKey(d), fDataRequests(std::move(rs))
193 {
194 for (unsigned i = 0; i < fDataRequests.size(); i++)
195 fIndices.emplace(fDataRequests[i].fAkey, i);
196 };
197 explicit RWOperation(ROidDkeyPair &k) : fOid(k.oid), fDistributionKey(k.dkey){};
200 std::vector<RDaosObject::RAkeyRequest> fDataRequests{};
201 std::unordered_map<AttributeKey_t, unsigned> fIndices{};
202
203 void Insert(AttributeKey_t attr, const d_iov_t &iov)
204 {
205 auto [it, ret] = fIndices.emplace(attr, fDataRequests.size());
206 unsigned attrIndex = it->second;
207
208 if (attrIndex == fDataRequests.size()) {
209 fDataRequests.emplace_back(attr, std::initializer_list<d_iov_t>{iov});
210 } else {
211 fDataRequests[attrIndex].fIovs.emplace_back(iov);
212 }
213 }
214
215 void Insert(AttributeKey_t attr, std::vector<d_iov_t> &iovs)
216 {
217 auto [it, ret] = fIndices.emplace(attr, fDataRequests.size());
218 unsigned attrIndex = it->second;
219
220 if (attrIndex == fDataRequests.size()) {
221 fDataRequests.emplace_back(attr, iovs);
222 } else {
223 fDataRequests[attrIndex].fIovs.insert(std::end(fDataRequests[attrIndex].fIovs),
224 std::make_move_iterator(std::begin(iovs)),
225 std::make_move_iterator(std::end(iovs)));
226 }
227 }
228 };
229
230 using MultiObjectRWOperation_t = std::unordered_map<ROidDkeyPair, RWOperation, ROidDkeyPair::Hash>;
231
232 std::string GetContainerUuid();
233
234private:
237 std::string fContainerLabel{};
238 std::shared_ptr<RDaosPool> fPool;
240
241 /**
242 \brief Perform a vector read/write operation on different objects.
243 \param map A `MultiObjectRWOperation_t` that describes read/write operations to perform.
244 \param cid The `daos_oclass_id_t` used to qualify OIDs.
245 \param fn Either `&RDaosObject::Fetch` (read) or `&RDaosObject::Update` (write).
246 \return 0 if the operation succeeded; a negative DAOS error number otherwise.
247 */
250
251public:
252 RDaosContainer(std::shared_ptr<RDaosPool> pool, std::string_view containerId, bool create = false);
254
257
258 /**
259 \brief Read data from a single object attribute key to the given buffer.
260 \param buffer The address of a buffer that has capacity for at least `length` bytes.
261 \param length Length of the buffer.
262 \param oid A 128-bit DAOS object identifier.
263 \param dkey The distribution key used for this operation.
264 \param akey The attribute key used for this operation.
265 \param cid An object class ID.
266 \return 0 if the operation succeeded; a negative DAOS error number otherwise.
267 */
268 int ReadSingleAkey(void *buffer, std::size_t length, daos_obj_id_t oid,
269 DistributionKey_t dkey, AttributeKey_t akey, ObjClassId_t cid);
270 int ReadSingleAkey(void *buffer, std::size_t length, daos_obj_id_t oid,
272 { return ReadSingleAkey(buffer, length, oid, dkey, akey, fDefaultObjectClass); }
273
274 /**
275 \brief Write the given buffer to a single object attribute key.
276 \param buffer The address of the source buffer.
277 \param length Length of the buffer.
278 \param oid A 128-bit DAOS object identifier.
279 \param dkey The distribution key used for this operation.
280 \param akey The attribute key used for this operation.
281 \param cid An object class ID.
282 \return 0 if the operation succeeded; a negative DAOS error number otherwise.
283 */
284 int WriteSingleAkey(const void *buffer, std::size_t length, daos_obj_id_t oid,
285 DistributionKey_t dkey, AttributeKey_t akey, ObjClassId_t cid);
286 int WriteSingleAkey(const void *buffer, std::size_t length, daos_obj_id_t oid,
288 { return WriteSingleAkey(buffer, length, oid, dkey, akey, fDefaultObjectClass); }
289
290 /**
291 \brief Perform a vector read operation on multiple objects.
292 \param map A `MultiObjectRWOperation_t` that describes read operations to perform.
293 \param cid An object class ID.
294 \return Number of operations that could not complete.
295 */
298
299 /**
300 \brief Perform a vector write operation on multiple objects.
301 \param map A `MultiObjectRWOperation_t` that describes write operations to perform.
302 \param cid An object class ID.
303 \return Number of operations that could not complete.
304 */
310};
311
312} // namespace Internal
313
314} // namespace Experimental
315} // namespace ROOT
316
317#endif
#define d(i)
Definition RSha256.hxx:102
#define a(i)
Definition RSha256.hxx:99
char * ret
Definition Rotated.cxx:221
char name[80]
Definition TGX11.cxx:148
A RDaosContainer provides read/write access to objects in a given container.
Definition RDaos.hxx:156
int ReadSingleAkey(void *buffer, std::size_t length, daos_obj_id_t oid, DistributionKey_t dkey, AttributeKey_t akey)
Definition RDaos.hxx:270
void SetDefaultObjectClass(const ObjClassId_t cid)
Definition RDaos.hxx:256
RDaosContainer(std::shared_ptr< RDaosPool > pool, std::string_view containerId, bool create=false)
Definition RDaos.cxx:174
RDaosObject::DistributionKey_t DistributionKey_t
Definition RDaos.hxx:159
int ReadV(MultiObjectRWOperation_t &map)
Definition RDaos.hxx:297
std::unordered_map< ROidDkeyPair, RWOperation, ROidDkeyPair::Hash > MultiObjectRWOperation_t
Definition RDaos.hxx:230
int ReadSingleAkey(void *buffer, std::size_t length, daos_obj_id_t oid, DistributionKey_t dkey, AttributeKey_t akey, ObjClassId_t cid)
Read data from a single object attribute key to the given buffer.
Definition RDaos.cxx:210
std::shared_ptr< RDaosPool > fPool
Definition RDaos.hxx:238
int WriteV(MultiObjectRWOperation_t &map, ObjClassId_t cid)
Perform a vector write operation on multiple objects.
Definition RDaos.hxx:305
int WriteV(MultiObjectRWOperation_t &map)
Definition RDaos.hxx:309
RDaosObject::AttributeKey_t AttributeKey_t
Definition RDaos.hxx:160
int WriteSingleAkey(const void *buffer, std::size_t length, daos_obj_id_t oid, DistributionKey_t dkey, AttributeKey_t akey, ObjClassId_t cid)
Write the given buffer to a single object attribute key.
Definition RDaos.cxx:221
int VectorReadWrite(MultiObjectRWOperation_t &map, ObjClassId_t cid, int(RDaosObject::*fn)(RDaosObject::FetchUpdateArgs &))
Perform a vector read/write operation on different objects.
Definition RDaos.cxx:233
int ReadV(MultiObjectRWOperation_t &map, ObjClassId_t cid)
Perform a vector read operation on multiple objects.
Definition RDaos.hxx:296
int WriteSingleAkey(const void *buffer, std::size_t length, daos_obj_id_t oid, DistributionKey_t dkey, AttributeKey_t akey)
Definition RDaos.hxx:286
Provides low-level access to DAOS objects in a container.
Definition RDaos.hxx:86
int Fetch(FetchUpdateArgs &args)
Definition RDaos.cxx:123
int Update(FetchUpdateArgs &args)
Definition RDaos.cxx:130
std::unique_ptr< RDaosEventQueue > fEventQueue
Definition RDaos.hxx:71
RDaosPool(const RDaosPool &)=delete
RDaosPool & operator=(const RDaosPool &)=delete
STL class.
This file is a reduced version of daos_xxx.h headers that provides (simplified) declarations for use ...
d_iov_t daos_key_t
Definition daos.h:76
int daos_oclass_name2id(const char *name)
@ OC_SX
Definition daos.h:129
@ OC_UNKNOWN
Definition daos.h:109
uint16_t daos_oclass_id_t
Definition daos.h:135
struct daos_event daos_event_t
Event and event queue.
Double_t x[n]
Definition legend1.C:17
Namespace for ROOT features in testing.
Definition TROOT.h:100
A pair of <object ID, distribution key> that can be used to issue a fetch/update request for multiple...
Definition RDaos.hxx:165
bool operator==(const ROidDkeyPair &other) const
Definition RDaos.hxx:169
void Insert(AttributeKey_t attr, std::vector< d_iov_t > &iovs)
Definition RDaos.hxx:215
std::unordered_map< AttributeKey_t, unsigned > fIndices
Definition RDaos.hxx:201
RWOperation(daos_obj_id_t o, DistributionKey_t d, std::vector< RDaosObject::RAkeyRequest > &&rs)
Definition RDaos.hxx:191
void Insert(AttributeKey_t attr, const d_iov_t &iov)
Definition RDaos.hxx:203
std::vector< RDaosObject::RAkeyRequest > fDataRequests
Definition RDaos.hxx:200
int InitializeEvent(daos_event_t *ev_ptr, daos_event_t *parent_ptr=nullptr) const
Reserve event in queue, optionally tied to a parent event.
Definition RDaos.cxx:149
static int FinalizeEvent(daos_event_t *ev_ptr)
Release event data from queue.
Definition RDaos.cxx:154
static int WaitOnParentBarrier(daos_event_t *ev_ptr)
Sets event barrier for a given parent event and waits for the completion of all children launched bef...
Definition RDaos.cxx:159
Contains required information for a single fetch/update operation.
Definition RDaos.hxx:120
std::span< RAkeyRequest > fRequests
fRequests is a sequential container assumed to remain valid throughout the fetch/update operation,...
Definition RDaos.hxx:133
daos_key_t fDistributionKey
The distribution key, as used by the daos_obj_{fetch,update} functions.
Definition RDaos.hxx:136
FetchUpdateArgs & operator=(const FetchUpdateArgs &)=delete
DistributionKey_t fDkey
A daos_key_t is a type alias of d_iov_t.
Definition RDaos.hxx:130
static constexpr std::size_t kOCNameMaxLength
This limit is currently not defined in any header and any call to daos_oclass_id2name() within DAOS u...
Definition RDaos.hxx:107
RAkeyRequest(const AttributeKey_t a, const std::vector< d_iov_t > &iovs)
Definition RDaos.hxx:115
RAkeyRequest(const AttributeKey_t a, std::vector< d_iov_t > &&iovs)
Definition RDaos.hxx:116
iovec for memory buffer
Definition daos.h:37
Generic handle for various DAOS components like container, object, etc.
Definition daos.h:59
uint64_t hi
Definition daos.h:147
uint64_t lo
Definition daos.h:146