module Network.QUIC.Stream.Skew ( Skew(..) , empty , insert , deleteMin , deleteMinIf -- , deleteMin' -- , showSkew ) where import Data.Maybe import Data.Sequence (Seq, (><)) import qualified Data.Sequence as Seq import Prelude hiding (minimum) import Network.QUIC.Stream.Frag ---------------------------------------------------------------- data Skew a = Leaf | Node (Skew a) (Seq a) (Skew a) deriving Show empty :: Skew a empty = Leaf ---------------------------------------------------------------- -- | Insertion. Worst-case: O(N), amortized: O(log N). insert :: Frag a => a -> Skew a -> Skew a insert x t = merge (Node Leaf (Seq.singleton x) Leaf) t ---------------------------------------------------------------- -- | Finding the minimum element. Worst-case: O(1). minimum :: Skew a -> Maybe (Seq a) minimum Leaf = Nothing minimum (Node _ f _) = Just f ---------------------------------------------------------------- -- | Deleting the minimum element. Worst-case: O(N), amortized: O(log N). deleteMin' :: Frag a => Skew a -> Skew a deleteMin' Leaf = Leaf deleteMin' (Node l _ r) = merge l r deleteMin :: Frag a => Skew a -> (Skew a, Maybe (Seq a)) deleteMin h = (deleteMin' h, minimum h) deleteMinIf :: Frag a => Int -> Skew a -> (Skew a, Maybe (Seq a)) deleteMinIf off h = case minimum h of jf@(Just f) | currOff f == off -> (deleteMin' h, jf) | currOff f < off && off < nextOff f -> (deleteMin' h, shrink off <$> jf) | nextOff f <= off -> (deleteMin' h, Nothing) _ -> (h, Nothing) ---------------------------------------------------------------- -- | Merging two heaps. Worst-case: O(N), amortized: O(log N). merge :: Frag a => Skew a -> Skew a -> Skew a merge t1 Leaf = t1 merge Leaf t2 = t2 merge t1@(Node l1 f1 r1) t2@(Node l2 f2 r2) | e1 < s2 = Node r1 f1 (merge l1 t2) | e2 < s1 = Node r2 f2 (merge l2 t1) | otherwise = let f12 | e1 == s2 = f1 >< f2 | s1 == e2 = f2 >< f1 | s1 <= s2 && e2 <= e1 = f1 | s2 <= s1 && e1 <= e2 = f2 | s1 <= s2 = f1 >< shrink e1 f2 | otherwise = f2 >< shrink e2 f1 in Node (merge l1 l2) f12 (merge r1 r2) where s1 = currOff f1 e1 = nextOff f1 s2 = currOff f2 e2 = nextOff f2 {- showSkew :: Show a => Skew a -> String showSkew = showSkew' "" showSkew' :: Show a => String -> Skew a -> String showSkew' _ Leaf = "\n" showSkew' pref (Node l x r) = show x ++ "\n" ++ pref ++ "+ " ++ showSkew' pref' l ++ pref ++ "+ " ++ showSkew' pref' r where pref' = " " ++ pref -}