// etabench // Copyright (C) 2022 xaizek <xaizek@posteo.net> // // This file is part of etabench. // // etabench is free software: you can redistribute it and/or modify // it under the terms of version 3 of the GNU General Public License // as published by the Free Software Foundation. // // etabench is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with etabench. If not, see <https://www.gnu.org/licenses/>. #ifndef ETABENCH__PROFILES_HPP__ #define ETABENCH__PROFILES_HPP__ #include <cmath> #include <random> #include <string> #include <vector> #include <fmt/core.h> #include "core.hpp" class ConstantProfile : public Profile { public: explicit ConstantProfile(int speed) : speed(speed) { } public: virtual std::string getName() const { return "Constant"; } virtual int operator()(int time) override { return speed; } private: int speed; }; class LinearProfile : public Profile { public: explicit LinearProfile(int size, int angle) : angle(angle) { dt = std::tan(std::abs(angle)*2*M_PI/360); if (angle < 0) { from = std::ceil(std::sqrt(2*size*dt)); dt = -dt; } else { from = 0; } } public: virtual std::string getName() const override { return fmt::format("{} {}°", angle < 0 ? "Falling" : "Raising", std::abs(angle)); } virtual int operator()(int time) override { return std::ceil(from + time*dt); } private: int from; int angle; float dt; }; class SawProfile : public Profile { public: explicit SawProfile(int period) : period(period) { } public: virtual std::string getName() const override { return "Saw"; } virtual int operator()(int time) override { return time % period; } private: int period; }; class SquareProfile : public Profile { public: explicit SquareProfile(int period) : period(period) { } public: virtual std::string getName() const override { return "Square"; } virtual int operator()(int time) override { return (time%period < period/2) ? period : 0; } private: int period; }; class StepProfile : public Profile { public: explicit StepProfile(int period) : period(period) { } public: virtual std::string getName() const override { return "Step"; } virtual int operator()(int time) override { return (time/period)*period; } private: int period; }; class RandomProfile : public Profile { public: RandomProfile(int seed, int max) : seed(seed), g(seed), distrib(0, max) { } public: virtual std::string getName() const override { return "Random"; } virtual void reset() override { g.seed(seed); }; virtual int operator()(int time) override { return distrib(g); } private: int seed; std::mt19937 g; std::uniform_int_distribution<int> distrib; }; // This was derived from log of copying 13 GiB onto HDD with datasync() after // each 256 MiB. class ReplayProfile : public Profile { public: ReplayProfile() { speeds = { 20, 10, 20, 30, 40, 30, 30, 40, 20, 30, 40, 30, 20, 40, 30, 50, 20, 30, 40, 30, 20, 30, 40, 20, 30, 50, 20, 30, 40, 30, 30, 40, 30, 20, 50, 20, 30, 40, 30, 20, 50, 30, 20, }; } public: virtual std::string getName() const override { return "Replay"; } virtual int operator()(int time) override { if (time%2 == 1) { return 0; } return speeds[(time/2)%speeds.size()]; } private: std::vector<int> speeds; }; #endif // ETABENCH__PROFILES_HPP__