Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Frame in memory interface #278

Closed
wants to merge 15 commits into from
Closed

Frame in memory interface #278

wants to merge 15 commits into from

Conversation

tmadlener
Copy link
Collaborator

@tmadlener tmadlener commented Mar 30, 2022

BEGINRELEASENOTES

  • Introduce the podio::Frame as a generalized (event) data container with the necessary prerequisites to extend this basic implementation with all the planned functionality later.
    • This version does not yet include any I/O functionality but only introduces the thread-safe in-memory interface.

ENDRELEASENOTES

This is a first version of the in-memory interface of the Frame proposal. I am putting this here to gather early feedback, mainly on the user interface and on some of the proposed functionality. At this point only the basic skeleton for the podio::Frame is present and much of the foreseen functionality is still missing. However, the interface should be somewhat stable already as most of that functionality should be hidden, or not observable through the interface. One thing that could still influence the interface could be the choice of policies that we want to offer. I have put some of my proposals below.

Having this discussion early enough might make it possible to split this feature into several pull requests instead of having one extremely large one.

podio::Frame interface

The Frame is implemented via type-erasure. This allows us to have different policies but only one user facing class with value semantics and the possibility to construct from different raw data types 1. The current public interface of the Frame looks essentially like this:

class Frame {
public:
  template<typename CollT>
  const CollT& get(const std::string& name) const;

  template<typename CollT>
  const CollT& put(CollT&& coll, const std::string& name);

  template<typename T>
  void putParameter(const std::string& key, T value);
  
  template<typename T>
  const T& getParameter(const std::string& key) const;
};

Some notes (about the actual implementation that are not visible in the above version):

  • The put and get methods use std::enable_if to only be available for collections added by podio.
  • The put method uses std::enable_if to force users to explicitly pass a temporary or relinquish ownership via std::move.
  • The {put|get}Parameter functionality provides the extra data / meta data functionality and is using the GenericParameters class under the hood.
    • The templates are using std::enable_if to only be available for the types that are actually supported (int, float, std::string and std::vectors of those)
    • The return value of getParameter is either a const T& or a T (for int and float).
    • There are a few dedicated overloads for putParameter to enhance the usability, e.g. for passing raw string literals or initializer lists.

Planned policies

There are a few policies that I have already in mind, but this is still open for discussion

  • Unpacking policy that controls how the raw data that are passed are unpacked. E.g. could be eagerly on Frame construction or lazily on demand. Would be completely invisible for users.
  • Handling of collisions when putting collections into the Frame. E.g. could throw an exception, silently drop the new collection or replace the existing collection. Could potentially also be part of the put interface to have more fine grained control, instead of having a "global" policy
  • Handling of missing collections. E.g. could throw an exception or simply return an empty new collection. Could potentially become part of the get interface to have more fine grained control, instead of a "global" policy.
  • Locking policy. E.g. could drop all (externally observable) locking if the Frame is only used from one thread or to read only, or could go with the default locking which might have an impact on single threaded use.

Preliminary TODO list

Footnotes

  1. This first proposal is still missing these features at the moment.

@tmadlener tmadlener marked this pull request as draft March 30, 2022 16:52
@tmadlener tmadlener changed the base branch from develop to master April 4, 2022 09:30
@tmadlener tmadlener changed the title [WIP] Frame proposal Frame in memory interface May 17, 2022
@tmadlener tmadlener marked this pull request as ready for review May 17, 2022 12:18
@tmadlener tmadlener mentioned this pull request May 23, 2022
9 tasks
Using a mutex to guard the internal map. Not yet a policy with
possibility to disable locking from the outside
Use a unique_ptr<mutex> to preserve default movability of things
- Make them non-copyable
- Fix read_tests to use const references instead of copying
If REQUIRE is the last statement in a function run on a thread, clangs
ThreadSanitizer triggers in the Catch2 internals.
Makes all thread test cases consistent
tests/frame.cpp Outdated Show resolved Hide resolved
@tmadlener
Copy link
Collaborator Author

Closing this, as it is fully contained in #287 and will be merged as an “atomic” commit introducing the Frame

@tmadlener tmadlener closed this Sep 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant