{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Control.Monad.Foil.Registry (
StripeIndex (..),
StripeSize (..),
StripeLayout (..),
stripesBelowZero,
stripesAbove,
RegionWidth (..),
RegionsPerUnit (..),
RegionLayout (..),
regionsAbove,
Registry,
emptyRegistry,
registrySize,
registerUnit,
) where
import Data.Binary (Binary)
import Data.Map (Map)
import qualified Data.Map as Map
import Control.Monad.Foil.Internal (NameRange (..), RawName)
newtype StripeIndex = StripeIndex Int
deriving newtype (StripeIndex -> StripeIndex -> Bool
(StripeIndex -> StripeIndex -> Bool)
-> (StripeIndex -> StripeIndex -> Bool) -> Eq StripeIndex
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: StripeIndex -> StripeIndex -> Bool
== :: StripeIndex -> StripeIndex -> Bool
$c/= :: StripeIndex -> StripeIndex -> Bool
/= :: StripeIndex -> StripeIndex -> Bool
Eq, Eq StripeIndex
Eq StripeIndex =>
(StripeIndex -> StripeIndex -> Ordering)
-> (StripeIndex -> StripeIndex -> Bool)
-> (StripeIndex -> StripeIndex -> Bool)
-> (StripeIndex -> StripeIndex -> Bool)
-> (StripeIndex -> StripeIndex -> Bool)
-> (StripeIndex -> StripeIndex -> StripeIndex)
-> (StripeIndex -> StripeIndex -> StripeIndex)
-> Ord StripeIndex
StripeIndex -> StripeIndex -> Bool
StripeIndex -> StripeIndex -> Ordering
StripeIndex -> StripeIndex -> StripeIndex
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: StripeIndex -> StripeIndex -> Ordering
compare :: StripeIndex -> StripeIndex -> Ordering
$c< :: StripeIndex -> StripeIndex -> Bool
< :: StripeIndex -> StripeIndex -> Bool
$c<= :: StripeIndex -> StripeIndex -> Bool
<= :: StripeIndex -> StripeIndex -> Bool
$c> :: StripeIndex -> StripeIndex -> Bool
> :: StripeIndex -> StripeIndex -> Bool
$c>= :: StripeIndex -> StripeIndex -> Bool
>= :: StripeIndex -> StripeIndex -> Bool
$cmax :: StripeIndex -> StripeIndex -> StripeIndex
max :: StripeIndex -> StripeIndex -> StripeIndex
$cmin :: StripeIndex -> StripeIndex -> StripeIndex
min :: StripeIndex -> StripeIndex -> StripeIndex
Ord, RawName -> StripeIndex -> ShowS
[StripeIndex] -> ShowS
StripeIndex -> String
(RawName -> StripeIndex -> ShowS)
-> (StripeIndex -> String)
-> ([StripeIndex] -> ShowS)
-> Show StripeIndex
forall a.
(RawName -> a -> ShowS)
-> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: RawName -> StripeIndex -> ShowS
showsPrec :: RawName -> StripeIndex -> ShowS
$cshow :: StripeIndex -> String
show :: StripeIndex -> String
$cshowList :: [StripeIndex] -> ShowS
showList :: [StripeIndex] -> ShowS
Show, ReadPrec [StripeIndex]
ReadPrec StripeIndex
RawName -> ReadS StripeIndex
ReadS [StripeIndex]
(RawName -> ReadS StripeIndex)
-> ReadS [StripeIndex]
-> ReadPrec StripeIndex
-> ReadPrec [StripeIndex]
-> Read StripeIndex
forall a.
(RawName -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: RawName -> ReadS StripeIndex
readsPrec :: RawName -> ReadS StripeIndex
$creadList :: ReadS [StripeIndex]
readList :: ReadS [StripeIndex]
$creadPrec :: ReadPrec StripeIndex
readPrec :: ReadPrec StripeIndex
$creadListPrec :: ReadPrec [StripeIndex]
readListPrec :: ReadPrec [StripeIndex]
Read, Get StripeIndex
[StripeIndex] -> Put
StripeIndex -> Put
(StripeIndex -> Put)
-> Get StripeIndex -> ([StripeIndex] -> Put) -> Binary StripeIndex
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
$cput :: StripeIndex -> Put
put :: StripeIndex -> Put
$cget :: Get StripeIndex
get :: Get StripeIndex
$cputList :: [StripeIndex] -> Put
putList :: [StripeIndex] -> Put
Binary)
newtype StripeSize = StripeSize Int
deriving newtype (StripeSize -> StripeSize -> Bool
(StripeSize -> StripeSize -> Bool)
-> (StripeSize -> StripeSize -> Bool) -> Eq StripeSize
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: StripeSize -> StripeSize -> Bool
== :: StripeSize -> StripeSize -> Bool
$c/= :: StripeSize -> StripeSize -> Bool
/= :: StripeSize -> StripeSize -> Bool
Eq, Eq StripeSize
Eq StripeSize =>
(StripeSize -> StripeSize -> Ordering)
-> (StripeSize -> StripeSize -> Bool)
-> (StripeSize -> StripeSize -> Bool)
-> (StripeSize -> StripeSize -> Bool)
-> (StripeSize -> StripeSize -> Bool)
-> (StripeSize -> StripeSize -> StripeSize)
-> (StripeSize -> StripeSize -> StripeSize)
-> Ord StripeSize
StripeSize -> StripeSize -> Bool
StripeSize -> StripeSize -> Ordering
StripeSize -> StripeSize -> StripeSize
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: StripeSize -> StripeSize -> Ordering
compare :: StripeSize -> StripeSize -> Ordering
$c< :: StripeSize -> StripeSize -> Bool
< :: StripeSize -> StripeSize -> Bool
$c<= :: StripeSize -> StripeSize -> Bool
<= :: StripeSize -> StripeSize -> Bool
$c> :: StripeSize -> StripeSize -> Bool
> :: StripeSize -> StripeSize -> Bool
$c>= :: StripeSize -> StripeSize -> Bool
>= :: StripeSize -> StripeSize -> Bool
$cmax :: StripeSize -> StripeSize -> StripeSize
max :: StripeSize -> StripeSize -> StripeSize
$cmin :: StripeSize -> StripeSize -> StripeSize
min :: StripeSize -> StripeSize -> StripeSize
Ord, RawName -> StripeSize -> ShowS
[StripeSize] -> ShowS
StripeSize -> String
(RawName -> StripeSize -> ShowS)
-> (StripeSize -> String)
-> ([StripeSize] -> ShowS)
-> Show StripeSize
forall a.
(RawName -> a -> ShowS)
-> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: RawName -> StripeSize -> ShowS
showsPrec :: RawName -> StripeSize -> ShowS
$cshow :: StripeSize -> String
show :: StripeSize -> String
$cshowList :: [StripeSize] -> ShowS
showList :: [StripeSize] -> ShowS
Show, ReadPrec [StripeSize]
ReadPrec StripeSize
RawName -> ReadS StripeSize
ReadS [StripeSize]
(RawName -> ReadS StripeSize)
-> ReadS [StripeSize]
-> ReadPrec StripeSize
-> ReadPrec [StripeSize]
-> Read StripeSize
forall a.
(RawName -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: RawName -> ReadS StripeSize
readsPrec :: RawName -> ReadS StripeSize
$creadList :: ReadS [StripeSize]
readList :: ReadS [StripeSize]
$creadPrec :: ReadPrec StripeSize
readPrec :: ReadPrec StripeSize
$creadListPrec :: ReadPrec [StripeSize]
readListPrec :: ReadPrec [StripeSize]
Read)
newtype StripeLayout = StripeLayout
{ StripeLayout -> StripeIndex -> NameRange
stripeRange :: StripeIndex -> NameRange
}
stripesBelowZero :: StripeSize -> StripeLayout
stripesBelowZero :: StripeSize -> StripeLayout
stripesBelowZero (StripeSize RawName
size) = (StripeIndex -> NameRange) -> StripeLayout
StripeLayout ((StripeIndex -> NameRange) -> StripeLayout)
-> (StripeIndex -> NameRange) -> StripeLayout
forall a b. (a -> b) -> a -> b
$ \(StripeIndex RawName
i) ->
let hi :: RawName
hi = RawName -> RawName
forall a. Num a => a -> a
negate (RawName
i RawName -> RawName -> RawName
forall a. Num a => a -> a -> a
* RawName
size) RawName -> RawName -> RawName
forall a. Num a => a -> a -> a
- RawName
1
in RawName -> RawName -> NameRange
NameRange (RawName
hi RawName -> RawName -> RawName
forall a. Num a => a -> a -> a
- RawName
size RawName -> RawName -> RawName
forall a. Num a => a -> a -> a
+ RawName
1) RawName
hi
stripesAbove
:: RawName
-> StripeSize
-> StripeLayout
stripesAbove :: RawName -> StripeSize -> StripeLayout
stripesAbove RawName
base (StripeSize RawName
size) = (StripeIndex -> NameRange) -> StripeLayout
StripeLayout ((StripeIndex -> NameRange) -> StripeLayout)
-> (StripeIndex -> NameRange) -> StripeLayout
forall a b. (a -> b) -> a -> b
$ \(StripeIndex RawName
i) ->
let lo :: RawName
lo = RawName
base RawName -> RawName -> RawName
forall a. Num a => a -> a -> a
+ RawName
i RawName -> RawName -> RawName
forall a. Num a => a -> a -> a
* RawName
size
in RawName -> RawName -> NameRange
NameRange RawName
lo (RawName
lo RawName -> RawName -> RawName
forall a. Num a => a -> a -> a
+ RawName
size RawName -> RawName -> RawName
forall a. Num a => a -> a -> a
- RawName
1)
type Registry name = Map name StripeIndex
emptyRegistry :: Registry name
emptyRegistry :: forall name. Registry name
emptyRegistry = Map name StripeIndex
forall k a. Map k a
Map.empty
registrySize :: Registry name -> Int
registrySize :: forall name. Registry name -> RawName
registrySize = Map name StripeIndex -> RawName
forall k a. Map k a -> RawName
Map.size
registerUnit
:: Ord name
=> name -> Registry name -> (Registry name, StripeIndex)
registerUnit :: forall name.
Ord name =>
name -> Registry name -> (Registry name, StripeIndex)
registerUnit name
name Registry name
registry = case name -> Registry name -> Maybe StripeIndex
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup name
name Registry name
registry of
Just StripeIndex
i -> (Registry name
registry, StripeIndex
i)
Maybe StripeIndex
Nothing ->
let i :: StripeIndex
i = RawName -> StripeIndex
StripeIndex (Registry name -> RawName
forall k a. Map k a -> RawName
Map.size Registry name
registry)
in (name -> StripeIndex -> Registry name -> Registry name
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert name
name StripeIndex
i Registry name
registry, StripeIndex
i)
newtype RegionWidth = RegionWidth Int
deriving newtype (RegionWidth -> RegionWidth -> Bool
(RegionWidth -> RegionWidth -> Bool)
-> (RegionWidth -> RegionWidth -> Bool) -> Eq RegionWidth
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: RegionWidth -> RegionWidth -> Bool
== :: RegionWidth -> RegionWidth -> Bool
$c/= :: RegionWidth -> RegionWidth -> Bool
/= :: RegionWidth -> RegionWidth -> Bool
Eq, Eq RegionWidth
Eq RegionWidth =>
(RegionWidth -> RegionWidth -> Ordering)
-> (RegionWidth -> RegionWidth -> Bool)
-> (RegionWidth -> RegionWidth -> Bool)
-> (RegionWidth -> RegionWidth -> Bool)
-> (RegionWidth -> RegionWidth -> Bool)
-> (RegionWidth -> RegionWidth -> RegionWidth)
-> (RegionWidth -> RegionWidth -> RegionWidth)
-> Ord RegionWidth
RegionWidth -> RegionWidth -> Bool
RegionWidth -> RegionWidth -> Ordering
RegionWidth -> RegionWidth -> RegionWidth
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: RegionWidth -> RegionWidth -> Ordering
compare :: RegionWidth -> RegionWidth -> Ordering
$c< :: RegionWidth -> RegionWidth -> Bool
< :: RegionWidth -> RegionWidth -> Bool
$c<= :: RegionWidth -> RegionWidth -> Bool
<= :: RegionWidth -> RegionWidth -> Bool
$c> :: RegionWidth -> RegionWidth -> Bool
> :: RegionWidth -> RegionWidth -> Bool
$c>= :: RegionWidth -> RegionWidth -> Bool
>= :: RegionWidth -> RegionWidth -> Bool
$cmax :: RegionWidth -> RegionWidth -> RegionWidth
max :: RegionWidth -> RegionWidth -> RegionWidth
$cmin :: RegionWidth -> RegionWidth -> RegionWidth
min :: RegionWidth -> RegionWidth -> RegionWidth
Ord, RawName -> RegionWidth -> ShowS
[RegionWidth] -> ShowS
RegionWidth -> String
(RawName -> RegionWidth -> ShowS)
-> (RegionWidth -> String)
-> ([RegionWidth] -> ShowS)
-> Show RegionWidth
forall a.
(RawName -> a -> ShowS)
-> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: RawName -> RegionWidth -> ShowS
showsPrec :: RawName -> RegionWidth -> ShowS
$cshow :: RegionWidth -> String
show :: RegionWidth -> String
$cshowList :: [RegionWidth] -> ShowS
showList :: [RegionWidth] -> ShowS
Show, ReadPrec [RegionWidth]
ReadPrec RegionWidth
RawName -> ReadS RegionWidth
ReadS [RegionWidth]
(RawName -> ReadS RegionWidth)
-> ReadS [RegionWidth]
-> ReadPrec RegionWidth
-> ReadPrec [RegionWidth]
-> Read RegionWidth
forall a.
(RawName -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: RawName -> ReadS RegionWidth
readsPrec :: RawName -> ReadS RegionWidth
$creadList :: ReadS [RegionWidth]
readList :: ReadS [RegionWidth]
$creadPrec :: ReadPrec RegionWidth
readPrec :: ReadPrec RegionWidth
$creadListPrec :: ReadPrec [RegionWidth]
readListPrec :: ReadPrec [RegionWidth]
Read)
newtype RegionsPerUnit = RegionsPerUnit Int
deriving newtype (RegionsPerUnit -> RegionsPerUnit -> Bool
(RegionsPerUnit -> RegionsPerUnit -> Bool)
-> (RegionsPerUnit -> RegionsPerUnit -> Bool) -> Eq RegionsPerUnit
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: RegionsPerUnit -> RegionsPerUnit -> Bool
== :: RegionsPerUnit -> RegionsPerUnit -> Bool
$c/= :: RegionsPerUnit -> RegionsPerUnit -> Bool
/= :: RegionsPerUnit -> RegionsPerUnit -> Bool
Eq, Eq RegionsPerUnit
Eq RegionsPerUnit =>
(RegionsPerUnit -> RegionsPerUnit -> Ordering)
-> (RegionsPerUnit -> RegionsPerUnit -> Bool)
-> (RegionsPerUnit -> RegionsPerUnit -> Bool)
-> (RegionsPerUnit -> RegionsPerUnit -> Bool)
-> (RegionsPerUnit -> RegionsPerUnit -> Bool)
-> (RegionsPerUnit -> RegionsPerUnit -> RegionsPerUnit)
-> (RegionsPerUnit -> RegionsPerUnit -> RegionsPerUnit)
-> Ord RegionsPerUnit
RegionsPerUnit -> RegionsPerUnit -> Bool
RegionsPerUnit -> RegionsPerUnit -> Ordering
RegionsPerUnit -> RegionsPerUnit -> RegionsPerUnit
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: RegionsPerUnit -> RegionsPerUnit -> Ordering
compare :: RegionsPerUnit -> RegionsPerUnit -> Ordering
$c< :: RegionsPerUnit -> RegionsPerUnit -> Bool
< :: RegionsPerUnit -> RegionsPerUnit -> Bool
$c<= :: RegionsPerUnit -> RegionsPerUnit -> Bool
<= :: RegionsPerUnit -> RegionsPerUnit -> Bool
$c> :: RegionsPerUnit -> RegionsPerUnit -> Bool
> :: RegionsPerUnit -> RegionsPerUnit -> Bool
$c>= :: RegionsPerUnit -> RegionsPerUnit -> Bool
>= :: RegionsPerUnit -> RegionsPerUnit -> Bool
$cmax :: RegionsPerUnit -> RegionsPerUnit -> RegionsPerUnit
max :: RegionsPerUnit -> RegionsPerUnit -> RegionsPerUnit
$cmin :: RegionsPerUnit -> RegionsPerUnit -> RegionsPerUnit
min :: RegionsPerUnit -> RegionsPerUnit -> RegionsPerUnit
Ord, RawName -> RegionsPerUnit -> ShowS
[RegionsPerUnit] -> ShowS
RegionsPerUnit -> String
(RawName -> RegionsPerUnit -> ShowS)
-> (RegionsPerUnit -> String)
-> ([RegionsPerUnit] -> ShowS)
-> Show RegionsPerUnit
forall a.
(RawName -> a -> ShowS)
-> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: RawName -> RegionsPerUnit -> ShowS
showsPrec :: RawName -> RegionsPerUnit -> ShowS
$cshow :: RegionsPerUnit -> String
show :: RegionsPerUnit -> String
$cshowList :: [RegionsPerUnit] -> ShowS
showList :: [RegionsPerUnit] -> ShowS
Show, ReadPrec [RegionsPerUnit]
ReadPrec RegionsPerUnit
RawName -> ReadS RegionsPerUnit
ReadS [RegionsPerUnit]
(RawName -> ReadS RegionsPerUnit)
-> ReadS [RegionsPerUnit]
-> ReadPrec RegionsPerUnit
-> ReadPrec [RegionsPerUnit]
-> Read RegionsPerUnit
forall a.
(RawName -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: RawName -> ReadS RegionsPerUnit
readsPrec :: RawName -> ReadS RegionsPerUnit
$creadList :: ReadS [RegionsPerUnit]
readList :: ReadS [RegionsPerUnit]
$creadPrec :: ReadPrec RegionsPerUnit
readPrec :: ReadPrec RegionsPerUnit
$creadListPrec :: ReadPrec [RegionsPerUnit]
readListPrec :: ReadPrec [RegionsPerUnit]
Read)
data RegionLayout = RegionLayout
{ RegionLayout -> StripeIndex -> NameRange
firstRegionOf :: StripeIndex -> NameRange
, RegionLayout -> NameRange -> NameRange
nextRegion :: NameRange -> NameRange
}
regionsAbove :: RawName -> RegionsPerUnit -> RegionWidth -> RegionLayout
regionsAbove :: RawName -> RegionsPerUnit -> RegionWidth -> RegionLayout
regionsAbove RawName
base (RegionsPerUnit RawName
perUnit) (RegionWidth RawName
w) = RegionLayout
{ firstRegionOf :: StripeIndex -> NameRange
firstRegionOf = \(StripeIndex RawName
i) ->
RawName -> RawName -> NameRange
NameRange (RawName
base RawName -> RawName -> RawName
forall a. Num a => a -> a -> a
+ RawName
i RawName -> RawName -> RawName
forall a. Num a => a -> a -> a
* RawName
perUnit RawName -> RawName -> RawName
forall a. Num a => a -> a -> a
* RawName
w) RawName
forall a. Bounded a => a
maxBound
, nextRegion :: NameRange -> NameRange
nextRegion = \(NameRange RawName
lo RawName
_) -> RawName -> RawName -> NameRange
NameRange (RawName
lo RawName -> RawName -> RawName
forall a. Num a => a -> a -> a
+ RawName
w) RawName
forall a. Bounded a => a
maxBound
}