#include #include #include #include namespace bench { using clock_t = std::chrono::system_clock; struct SensorSample { unsigned sensor_id; clock_t::time_point timestamp; std::string payload; }; struct SensorReaderMockup { unsigned sensor_id; clock_t::duration interval; clock_t::time_point last_sample; SensorSample next() { SensorSample rtrn { sensor_id, last_sample, "some payload longer than SSO" }; last_sample += interval; return rtrn; } }; struct SampleCompare { bool operator()(const SensorSample& left, const SensorSample& right) const noexcept { return left.timestamp > right.timestamp; } }; using min_heap_t = std::priority_queue< SensorSample, std::vector, SampleCompare>; void run_heap(SensorReaderMockup* sensor_states, unsigned sensors, int events) { min_heap_t heap; /* * Read first sample of each sensor */ for(std::size_t i = 0; i < sensors; ++i) heap.push(sensor_states[i].next()); for(int i = 0; i < events; ++i) { /* * Retrieve oldest sample for transfer to output */ SensorSample oldest = std::move(heap.top()); heap.pop(); /* * Read next sample from this particular sensor. * Real code would obviously have to check whether sensor is at * end-of-file */ heap.push(sensor_states[oldest.sensor_id].next()); } } /** * Initializes sensors with pseudo-random sampling periods */ std::vector init_state(unsigned sensors) { std::vector rtrn; rtrn.reserve(sensors); std::default_random_engine rng; std::uniform_int_distribution distr {1, 100}; for(unsigned i = 0; i < sensors; ++i) { clock_t::duration interval {distr(rng)}; clock_t::time_point last_sample = clock_t::time_point{} + interval; rtrn.push_back(SensorReaderMockup{i, interval, last_sample}); } return rtrn; } } // namespace bench int main() { using namespace bench; unsigned sensors = 60'000; int events = 100'000'000; std::vector sensor_states = init_state(sensors); run_heap(sensor_states.data(), sensors, events); }