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
0058 entries.clear();
0059
0060 for (auto& pointer : m_refCollections) {
0061 pointer->clear();
0062 }
0063 return;
0064 }
0065
0066
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
0099
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
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;
0147 }
0148
0149
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;
0179 }
0180
0181 void makeSubsetCollection() {
0182
0183
0184 m_data.reset(nullptr);
0185
0186 m_rel_from.reset(nullptr);
0187 m_rel_to.reset(nullptr);
0188
0189
0190 m_refCollections.resize(1);
0191 m_refCollections[0] = std::make_unique<std::vector<podio::ObjectID>>();
0192 }
0193
0194 private:
0195
0196 podio::UVecPtr<FromT> m_rel_from{nullptr};
0197 podio::UVecPtr<ToT> m_rel_to{nullptr};
0198
0199
0200 podio::CollRefCollection m_refCollections{};
0201 podio::VectorMembersInfo m_vecInfo{};
0202 std::unique_ptr<LinkDataContainer> m_data{nullptr};
0203 };
0204
0205 }
0206
0207 #endif