Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/podio/detail/LinkCollectionData.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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