-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ntuple] Support the storage of collections using the TVirtualCollectionProxy
interface
#11525
[ntuple] Support the storage of collections using the TVirtualCollectionProxy
interface
#11525
Conversation
Initial skeleton for supporting classes with an associated collection proxy. Object of such type behave as a collection of elements accessible through the `TVirtualCollectionProxy` interface.
Reduce the number of virtual calls to `TVirtualCollectionProxy::Insert()` by reading and inserting a block of elements at once.
Starting build on |
FYI, @mnowakgit 🙂 |
Build failed on ROOT-ubuntu2004/python3. Errors:
|
Build failed on mac1015/cxx17. Warnings:
|
429dc07
to
129332b
Compare
Starting build on |
Build failed on ROOT-ubuntu2004/python3. Errors:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is awesome!
Some minor comments inline; for the tests: let's also test: vector of collection proxies, collection proxy of vectors and collection proxy of collection proxies.
…emplate arg Do not rely on the use of an additional "tag" argument to disambiguate between the `RField` primary template definition that derives from `RClassField` and the specialization for classes using a collection proxy. Instead, this commit introduces the `IsCollectionProxy<T>` template that can be specialized to mark a specific class as a proxied collection.
129332b
to
c0a8676
Compare
Starting build on |
Test the usage of collection proxies yielding elements of a fundamental C++ type.
Test the usage of collection proxies whose value type is a compound type with nested collections.
Co-authored-by: Jakob Blomer <jblomer@cern.ch>
c0a8676
to
f72e321
Compare
Starting build on |
- Test `RField<std::vector<T>>` where `T` is a proxied collection - Test nested collection proxies
f72e321
to
377a520
Compare
Build failed on mac1015/cxx17. Failing tests: |
…roxy Co-authored-by: Philippe Canal <pcanal@fnal.gov>
Starting build on |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Many thanks for the update! Not entirely through yet but some comments are ready for discussion.
Starting build on |
232fb0f
to
e926475
Compare
Starting build on |
Starting build on |
Build failed on mac1015/cxx17. Failing tests: |
`RClassField` and `RCollectionClassField` (used for regular user-defined classes / classes with an associated collection proxy, respectively) should throw if used unappropriately, i.e. if `RClassField` is instantiated to handle a class that has a collection proxy set or viceversa.
04f7b88
to
e619d57
Compare
Starting build on |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work! From my side, that's good to go. It would probably be a good idea to still address Philippe's comment on `fProxy->Clear();.
Instead of manually destroying collection items in `ReadGlobalImpl()`, rely on `TVirtualCollectionProxy::Clear()`. Rationale (a PR comment by jblomer): The `DestroyValue` and `GenerateValue` calls should be symmetric. So if the collection proxy takes care of cleaning memory, it should also be in charge of (default)-constructing new elements on resize. I think that is the case here. The `GenerateValue` call is only used on the internal buffer. The collection then copies the elements from the internal buffer into its own memory, IIUC. Co-authored-by: Philippe Canal <pcanal@fnal.gov> Co-authored-by: Jakob Blomer <jblomer@cern.ch>
Starting build on |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks.
This pull request introduces RField support for user-defined classes that behave as collections of elements. These classes specify a "collection proxy" that provides access to the elements in the collection.
A legacy collection proxy is provided in the form of an instance of a class derived from
TVirtualCollectionProxy
. The collection proxy for a class is typically set during initialization, usually usingTClass::CopyCollectionProxy()
or similar.In this pull request, we introduce support for legacy collection proxies derived from the
TVirtualCollectionProxy
class, although in later stages, RNTuple might provide this functionality through an interface different interface.At a bare minimum, the user is required to provide an implementation for the following functions in
TVirtualCollectionProxy
:HasPointers()
,GetProperties()
,GetValueClass()
,GetType()
,Sizeof()
: for general information about the collection and its value type.Sizeof()
,At()
,Clear()
, andInsert()
: for element accessPushProxy()
,PopProxy()
: for selecting the target object.A usage example can be seen here.
Changes or fixes:
RCollectionClassField
, representing a field of a user-defined class that behaves as a collection that is compliant with theTVirtualCollectionProxy
interface.Given that the
RField<T>
primary template definition (that used if no specialization matches) usesRClassField
to store members of a class, we rely on an additional helper type (IsCollectionProxy<T>
) to annotate that a particular class has an associated collection proxy (see example below).This tag is not required when using the type-erased interface (i.e.,
RFieldBase::Create()
), as the use of a collection proxy can be determined at run time viaTClass
.RCollectionClassField::ReadGlobalImpl()
: reduce the number of virtual calls toTVirtualCollectionProxy::Insert()
by reading and inserting a block of elements at once. The size of the buffer that holds the elements is set byRCollectionClassField::kReadChunkSize
(in bytes).RPrintValueVisitor::VisitCollectionClassField()
doc/specifications.md
Checklist:
This PR fixes #11523.