{-# LANGUAGE RecordWildCards #-}
module Network.Control.Flow (
defaultMaxStreams,
defaultMaxStreamData,
defaultMaxData,
TxFlow (..),
newTxFlow,
txWindowSize,
WindowSize,
RxFlow (..),
newRxFlow,
rxWindowSize,
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
defaultMaxStreamData Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
defaultMaxStreams
type WindowSize = Int
data TxFlow = TxFlow
{ TxFlow -> Int
txfSent :: Int
, TxFlow -> Int
txfLimit :: Int
}
deriving (TxFlow -> TxFlow -> Bool
(TxFlow -> TxFlow -> Bool)
-> (TxFlow -> TxFlow -> Bool) -> Eq TxFlow
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TxFlow -> TxFlow -> Bool
== :: TxFlow -> TxFlow -> Bool
$c/= :: TxFlow -> TxFlow -> Bool
/= :: TxFlow -> TxFlow -> Bool
Eq, Int -> TxFlow -> ShowS
[TxFlow] -> ShowS
TxFlow -> String
(Int -> TxFlow -> ShowS)
-> (TxFlow -> String) -> ([TxFlow] -> ShowS) -> Show TxFlow
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TxFlow -> ShowS
showsPrec :: Int -> TxFlow -> ShowS
$cshow :: TxFlow -> String
show :: TxFlow -> String
$cshowList :: [TxFlow] -> ShowS
showList :: [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
txfSent :: TxFlow -> Int
txfLimit :: TxFlow -> Int
txfSent :: Int
txfLimit :: Int
..} = Int
txfLimit Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
txfSent
data RxFlow = RxFlow
{ RxFlow -> Int
rxfBufSize :: Int
, RxFlow -> Int
rxfConsumed :: Int
, RxFlow -> Int
rxfReceived :: Int
, RxFlow -> Int
rxfLimit :: Int
}
deriving (RxFlow -> RxFlow -> Bool
(RxFlow -> RxFlow -> Bool)
-> (RxFlow -> RxFlow -> Bool) -> Eq RxFlow
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: RxFlow -> RxFlow -> Bool
== :: RxFlow -> RxFlow -> Bool
$c/= :: RxFlow -> RxFlow -> Bool
/= :: RxFlow -> RxFlow -> Bool
Eq, Int -> RxFlow -> ShowS
[RxFlow] -> ShowS
RxFlow -> String
(Int -> RxFlow -> ShowS)
-> (RxFlow -> String) -> ([RxFlow] -> ShowS) -> Show RxFlow
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> RxFlow -> ShowS
showsPrec :: Int -> RxFlow -> ShowS
$cshow :: RxFlow -> String
show :: RxFlow -> String
$cshowList :: [RxFlow] -> ShowS
showList :: [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
rxWindowSize :: RxFlow -> WindowSize
rxWindowSize :: RxFlow -> Int
rxWindowSize RxFlow{Int
rxfBufSize :: RxFlow -> Int
rxfConsumed :: RxFlow -> Int
rxfReceived :: RxFlow -> Int
rxfLimit :: RxFlow -> Int
rxfBufSize :: Int
rxfConsumed :: Int
rxfReceived :: Int
rxfLimit :: Int
..} = Int
rxfLimit Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
rxfReceived
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
rxfBufSize :: RxFlow -> Int
rxfConsumed :: RxFlow -> Int
rxfReceived :: RxFlow -> Int
rxfLimit :: RxFlow -> Int
rxfBufSize :: Int
rxfConsumed :: Int
rxfReceived :: Int
rxfLimit :: Int
..}
| Int
winUpdate Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
threshold =
let flow' :: RxFlow
flow' =
RxFlow
flow
{ rxfConsumed = rxfConsumed'
, rxfLimit = rxfLimit'
}
update :: Int
update = case FlowControlType
fct of
FlowControlType
FCTWindowUpdate -> Int
winUpdate
FlowControlType
FCTMaxData -> Int
rxfLimit'
in (RxFlow
flow', Int -> Maybe Int
forall a. a -> Maybe a
Just Int
update)
| Bool
otherwise =
let flow' :: RxFlow
flow' = RxFlow
flow{rxfConsumed = rxfConsumed'}
in (RxFlow
flow', Maybe Int
forall a. Maybe a
Nothing)
where
rxfConsumed' :: Int
rxfConsumed' = Int
rxfConsumed Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
consumed
threshold :: Int
threshold = Int
rxfBufSize Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`unsafeShiftR` Int
1
rxfLimit' :: Int
rxfLimit' = Int
rxfConsumed' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
rxfBufSize
winUpdate :: Int
winUpdate = Int
rxfLimit' Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
rxfLimit
checkRxLimit
:: Int
-> RxFlow
-> (RxFlow, Bool)
checkRxLimit :: Int -> RxFlow -> (RxFlow, Bool)
checkRxLimit Int
received flow :: RxFlow
flow@RxFlow{Int
rxfBufSize :: RxFlow -> Int
rxfConsumed :: RxFlow -> Int
rxfReceived :: RxFlow -> Int
rxfLimit :: RxFlow -> Int
rxfBufSize :: Int
rxfConsumed :: Int
rxfReceived :: Int
rxfLimit :: Int
..}
| Int
received' Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
rxfLimit =
let flow' :: RxFlow
flow' = RxFlow
flow{rxfReceived = received'}
in (RxFlow
flow', Bool
True)
| Bool
otherwise = (RxFlow
flow, Bool
False)
where
received' :: Int
received' = Int
rxfReceived Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
received