pipeline/PipelineSnooper.hpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // <PipelineSnooper.hpp> -*- C++ -*- | ||
| 2 | |||
| 3 | #pragma once | ||
| 4 | |||
| 5 | #include <functional> | ||
| 6 | #include <set> | ||
| 7 | #include <vector> | ||
| 8 | |||
| 9 | #include "simdb/Assert.hpp" | ||
| 10 | |||
| 11 | namespace simdb::pipeline { | ||
| 12 | |||
| 13 | class PipelineManager; | ||
| 14 | class Stage; | ||
| 15 | |||
| 16 | /*! | ||
| 17 | * \class PipelineSnooper | ||
| 18 | * | ||
| 19 | * \brief Collects Stage::snoop(key, snooped_obj) callbacks and runs them | ||
| 20 | * via snoopAllStages(). Create with PipelineManager::createSnooper<KeyType,SnoopedType>(), | ||
| 21 | * addStage() for each stage that implements snoop(), then call | ||
| 22 | * snoopAllStages() to query all stages (optionally with pipeline disabled). | ||
| 23 | * \tparam KeyType Type of the key passed to snoop(). | ||
| 24 | * \tparam SnoopedType Type of the object that stages fill in (e.g. aggregate result). | ||
| 25 | */ | ||
| 26 | template <typename KeyType, typename SnoopedType> class PipelineSnooper | ||
| 27 | { | ||
| 28 | public: | ||
| 29 | /// \brief Construct with the PipelineManager (used for snoopAllStages to optionally disable pipeline). | ||
| 30 | /// \param pipeline_mgr Non-null PipelineManager. | ||
| 31 | 1 | explicit PipelineSnooper(PipelineManager* pipeline_mgr) : | |
| 32 | 1 | pipeline_mgr_(pipeline_mgr) | |
| 33 | { | ||
| 34 | 1 | } | |
| 35 | |||
| 36 | /// \brief Register a stage's snoop method; StageType must have void snoop(const KeyType&, SnoopedType&). | ||
| 37 | /// \tparam StageType Stage-derived type that implements snoop(). | ||
| 38 | /// \param stage Stage to call snoop() on. | ||
| 39 | /// \throws DBException if this stage was already added. | ||
| 40 | 4 | template <typename StageType> void addStage(StageType* stage) | |
| 41 | { | ||
| 42 | static_assert(std::is_base_of<Stage, StageType>::value); | ||
| 43 | 4 | simdb_assert(snooped_stages_.insert(stage).second, "Already snooping stage!"); | |
| 44 | |||
| 45 | 4 | auto cb = std::bind(&StageType::snoop, stage, std::placeholders::_1, std::placeholders::_2); | |
| 46 | 4 | callbacks_.push_back(cb); | |
| 47 | 4 | } | |
| 48 | |||
| 49 | /// \brief Call each stage's snoop(key, snooped_obj) until one returns true or all are tried. | ||
| 50 | /// \param key Key to pass to snoop (e.g. lookup key). | ||
| 51 | /// \param snooped_obj Object that stages may fill; passed by reference to each snoop(). | ||
| 52 | /// \param disable_pipeline If true, use scopedDisableAll() while snooping so pipeline is paused. | ||
| 53 | /// \return true if any stage's snoop() returned true, false otherwise. | ||
| 54 | bool snoopAllStages(const KeyType& key, SnoopedType& snooped_obj, bool disable_pipeline = true); | ||
| 55 | |||
| 56 | private: | ||
| 57 | using Callback = std::function<bool(const KeyType&, SnoopedType&)>; | ||
| 58 | std::vector<Callback> callbacks_; | ||
| 59 | std::set<Stage*> snooped_stages_; | ||
| 60 | PipelineManager* pipeline_mgr_ = nullptr; | ||
| 61 | }; | ||
| 62 | |||
| 63 | } // namespace simdb::pipeline | ||
| 64 |