From 9a6c1b12a1c480631ec95183fa0872a73a314cf9 Mon Sep 17 00:00:00 2001 From: tmadlener Date: Thu, 13 Apr 2023 16:46:07 +0200 Subject: [PATCH] Add documentation --- include/podio/CollectionBufferFactory.h | 44 ++++++++++++++++++++++--- python/templates/Collection.cc.jinja2 | 5 +++ 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/include/podio/CollectionBufferFactory.h b/include/podio/CollectionBufferFactory.h index ac798cedd..c3c45692b 100644 --- a/include/podio/CollectionBufferFactory.h +++ b/include/podio/CollectionBufferFactory.h @@ -12,35 +12,71 @@ namespace podio { /** - * Registry like type that provides empty buffers for collections + * The CollectionBufferFactory allows to create buffers of known datatypes, + * which can then be populated by e.g. readers. In order to support schema + * evolution, the buffers have a version and this factory will also require a + * schema version to create buffers. + * + * It is implemented as a singleton, which is populated at the time a shared + * datamodel library is loaded. It is assumed that that happens early on in the + * startup of an appliation, such that only a single thread will access the + * factory instance for registering datatypes. Since the necessary creation + * functions are part of the core datamodel library, this should be very easy to + * achieve by simply linking to that library. Once the factory is populated it + * can be safely accessed from multiple threads concurrently to obtain buffers. */ class CollectionBufferFactory { /// Internal storage is a map to an array of creation functions, where the /// version determines the place in that array. This should be a viable - /// approach because we now the "latest and greatest" schema version + /// approach because we know the "latest and greatest" schema version using CreationFuncT = std::function; using VersionMapT = std::vector; using MapT = std::unordered_map; public: + /// The buffer factory is a singleton so we disable all copy and move + /// constructors explicitly CollectionBufferFactory(CollectionBufferFactory const&) = delete; CollectionBufferFactory& operator=(CollectionBufferFactory const&) = delete; CollectionBufferFactory(CollectionBufferFactory&&) = delete; CollectionBufferFactory& operator=(CollectionBufferFactory&&) = delete; ~CollectionBufferFactory() = default; + /// Mutable instance only used for the initial registration of functions + /// during library loading static CollectionBufferFactory& mutInstance(); + /// Get the factory instance static CollectionBufferFactory const& instance(); + /** + * Create buffers for a given collection type of a given schema version. + * + * @param collType The collection type name (e.g. from collection->getTypeName()) + * @param version The schema version the created buffers should have + * @param susbsetColl Should the buffers be for a subset collection or not + * + * @return CollectionReadBuffers if a creation function for this collection + * type has been registered, otherwise an empty optional + */ std::optional createBuffers(const std::string& collType, SchemaVersionT version, bool subsetColl) const; - + /** + * Register a creation function for a given collection type and schema version. + * + * @param collType The collection type name (i.e. what + * collection->getTypeName() returns) + * @param version The schema version for which this creation function is valid + * @param creationFunc The function that when invoked returns buffers for this + * collection type and schema version. The signature has to be + * podio::CollectionReadBuffers(bool) where the boolean parameter steers + * whether the buffers are for a subset collection or not. + */ void registerCreationFunc(const std::string& collType, SchemaVersionT version, const CreationFuncT& creationFunc); private: CollectionBufferFactory() = default; - MapT m_funcMap{}; + MapT m_funcMap{}; ///< Map to the creation functions }; } // namespace podio diff --git a/python/templates/Collection.cc.jinja2 b/python/templates/Collection.cc.jinja2 index df6d0e4d9..1789a83f6 100644 --- a/python/templates/Collection.cc.jinja2 +++ b/python/templates/Collection.cc.jinja2 @@ -164,6 +164,9 @@ podio::SchemaVersionT {{ collection_type }}::getSchemaVersion() const { return {{ package_name }}::meta::schemaVersion; } +// anonymous namespace for registration with the CollectionBufferFactory. This +// ensures that we don't have to make up arbitrary namespace names here, since +// none of this is publicly visible namespace { podio::CollectionReadBuffers createBuffers(bool isSubset) { auto readBuffers = podio::CollectionReadBuffers{}; @@ -205,6 +208,8 @@ podio::CollectionReadBuffers createBuffers(bool isSubset) { return readBuffers; } +// The usual trick with an IIFE and a static variable inside a funtion and then +// making sure to call that function during shared library loading bool registerCollection() { const static auto reg = []() { auto& factory = podio::CollectionBufferFactory::mutInstance();