Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-05 09:17:42

0001 #ifndef PODIO_DETAIL_LINKCOLLECTIONDATA_H
0002 #define PODIO_DETAIL_LINKCOLLECTIONDATA_H
0003 
0004 #include "podio/detail/LinkFwd.h"
0005 #include "podio/detail/LinkObj.h"
0006 
0007 #include "podio/CollectionBase.h"
0008 #include "podio/CollectionBuffers.h"
0009 #include "podio/ICollectionProvider.h"
0010 #include "podio/detail/RelationIOHelpers.h"
0011 
0012 #include <memory>
0013 #include <vector>
0014 
0015 namespace podio {
0016 
0017 template <typename FromT, typename ToT>
0018 class LinkCollectionData {
0019 public:
0020   LinkObjPointerContainer<FromT, ToT> entries{};
0021 
0022   LinkCollectionData() :
0023       m_rel_from(new std::vector<FromT>()), m_rel_to(new std::vector<ToT>()), m_data(new LinkDataContainer()) {
0024     m_refCollections.reserve(2);
0025     m_refCollections.emplace_back(std::make_unique<std::vector<podio::ObjectID>>());
0026     m_refCollections.emplace_back(std::make_unique<std::vector<podio::ObjectID>>());
0027   }
0028 
0029   LinkCollectionData(podio::CollectionReadBuffers&& buffers, bool isSubsetColl) :
0030       m_rel_from(new std::vector<FromT>()),
0031       m_rel_to(new std::vector<ToT>()),
0032       m_refCollections(std::move(*buffers.references)) {
0033     if (!isSubsetColl) {
0034       m_data.reset(buffers.dataAsVector<LinkData>());
0035       buffers.data = nullptr;
0036     }
0037 
0038     delete buffers.references;
0039     buffers.references = nullptr;
0040     delete buffers.vectorMembers;
0041     buffers.vectorMembers = nullptr;
0042   }
0043 
0044   LinkCollectionData(const LinkCollectionData&) = delete;
0045   LinkCollectionData& operator=(const LinkCollectionData&) = delete;
0046   LinkCollectionData(LinkCollectionData&&) = default;
0047   LinkCollectionData& operator=(LinkCollectionData&&) = default;
0048   ~LinkCollectionData() = default;
0049 
0050   podio::CollectionWriteBuffers getCollectionBuffers(bool isSubsetColl) {
0051     return {isSubsetColl ? nullptr : static_cast<void*>(&m_data), static_cast<void*>(m_data.get()), &m_refCollections,
0052             &m_vecInfo};
0053   }
0054 
0055   void clear(bool isSubsetColl) {
0056     if (isSubsetColl) {
0057       // We don't own the objects so no cleanup to do here
0058       entries.clear();
0059       // Clear the ObjectID I/O buffer
0060       for (auto& pointer : m_refCollections) {
0061         pointer->clear();
0062       }
0063       return;
0064     }
0065 
0066     // Normal collections manage a bit more and have to clean up a bit more
0067     if (m_data) {
0068       m_data->clear();
0069     }
0070     for (const auto& pointer : m_refCollections) {
0071       pointer->clear();
0072     }
0073     if (m_rel_from) {
0074       for (auto& item : (*m_rel_from)) {
0075         item.unlink();
0076       }
0077       m_rel_from->clear();
0078     }
0079 
0080     if (m_rel_to) {
0081       for (auto& item : (*m_rel_to)) {
0082         item.unlink();
0083       }
0084       m_rel_to->clear();
0085     }
0086 
0087     for (const auto& obj : entries) {
0088       delete obj;
0089     }
0090     entries.clear();
0091   }
0092 
0093   void prepareForWrite(bool isSubsetColl) {
0094     for (const auto& pointer : m_refCollections) {
0095       pointer->clear();
0096     }
0097 
0098     // If this is a subset collection use the relation storing mechanism to
0099     // store the ObjectIDs of all reference objects and nothing else
0100     if (isSubsetColl) {
0101       for (const auto* obj : entries) {
0102         m_refCollections[0]->emplace_back(obj->id);
0103       }
0104       return;
0105     }
0106 
0107     m_data->reserve(entries.size());
0108     for (const auto obj : entries) {
0109       m_data->push_back(obj->data);
0110 
0111       if (obj->m_from) {
0112         m_refCollections[0]->emplace_back(obj->m_from->getObjectID());
0113       } else {
0114         m_refCollections[0]->push_back({podio::ObjectID::invalid, 0});
0115       }
0116 
0117       if (obj->m_to) {
0118         m_refCollections[1]->emplace_back(obj->m_to->getObjectID());
0119       } else {
0120         m_refCollections[1]->push_back({podio::ObjectID::invalid, 0});
0121       }
0122     }
0123   }
0124 
0125   void prepareAfterRead(uint32_t collectionID) {
0126     int index = 0;
0127     for (const auto data : *m_data) {
0128       auto obj = new LinkObj<FromT, ToT>({index++, collectionID}, data);
0129       entries.emplace_back(obj);
0130     }
0131 
0132     // Keep the I/O data buffer to keep the preparedForWrite state intact
0133   }
0134 
0135   bool setReferences(const podio::ICollectionProvider* collectionProvider, bool isSubsetColl) {
0136     if (isSubsetColl) {
0137       for (const auto& id : *m_refCollections[0]) {
0138         podio::CollectionBase* coll{nullptr};
0139         LinkObj<FromT, ToT>* obj{nullptr};
0140         if (collectionProvider->get(id.collectionID, coll)) {
0141           auto* tmp_coll = static_cast<LinkCollection<FromT, ToT>*>(coll);
0142           obj = tmp_coll->m_storage.entries[id.index];
0143         }
0144         entries.push_back(obj);
0145       }
0146       return true; // TODO: check success, how?
0147     }
0148 
0149     // Normal collections have to resolve all relations
0150     for (size_t i = 0; i < entries.size(); ++i) {
0151       const auto id = (*m_refCollections[0])[i];
0152       if (id.index != podio::ObjectID::invalid) {
0153         podio::CollectionBase* coll = nullptr;
0154         if (!collectionProvider->get(id.collectionID, coll)) {
0155           entries[i]->m_from = nullptr;
0156           continue;
0157         }
0158         podio::detail::addSingleRelation(entries[i]->m_from, coll, id);
0159       } else {
0160         entries[i]->m_from = nullptr;
0161       }
0162     }
0163 
0164     for (size_t i = 0; i < entries.size(); ++i) {
0165       const auto id = (*m_refCollections[1])[i];
0166       if (id.index != podio::ObjectID::invalid) {
0167         podio::CollectionBase* coll = nullptr;
0168         if (!collectionProvider->get(id.collectionID, coll)) {
0169           entries[i]->m_to = nullptr;
0170           continue;
0171         }
0172         podio::detail::addSingleRelation(entries[i]->m_to, coll, id);
0173       } else {
0174         entries[i]->m_to = nullptr;
0175       }
0176     }
0177 
0178     return true; // TODO: check success, how?
0179   }
0180 
0181   void makeSubsetCollection() {
0182     // Subset collections do not need all the data buffers that normal
0183     // collections need, so we can free them here
0184     m_data.reset(nullptr);
0185 
0186     m_rel_from.reset(nullptr);
0187     m_rel_to.reset(nullptr);
0188 
0189     // Subset collections need one vector of ObjectIDs for I/O purposes.
0190     m_refCollections.resize(1);
0191     m_refCollections[0] = std::make_unique<std::vector<podio::ObjectID>>();
0192   }
0193 
0194 private:
0195   // members to handle relations
0196   podio::UVecPtr<FromT> m_rel_from{nullptr};
0197   podio::UVecPtr<ToT> m_rel_to{nullptr};
0198 
0199   // I/O related buffers (as far as necessary)
0200   podio::CollRefCollection m_refCollections{};
0201   podio::VectorMembersInfo m_vecInfo{};
0202   std::unique_ptr<LinkDataContainer> m_data{nullptr};
0203 };
0204 
0205 } // namespace podio
0206 
0207 #endif // PODIO_DETAIL_LINKCOLLECTIONDATA_H