xaizek / etabench (License: GPLv3) (since 2022-09-08)
Benchmark for algorithms that compute I/O ETA
<root> / src / profiles.hpp (8db985390938c602018c3e75c2450ba735df4440) (3,933B) (mode 100644) [raw]
// 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__
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/etabench

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/etabench

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master