{-# LANGUAGE RecordWildCards #-}
module Network.Control.Flow (
defaultMaxStreams,
defaultMaxStreamData,
defaultMaxData,
TxFlow (..),
newTxFlow,
txWindowSize,
WindowSize,
RxFlow (..),
newRxFlow,
FlowControlType (..),
maybeOpenRxWindow,
checkRxLimit,
) where
import Data.Bits
defaultMaxStreams :: Int
defaultMaxStreams :: Int
defaultMaxStreams = Int
64
defaultMaxStreamData :: Int
defaultMaxStreamData :: Int
defaultMaxStreamData = Int
262144
defaultMaxData :: Int
defaultMaxData :: Int
defaultMaxData = Int
1048576
type WindowSize = Int
data TxFlow = TxFlow
{ TxFlow -> Int
txfSent :: Int
, TxFlow -> Int
txfLimit :: Int
}
deriving (Int -> TxFlow -> ShowS
[TxFlow] -> ShowS
TxFlow -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TxFlow] -> ShowS
$cshowList :: [TxFlow] -> ShowS
show :: TxFlow -> String
$cshow :: TxFlow -> String
showsPrec :: Int -> TxFlow -> ShowS
$cshowsPrec :: Int -> TxFlow -> ShowS
Show)
newTxFlow :: WindowSize -> TxFlow
newTxFlow :: Int -> TxFlow
newTxFlow Int
win = Int -> Int -> TxFlow
TxFlow Int
0 Int
win
txWindowSize :: TxFlow -> WindowSize
txWindowSize :: TxFlow -> Int
txWindowSize TxFlow{Int
txfLimit :: Int
txfSent :: Int
txfLimit :: TxFlow -> Int
txfSent :: TxFlow -> Int
..} = Int
txfLimit forall a. Num a => a -> a -> a
- Int
txfSent
data RxFlow = RxFlow
{ RxFlow -> Int
rxfWindow :: WindowSize
, RxFlow -> Int
rxfConsumed :: Int
, RxFlow -> Int
rxfReceived :: Int
, RxFlow -> Int
rxfLimit :: Int
}
deriving (Int -> RxFlow -> ShowS
[RxFlow] -> ShowS
RxFlow -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RxFlow] -> ShowS
$cshowList :: [RxFlow] -> ShowS
show :: RxFlow -> String
$cshow :: RxFlow -> String
showsPrec :: Int -> RxFlow -> ShowS
$cshowsPrec :: Int -> RxFlow -> ShowS
Show)
newRxFlow :: WindowSize -> RxFlow
newRxFlow :: Int -> RxFlow
newRxFlow Int
win = Int -> Int -> Int -> Int -> RxFlow
RxFlow Int
win Int
0 Int
0 Int
win
data FlowControlType
=
FCTWindowUpdate
|
FCTMaxData
maybeOpenRxWindow
:: Int
-> FlowControlType
-> RxFlow
-> (RxFlow, Maybe Int)
maybeOpenRxWindow :: Int -> FlowControlType -> RxFlow -> (RxFlow, Maybe Int)
maybeOpenRxWindow Int
consumed FlowControlType
fct flow :: RxFlow
flow@RxFlow{Int
rxfLimit :: Int
rxfReceived :: Int
rxfConsumed :: Int
rxfWindow :: Int
rxfLimit :: RxFlow -> Int
rxfReceived :: RxFlow -> Int
rxfConsumed :: RxFlow -> Int
rxfWindow :: RxFlow -> Int
..}
| Int
available forall a. Ord a => a -> a -> Bool
< Int
threshold =
let limit :: Int
limit = Int
consumed' forall a. Num a => a -> a -> a
+ Int
rxfWindow
flow' :: RxFlow
flow' =
RxFlow
flow
{ rxfConsumed :: Int
rxfConsumed = Int
consumed'
, rxfLimit :: Int
rxfLimit = Int
limit
}
update :: Int
update = case FlowControlType
fct of
FlowControlType
FCTWindowUpdate -> Int
limit forall a. Num a => a -> a -> a
- Int
rxfLimit
FlowControlType
FCTMaxData -> Int
limit
in (RxFlow
flow', forall a. a -> Maybe a
Just Int
update)
| Bool
otherwise =
let flow' :: RxFlow
flow' = RxFlow
flow{rxfConsumed :: Int
rxfConsumed = Int
consumed'}
in (RxFlow
flow', forall a. Maybe a
Nothing)
where
available :: Int
available = Int
rxfLimit forall a. Num a => a -> a -> a
- Int
rxfReceived
threshold :: Int
threshold = Int
rxfWindow forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
1
consumed' :: Int
consumed' = Int
rxfConsumed forall a. Num a => a -> a -> a
+ Int
consumed
checkRxLimit
:: Int
-> RxFlow
-> (RxFlow, Bool)
checkRxLimit :: Int -> RxFlow -> (RxFlow, Bool)
checkRxLimit Int
received flow :: RxFlow
flow@RxFlow{Int
rxfLimit :: Int
rxfReceived :: Int
rxfConsumed :: Int
rxfWindow :: Int
rxfLimit :: RxFlow -> Int
rxfReceived :: RxFlow -> Int
rxfConsumed :: RxFlow -> Int
rxfWindow :: RxFlow -> Int
..}
| Int
received' forall a. Ord a => a -> a -> Bool
<= Int
rxfLimit =
let flow' :: RxFlow
flow' = RxFlow
flow{rxfReceived :: Int
rxfReceived = Int
received'}
in (RxFlow
flow', Bool
True)
| Bool
otherwise = (RxFlow
flow, Bool
False)
where
received' :: Int
received' = Int
rxfReceived forall a. Num a => a -> a -> a
+ Int
received