10#include <initializer_list>
17#include <unordered_map>
32using EnableIfRValue =
typename std::enable_if_t<!std ::is_lvalue_reference_v<T>>;
55 return std::make_unique<podio::GenericParameters>();
60template <
typename FrameDataT>
61std::optional<podio::CollectionReadBuffers>
unpack(FrameDataT* data,
const std::string& name) {
62 return data->getCollectionBuffers(name);
74 virtual ~FrameConcept() =
default;
76 virtual const podio::CollectionBase* put(std::unique_ptr<podio::CollectionBase> coll,
const std::string& name) = 0;
80 virtual std::vector<std::string> availableCollections()
const = 0;
91 template <
typename FrameDataT>
94 FrameModel(std::unique_ptr<FrameDataT> data);
95 ~FrameModel() =
default;
96 FrameModel(
const FrameModel&) =
delete;
97 FrameModel& operator=(
const FrameModel&) =
delete;
98 FrameModel(FrameModel&&) =
default;
99 FrameModel& operator=(FrameModel&&) =
default;
110 const podio::CollectionBase* put(std::unique_ptr<CollectionBase> coll,
const std::string& name)
final;
115 return *m_parameters;
120 return *m_parameters;
127 return {m_idTable.
ids(), m_idTable.names()};
130 std::vector<std::string> availableCollections()
const override;
135 using CollectionMapT = std::unordered_map<std::string, std::unique_ptr<podio::CollectionBase>>;
137 mutable CollectionMapT m_collections{};
138 mutable std::unique_ptr<std::mutex> m_mapMtx{
nullptr};
139 std::unique_ptr<FrameDataT> m_data{
nullptr};
140 mutable std::unique_ptr<std::mutex> m_dataMtx{
nullptr};
142 std::unique_ptr<podio::GenericParameters> m_parameters{
nullptr};
143 mutable std::set<int> m_retrievedIDs{};
147 std::unique_ptr<FrameConcept> m_self;
156 template <
typename FrameDataT>
157 Frame(std::unique_ptr<FrameDataT>);
164 template <
typename FrameDataT,
typename = EnableIfRValue<FrameDataT>>
179 template <
typename CollT,
typename = EnableIfCollection<CollT>>
180 const CollT&
get(
const std::string& name)
const;
190 template <
typename CollT,
typename = EnableIfCollectionRValue<CollT>>
191 const CollT&
put(CollT&& coll,
const std::string& name);
195 void put(std::unique_ptr<podio::CollectionBase> coll,
const std::string& name);
200 template <
typename T,
typename = podio::EnableIfVal
idGenericDataType<T>>
202 m_self->parameters().setValue(key, value);
209 putParameter<std::string>(key, std::move(value));
216 inline void putParameter(
const std::string& key, std::vector<std::string> values) {
217 putParameter<std::vector<std::string>>(key, std::move(values));
223 template <
typename T,
typename = std::enable_if_t<detail::isInTuple<T, SupportedGenericDataTypes>>>
224 inline void putParameter(
const std::string& key, std::initializer_list<T>&& values) {
225 putParameter<std::vector<T>>(key, std::move(values));
231 template <
typename T,
typename = podio::EnableIfVal
idGenericDataType<T>>
233 return m_self->parameters().getValue<T>(key);
239 return m_self->parameters();
244 template <
typename T,
typename = podio::EnableIfVal
idGenericDataType<T>>
246 return m_self->parameters().getKeys<T>();
253 return m_self->availableCollections();
263 return m_self->parameters();
270 const auto* coll = m_self->get(name);
279 return m_self->getIDTable();
288template <
typename FrameDataT>
289Frame::Frame(std::unique_ptr<FrameDataT> data) : m_self(std::make_unique<FrameModel<FrameDataT>>(std::move(data))) {
292template <
typename FrameDataT,
typename>
296template <
typename CollT,
typename>
298 const auto* coll =
dynamic_cast<const CollT*
>(m_self->get(name));
303 static const auto emptyColl = CollT();
308 return m_self->get(name);
311inline void Frame::put(std::unique_ptr<podio::CollectionBase> coll,
const std::string& name) {
312 const auto* retColl = m_self->put(std::move(coll), name);
318template <
typename CollT,
typename>
319const CollT&
Frame::put(CollT&& coll,
const std::string& name) {
320 const auto* retColl =
static_cast<const CollT*
>(m_self->put(std::make_unique<CollT>(std::move(coll)), name));
325 static const auto emptyColl = CollT();
329template <
typename FrameDataT>
330Frame::FrameModel<FrameDataT>::FrameModel(std::unique_ptr<FrameDataT> data) :
331 m_mapMtx(std::make_unique<std::mutex>()),
332 m_data(std::move(data)),
333 m_dataMtx(std::make_unique<std::mutex>()),
334 m_idTable(std::move(m_data->getIDTable())),
335 m_parameters(std::move(m_data->getParameters())) {
338template <
typename FrameDataT>
343template <
typename FrameDataT>
344podio::CollectionBase* Frame::FrameModel<FrameDataT>::doGet(
const std::string& name,
bool setReferences)
const {
350 std::lock_guard lock{*m_mapMtx};
351 if (
const auto it = m_collections.find(name); it != m_collections.end()) {
352 return it->second.get();
362 auto buffers = std::optional<podio::CollectionReadBuffers>{std::nullopt};
364 std::lock_guard lock{*m_dataMtx};
365 buffers =
unpack(m_data.get(), name);
368 auto coll = buffers->createCollection(buffers.value(), buffers->data ==
nullptr);
369 coll->prepareAfterRead();
370 coll->setID(m_idTable.collectionID(name));
372 std::lock_guard mapLock{*m_mapMtx};
373 auto [it, success] = m_collections.emplace(name, std::move(coll));
376 retColl = it->second.get();
388template <
typename FrameDataT>
389bool Frame::FrameModel<FrameDataT>::get(
int collectionID, CollectionBase*& collection)
const {
390 const auto& name = m_idTable.name(collectionID);
391 const auto& [_, inserted] = m_retrievedIDs.insert(collectionID);
394 auto coll = doGet(name);
400 auto coll = doGet(name,
false);
410template <
typename FrameDataT>
411const podio::CollectionBase* Frame::FrameModel<FrameDataT>::put(std::unique_ptr<podio::CollectionBase> coll,
412 const std::string& name) {
414 std::lock_guard lock{*m_mapMtx};
415 auto [it, success] = m_collections.try_emplace(name, std::move(coll));
421 it->second->
setID(m_idTable.add(name));
422 return it->second.get();
429template <
typename FrameDataT>
430std::vector<std::string> Frame::FrameModel<FrameDataT>::availableCollections()
const {
438 std::scoped_lock lock{*m_mapMtx, *m_dataMtx};
440 auto collections = m_data->getAvailableCollections();
441 collections.reserve(collections.size() + m_collections.size());
443 for (
const auto& [name, _] : m_collections) {
444 collections.push_back(name);
virtual void setID(unsigned id)=0
set collection ID
virtual void prepareForWrite() const =0
prepare buffers for serialization
virtual bool setReferences(const ICollectionProvider *collectionProvider)=0
initialize references after read
const std::vector< int > & ids() const
return the ids
const CollT & get(const std::string &name) const
const CollT & put(CollT &&coll, const std::string &name)
Frame & operator=(const Frame &)=delete
Frame & operator=(Frame &&)=default
podio::CollectionIDTable getCollectionIDTableForWrite() const
std::vector< std::string > getParameterKeys() const
Frame(const Frame &)=delete
std::vector< std::string > getAvailableCollections() const
void putParameter(const std::string &key, std::string value)
const podio::GenericParameters & getGenericParametersForWrite() const
void putParameter(const std::string &key, std::initializer_list< T > &&values)
const podio::GenericParameters & getParameters() const
void putParameter(const std::string &key, std::vector< std::string > values)
podio::GenericDataReturnType< T > getParameter(const std::string &key) const
void putParameter(const std::string &key, T value)
const podio::CollectionBase * getCollectionForWrite(const std::string &name) const
typename std::enable_if_t< isCollection< T > > EnableIfCollection
Alias template for enabling overloads only for Collections.
typename std::enable_if_t<!std ::is_lvalue_reference_v< T > > EnableIfRValue
Alias template for enabling overloads for r-values.
std::optional< podio::CollectionReadBuffers > unpack(FrameDataT *data, const std::string &name)
typename detail::GenericDataReturnTypeHelper< T >::type GenericDataReturnType
typename std::enable_if_t< isCollection< T > &&!std::is_lvalue_reference_v< T > > EnableIfCollectionRValue
Alias template for enabling overloads only for Collection r-values.
std::unique_ptr< podio::GenericParameters > getParameters()
std::optional< podio::CollectionReadBuffers > getCollectionBuffers(const std::string &)
std::vector< std::string > getAvailableCollections() const
podio::CollectionIDTable getIDTable() const