1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//! Module for Server definition
//!
//! and functions to be used with one or multiple Servers

use crate::curve::AggregateExt;

use crate::iterators::server::constrained_demand::ConstrainedServerDemandIterator;
use crate::iterators::{CurveIterator, ReclassifyIterator};
use crate::task::Task;
use crate::time::TimeUnit;

/// Marker Type for aggregated server demand curve
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Copy, Clone)]
pub struct AggregatedServerDemand;

/// Marker Type for constrained server demand curve
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Copy, Clone)]
pub struct ConstrainedServerDemand;

/// Marker Type for aggregated higher priority server demand curve
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Copy, Clone)]
pub struct HigherPriorityServerDemand;

/// Marker Type for aggregated higher priority server actual Execution curve
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Copy, Clone)]
pub struct HigherPriorityServerExecution;

/// Marker Type for unconstrained server demand curve
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Copy, Clone)]
pub struct UnconstrainedServerExecution;

/// Marker Type for constrained server execution curve
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Copy, Clone)]
pub struct ActualServerExecution;

/// Type Representing a Server
/// with a given set of tasks,
/// a capacity for fulfilling demand,
/// a replenishment interval for how
/// often the capacity is restored
/// ,and a server type determining if the
/// capacity is available only at the beginning of the interval
/// or until it is used up
#[derive(Debug, Clone)]
pub struct Server<'a> {
    /// The Tasks that produce Demand for this Server
    /// Sorted by priority with lower index equalling higher priority
    pub tasks: &'a [Task],
    /// The properties of the Server
    pub properties: ServerProperties,
}

/// The Properties of a server
#[derive(Debug, Clone, Copy)]
pub struct ServerProperties {
    /// The capacity for fulfilling Demand
    pub capacity: TimeUnit,
    /// How often the capacity is available
    pub interval: TimeUnit,
    /// How the available capacity behaves
    pub server_type: ServerKind,
}

/// The Type of a Server
#[derive(Debug, Clone, Copy)]
pub enum ServerKind {
    /// Indicated that the Server is a Deferrable Server
    /// as described/defined in Section 5.2 Paragraph 2 of the paper
    Deferrable,
    /// Indicates that the Server is a Periodic Server
    /// as described/defined in Section 5.2 Paragraph 4 of the paper
    Periodic,
}

impl<'a> Server<'a> {
    /// Create a new Server with the given Tasks and properties
    #[must_use]
    pub const fn new(
        tasks: &'a [Task],
        capacity: TimeUnit,
        interval: TimeUnit,
        server_type: ServerKind,
    ) -> Self {
        Server {
            tasks,
            properties: ServerProperties {
                capacity,
                interval,
                server_type,
            },
        }
    }

    /// Get a a reference to a slice of the Servers contained Tasks
    #[must_use]
    pub const fn as_tasks(&self) -> &'a [Task] {
        self.tasks
    }

    /// Calculate the aggregated demand Curve of a given Server up to a specified limit
    /// As defined in Definition 11. in the paper
    #[must_use]
    pub fn aggregated_demand_curve_iter(
        &self,
    ) -> impl CurveIterator<CurveKind = AggregatedServerDemand> + Clone + '_ {
        self.tasks
            .iter()
            .map(|task| task.into_iter())
            .aggregate::<ReclassifyIterator<_, _>>()
    }

    /// Calculate the constrained demand curve
    #[must_use]
    pub fn constraint_demand_curve_iter(
        &self,
    ) -> impl CurveIterator<CurveKind = ConstrainedServerDemand> + Clone + '_ {
        ConstrainedServerDemandIterator::new(self.properties, self.aggregated_demand_curve_iter())
    }
}