module Ecluse.Core.Registry.Sweep.Pacing.Internal (
cycleAllowance,
nominalPackagePace,
budgetFraction,
ceilingsFor,
cycleDemand,
BudgetShortfall (..),
) where
import Data.Map.Strict qualified as Map
import Data.Ratio ((%))
import Data.Time (NominalDiffTime)
import Ecluse.Core.Registry.Maintenance.Budget (
QuotaDimension,
RequestTally,
StoreBudget (bgCosts, bgQuotas),
smallestQuota,
tallyCounts,
)
import Ecluse.Core.Registry.Sweep.Types (
SweepPacing (swpBudgetFraction, swpChunkPause, swpChunkSize, swpCyclePause, swpCycleWindow),
minimumChunkPause,
)
cycleAllowance :: SweepPacing -> Rational
cycleAllowance :: SweepPacing -> Rational
cycleAllowance SweepPacing
pacing = (NominalDiffTime -> Rational
forall a. Real a => a -> Rational
toRational (SweepPacing -> NominalDiffTime
swpCycleWindow SweepPacing
pacing) Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
- NominalDiffTime -> Rational
forall a. Real a => a -> Rational
toRational (SweepPacing -> NominalDiffTime
swpCyclePause SweepPacing
pacing)) Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
2
nominalPackagePace :: Int -> NominalDiffTime -> Rational
nominalPackagePace :: Int -> NominalDiffTime -> Rational
nominalPackagePace Int
chunkSize NominalDiffTime
chunkPause =
Int -> Rational
forall a. Real a => a -> Rational
toRational (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
1 Int
chunkSize) Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ NominalDiffTime -> Rational
forall a. Real a => a -> Rational
toRational (NominalDiffTime -> NominalDiffTime -> NominalDiffTime
forall a. Ord a => a -> a -> a
max NominalDiffTime
minimumChunkPause NominalDiffTime
chunkPause)
budgetFraction :: SweepPacing -> StoreBudget -> Rational
budgetFraction :: SweepPacing -> StoreBudget -> Rational
budgetFraction SweepPacing
pacing StoreBudget
budget = Rational -> Maybe Rational -> Rational
forall a. a -> Maybe a -> a
fromMaybe Rational
computed (SweepPacing -> Maybe Rational
swpBudgetFraction SweepPacing
pacing)
where
computed :: Rational
computed = Rational -> (Rational -> Rational) -> Maybe Rational -> Rational
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Rational
fractionCeiling Rational -> Rational
implied (StoreBudget -> Maybe Rational
smallestQuota StoreBudget
budget)
implied :: Rational -> Rational
implied Rational
smallest
| Rational
smallest Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
<= Rational
0 = Rational
fractionCeiling
| Bool
otherwise = Rational -> Rational -> Rational
forall a. Ord a => a -> a -> a
min Rational
fractionCeiling (SweepPacing -> Rational
pacingPace SweepPacing
pacing Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
smallest)
pacingPace :: SweepPacing -> Rational
pacingPace :: SweepPacing -> Rational
pacingPace SweepPacing
pacing = Int -> NominalDiffTime -> Rational
nominalPackagePace (SweepPacing -> Int
swpChunkSize SweepPacing
pacing) (SweepPacing -> NominalDiffTime
swpChunkPause SweepPacing
pacing)
fractionCeiling :: Rational
fractionCeiling :: Rational
fractionCeiling = Integer
1 Integer -> Integer -> Rational
forall a. Integral a => a -> a -> Ratio a
% Integer
2
ceilingsFor :: Rational -> StoreBudget -> Map QuotaDimension Rational
ceilingsFor :: Rational -> StoreBudget -> Map QuotaDimension Rational
ceilingsFor Rational
fraction = (Rational -> Rational)
-> Map QuotaDimension Rational -> Map QuotaDimension Rational
forall a b k. (a -> b) -> Map k a -> Map k b
Map.map (Rational
fraction Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
*) (Map QuotaDimension Rational -> Map QuotaDimension Rational)
-> (StoreBudget -> Map QuotaDimension Rational)
-> StoreBudget
-> Map QuotaDimension Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StoreBudget -> Map QuotaDimension Rational
bgQuotas
cycleDemand :: Map QuotaDimension Rational -> StoreBudget -> RequestTally -> Rational
cycleDemand :: Map QuotaDimension Rational
-> StoreBudget -> RequestTally -> Rational
cycleDemand Map QuotaDimension Rational
ceilings StoreBudget
budget RequestTally
tally =
[Rational] -> Rational
forall a (f :: * -> *). (Foldable f, Num a) => f a -> a
sum [Int -> Rational
forall a. Real a => a -> Rational
toRational Int
count Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* RequestKind -> Rational
requestSeconds RequestKind
kind | (RequestKind
kind, Int
count) <- RequestTally -> [(RequestKind, Int)]
tallyCounts RequestTally
tally]
where
requestSeconds :: RequestKind -> Rational
requestSeconds RequestKind
kind =
(Rational -> Rational -> Rational)
-> Rational -> [Rational] -> Rational
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr
Rational -> Rational -> Rational
forall a. Ord a => a -> a -> a
max
Rational
0
[ Rational
cost Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
limit
| (QuotaDimension
dimension, Rational
cost) <- Map QuotaDimension Rational -> [(QuotaDimension, Rational)]
forall k a. Map k a -> [(k, a)]
Map.toList (Map QuotaDimension Rational
-> RequestKind
-> Map RequestKind (Map QuotaDimension Rational)
-> Map QuotaDimension Rational
forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault Map QuotaDimension Rational
forall k a. Map k a
Map.empty RequestKind
kind (StoreBudget -> Map RequestKind (Map QuotaDimension Rational)
bgCosts StoreBudget
budget))
, Just Rational
limit <- [QuotaDimension -> Map QuotaDimension Rational -> Maybe Rational
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup QuotaDimension
dimension Map QuotaDimension Rational
ceilings]
, Rational
limit Rational -> Rational -> Bool
forall a. Ord a => a -> a -> Bool
> Rational
0
]
data BudgetShortfall
=
WorkFillsAllowance
|
NeedsFraction Rational
deriving stock (BudgetShortfall -> BudgetShortfall -> Bool
(BudgetShortfall -> BudgetShortfall -> Bool)
-> (BudgetShortfall -> BudgetShortfall -> Bool)
-> Eq BudgetShortfall
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: BudgetShortfall -> BudgetShortfall -> Bool
== :: BudgetShortfall -> BudgetShortfall -> Bool
$c/= :: BudgetShortfall -> BudgetShortfall -> Bool
/= :: BudgetShortfall -> BudgetShortfall -> Bool
Eq, Int -> BudgetShortfall -> ShowS
[BudgetShortfall] -> ShowS
BudgetShortfall -> String
(Int -> BudgetShortfall -> ShowS)
-> (BudgetShortfall -> String)
-> ([BudgetShortfall] -> ShowS)
-> Show BudgetShortfall
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> BudgetShortfall -> ShowS
showsPrec :: Int -> BudgetShortfall -> ShowS
$cshow :: BudgetShortfall -> String
show :: BudgetShortfall -> String
$cshowList :: [BudgetShortfall] -> ShowS
showList :: [BudgetShortfall] -> ShowS
Show)