Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions tree/ntuple/inc/ROOT/RField/RFieldSequenceContainer.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ public:
/// The generic field for a (nested) `std::vector<Type>` except for `std::vector<bool>`
/// The field can be constructed as untyped collection through CreateUntyped().
class RVectorField : public RFieldBase {
friend class RArrayAsVectorField; // to get access to the RVectorDeleter
friend std::unique_ptr<RFieldBase> Internal::CreateEmulatedVectorField(std::string_view fieldName,
std::unique_ptr<RFieldBase> itemField,
std::string_view emulatedFromType);
Expand All @@ -222,6 +223,10 @@ class RVectorField : public RFieldBase {
ROOT::Internal::RColumnIndex fNWritten;
std::unique_ptr<RDeleter> fItemDeleter;

// Ensures that the std::vector pointed to by vec has at least nItems valid elements.
static void ResizeVector(void *vec, std::size_t nItems, std::size_t itemSize, const RFieldBase &itemField,
RDeleter *itemDeleter);

protected:
/// Creates a possibly-untyped VectorField.
/// If `emulatedFromType` is not nullopt, the field is untyped. If the string is empty, it is a "regular"
Expand All @@ -241,6 +246,7 @@ protected:
std::size_t AppendImpl(const void *from) final;
void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;

std::unique_ptr<RFieldBase> BeforeConnectPageSource(ROOT::Internal::RPageSource &pageSource) final;
void ReconcileOnDiskField(const RNTupleDescriptor &desc) final;

void CommitClusterImpl() final { fNWritten = 0; }
Expand Down Expand Up @@ -275,6 +281,9 @@ template <>
class RField<std::vector<bool>> final : public RFieldBase {
private:
ROOT::Internal::RColumnIndex fNWritten{0};
/// If schema-evolved from an std::array, fOnDiskNRepetition is > 0 and there will be no
/// principal column.
std::size_t fOnDiskNRepetitions = 0;

protected:
std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
Expand All @@ -291,6 +300,7 @@ protected:

std::size_t AppendImpl(const void *from) final;
void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
void ReadInClusterImpl(ROOT::RNTupleLocalIndex localIndex, void *to) final;

void ReconcileOnDiskField(const RNTupleDescriptor &desc) final;

Expand Down Expand Up @@ -363,6 +373,50 @@ public:
void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
};

/**
\class ROOT::RArrayAsVectorField
\brief A field for fixed-size arrays that are represented as std::vector in memory.
\ingroup NTuple
This class is used only for reading. In particular, it helps for schema evolution of fixed-size arrays into vectors.
*/
class RArrayAsVectorField final : public RFieldBase {
private:
std::unique_ptr<RDeleter> fItemDeleter; /// Sub field deleter or nullptr for simple fields
std::size_t fItemSize; /// The size of a child field's item
std::size_t fArrayLength; /// The length of the arrays in this field

protected:
std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;

void GenerateColumns() final;
using RFieldBase::GenerateColumns;

void ConstructValue(void *where) const final { new (where) std::vector<char>(); }
/// Returns an RVectorField::RVectorDeleter
std::unique_ptr<RDeleter> GetDeleter() const final;

void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
void ReadInClusterImpl(RNTupleLocalIndex localIndex, void *to) final;

void ReconcileOnDiskField(const RNTupleDescriptor &desc) final;

public:
/// The `itemField` argument represents the inner item of the on-disk array,
/// i.e. for an `std::array<float>` it is the `float`
RArrayAsVectorField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField, std::size_t arrayLength);
RArrayAsVectorField(const RArrayAsVectorField &other) = delete;
RArrayAsVectorField &operator=(const RArrayAsVectorField &other) = delete;
RArrayAsVectorField(RArrayAsVectorField &&other) = default;
RArrayAsVectorField &operator=(RArrayAsVectorField &&other) = default;
~RArrayAsVectorField() final = default;

size_t GetValueSize() const final { return sizeof(std::vector<char>); }
size_t GetAlignment() const final { return std::alignment_of<std::vector<char>>(); }

std::vector<RFieldBase::RValue> SplitValue(const RFieldBase::RValue &value) const final;
void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
};

} // namespace ROOT

#endif
2 changes: 2 additions & 0 deletions tree/ntuple/inc/ROOT/RFieldVisitor.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public:
virtual void VisitFieldZero(const ROOT::RFieldZero &field) { VisitField(field); }
virtual void VisitArrayField(const ROOT::RArrayField &field) { VisitField(field); }
virtual void VisitArrayAsRVecField(const ROOT::RArrayAsRVecField &field) { VisitField(field); }
virtual void VisitArrayAsVectorField(const ROOT::RArrayAsVectorField &field) { VisitField(field); }
virtual void VisitAtomicField(const ROOT::RAtomicField &field) { VisitField(field); }
virtual void VisitBitsetField(const ROOT::RBitsetField &field) { VisitField(field); }
virtual void VisitBoolField(const ROOT::RField<bool> &field) { VisitField(field); }
Expand Down Expand Up @@ -235,6 +236,7 @@ public:
void VisitCardinalityField(const ROOT::RCardinalityField &field) final;
void VisitArrayField(const ROOT::RArrayField &field) final;
void VisitArrayAsRVecField(const ROOT::RArrayAsRVecField &field) final;
void VisitArrayAsVectorField(const ROOT::RArrayAsVectorField &field) final;
void VisitClassField(const ROOT::RClassField &field) final;
void VisitTObjectField(const ROOT::RField<TObject> &field) final;
void VisitStreamerField(const ROOT::RStreamerField &field) final;
Expand Down
Loading
Loading