@@ -1558,7 +1558,7 @@ take i0 m0 = go i0 m0
15581558 go i (Bin _ kx x l r) =
15591559 case compare i sizeL of
15601560 LT -> go i l
1561- GT -> link kx x l (go (i - sizeL - 1 ) r)
1561+ GT -> linkL kx x l (go (i - sizeL - 1 ) r)
15621562 EQ -> l
15631563 where sizeL = size l
15641564
@@ -1578,7 +1578,7 @@ drop i0 m0 = go i0 m0
15781578 go ! _ Tip = Tip
15791579 go i (Bin _ kx x l r) =
15801580 case compare i sizeL of
1581- LT -> link kx x (go i l) r
1581+ LT -> linkR kx x (go i l) r
15821582 GT -> go (i - sizeL - 1 ) r
15831583 EQ -> insertMin kx x r
15841584 where sizeL = size l
@@ -1600,9 +1600,9 @@ splitAt i0 m0
16001600 go i (Bin _ kx x l r)
16011601 = case compare i sizeL of
16021602 LT -> case go i l of
1603- ll :*: lr -> ll :*: link kx x lr r
1603+ ll :*: lr -> ll :*: linkR kx x lr r
16041604 GT -> case go (i - sizeL - 1 ) r of
1605- rl :*: rr -> link kx x l rl :*: rr
1605+ rl :*: rr -> linkL kx x l rl :*: rr
16061606 EQ -> l :*: insertMin kx x r
16071607 where sizeL = size l
16081608
@@ -3034,7 +3034,7 @@ filterWithKeyA p t@(Bin _ kx x l r) =
30343034takeWhileAntitone :: (k -> Bool ) -> Map k a -> Map k a
30353035takeWhileAntitone _ Tip = Tip
30363036takeWhileAntitone p (Bin _ kx x l r)
3037- | p kx = link kx x l (takeWhileAntitone p r)
3037+ | p kx = linkL kx x l (takeWhileAntitone p r)
30383038 | otherwise = takeWhileAntitone p l
30393039
30403040-- | \(O(\log n)\). Drop while a predicate on the keys holds.
@@ -3052,7 +3052,7 @@ dropWhileAntitone :: (k -> Bool) -> Map k a -> Map k a
30523052dropWhileAntitone _ Tip = Tip
30533053dropWhileAntitone p (Bin _ kx x l r)
30543054 | p kx = dropWhileAntitone p r
3055- | otherwise = link kx x (dropWhileAntitone p l) r
3055+ | otherwise = linkR kx x (dropWhileAntitone p l) r
30563056
30573057-- | \(O(\log n)\). Divide a map at the point where a predicate on the keys stops holding.
30583058-- The user is responsible for ensuring that for all keys @j@ and @k@ in the map,
@@ -3075,8 +3075,8 @@ spanAntitone p0 m = toPair (go p0 m)
30753075 where
30763076 go _ Tip = Tip :*: Tip
30773077 go p (Bin _ kx x l r)
3078- | p kx = let u :*: v = go p r in link kx x l u :*: v
3079- | otherwise = let u :*: v = go p l in u :*: link kx x v r
3078+ | p kx = let u :*: v = go p r in linkL kx x l u :*: v
3079+ | otherwise = let u :*: v = go p l in u :*: linkR kx x v r
30803080
30813081-- | \(O(n)\). Partition the map according to a predicate. The first
30823082-- map contains all elements that satisfy the predicate, the second all
@@ -3842,7 +3842,7 @@ ascLinkTop (Push kx x l@(Bin lsz _ _ _ _) stk) !rsz r ky y
38423842ascLinkTop stk ! _ l kx x = Push kx x l stk
38433843
38443844ascLinkAll :: Stack k a -> Map k a
3845- ascLinkAll stk = foldl'Stack (\ r kx x l -> link kx x l r) Tip stk
3845+ ascLinkAll stk = foldl'Stack (\ r kx x l -> linkL kx x l r) Tip stk
38463846{-# INLINABLE ascLinkAll #-}
38473847
38483848-- | \(O(n)\). Build a map from a descending list of distinct elements in linear time.
@@ -3875,7 +3875,7 @@ descLinkTop ky y !_ r stk = Push ky y r stk
38753875{-# INLINABLE descLinkTop #-}
38763876
38773877descLinkAll :: Stack k a -> Map k a
3878- descLinkAll stk = foldl'Stack (\ l kx x r -> link kx x l r) Tip stk
3878+ descLinkAll stk = foldl'Stack (\ l kx x r -> linkR kx x l r) Tip stk
38793879{-# INLINABLE descLinkAll #-}
38803880
38813881data Stack k a = Push ! k a ! (Map k a ) ! (Stack k a ) | Nada
@@ -3939,8 +3939,8 @@ split !k0 t0 = toPair $ go k0 t0
39393939 case t of
39403940 Tip -> Tip :*: Tip
39413941 Bin _ kx x l r -> case compare k kx of
3942- LT -> let (lt :*: gt) = go k l in lt :*: link kx x gt r
3943- GT -> let (lt :*: gt) = go k r in link kx x l lt :*: gt
3942+ LT -> let (lt :*: gt) = go k l in lt :*: linkR kx x gt r
3943+ GT -> let (lt :*: gt) = go k r in linkL kx x l lt :*: gt
39443944 EQ -> (l :*: r)
39453945#if __GLASGOW_HASKELL__
39463946{-# INLINABLE split #-}
@@ -3964,10 +3964,10 @@ splitLookup k0 m = case go k0 m of
39643964 Tip -> StrictTriple Tip Nothing Tip
39653965 Bin _ kx x l r -> case compare k kx of
39663966 LT -> let StrictTriple lt z gt = go k l
3967- ! gt' = link kx x gt r
3967+ ! gt' = linkR kx x gt r
39683968 in StrictTriple lt z gt'
39693969 GT -> let StrictTriple lt z gt = go k r
3970- ! lt' = link kx x l lt
3970+ ! lt' = linkL kx x l lt
39713971 in StrictTriple lt' z gt
39723972 EQ -> StrictTriple l (Just x) r
39733973#if __GLASGOW_HASKELL__
@@ -3988,10 +3988,10 @@ splitMember k0 m = case go k0 m of
39883988 Tip -> StrictTriple Tip False Tip
39893989 Bin _ kx x l r -> case compare k kx of
39903990 LT -> let StrictTriple lt z gt = go k l
3991- ! gt' = link kx x gt r
3991+ ! gt' = linkR kx x gt r
39923992 in StrictTriple lt z gt'
39933993 GT -> let StrictTriple lt z gt = go k r
3994- ! lt' = link kx x l lt
3994+ ! lt' = linkL kx x l lt
39953995 in StrictTriple lt' z gt
39963996 EQ -> StrictTriple l True r
39973997#if __GLASGOW_HASKELL__
@@ -4079,11 +4079,38 @@ finishB (BMap m) = m
40794079link :: k -> a -> Map k a -> Map k a -> Map k a
40804080link kx x Tip r = insertMin kx x r
40814081link kx x l Tip = insertMax kx x l
4082- link kx x l@ (Bin sizeL ky y ly ry) r@ (Bin sizeR kz z lz rz)
4083- | delta* sizeL < sizeR = balanceL kz z (link kx x l lz) rz
4084- | delta* sizeR < sizeL = balanceR ky y ly (link kx x ry r)
4085- | otherwise = bin kx x l r
4086-
4082+ link kx x l@ (Bin lsz lkx lx ll lr) r@ (Bin rsz rkx rx rl rr)
4083+ | delta* lsz < rsz = balanceL rkx rx (linkR_ kx x lsz l rl) rr
4084+ | delta* rsz < lsz = balanceR lkx lx ll (linkL_ kx x lr rsz r)
4085+ | otherwise = Bin (1 + lsz+ rsz) kx x l r
4086+
4087+ -- Variant of link. Restores balance when the left tree may be too large for the
4088+ -- right tree, but not the other way around.
4089+ linkL :: k -> a -> Map k a -> Map k a -> Map k a
4090+ linkL kx x l r = case r of
4091+ Tip -> insertMax kx x l
4092+ Bin rsz _ _ _ _ -> linkL_ kx x l rsz r
4093+
4094+ linkL_ :: k -> a -> Map k a -> Int -> Map k a -> Map k a
4095+ linkL_ kx x l ! rsz r = case l of
4096+ Bin lsz lkx lx ll lr
4097+ | delta* rsz < lsz -> balanceR lkx lx ll (linkL_ kx x lr rsz r)
4098+ | otherwise -> Bin (1 + lsz+ rsz) kx x l r
4099+ Tip -> Bin (1 + rsz) kx x Tip r
4100+
4101+ -- Variant of link. Restores balance when the right tree may be too large for
4102+ -- the left tree, but not the other way around.
4103+ linkR :: k -> a -> Map k a -> Map k a -> Map k a
4104+ linkR kx x l r = case l of
4105+ Tip -> insertMin kx x r
4106+ Bin lsz _ _ _ _ -> linkR_ kx x lsz l r
4107+
4108+ linkR_ :: k -> a -> Int -> Map k a -> Map k a -> Map k a
4109+ linkR_ kx x ! lsz l r = case r of
4110+ Bin rsz rkx rx rl rr
4111+ | delta* lsz < rsz -> balanceL rkx rx (linkR_ kx x lsz l rl) rr
4112+ | otherwise -> Bin (1 + lsz+ rsz) kx x l r
4113+ Tip -> Bin (1 + lsz) kx x l Tip
40874114
40884115-- insertMin and insertMax don't perform potentially expensive comparisons.
40894116insertMax ,insertMin :: k -> a -> Map k a -> Map k a
@@ -4105,10 +4132,24 @@ insertMin kx x t
41054132link2 :: Map k a -> Map k a -> Map k a
41064133link2 Tip r = r
41074134link2 l Tip = l
4108- link2 l@ (Bin sizeL kx x lx rx) r@ (Bin sizeR ky y ly ry)
4109- | delta* sizeL < sizeR = balanceL ky y (link2 l ly) ry
4110- | delta* sizeR < sizeL = balanceR kx x lx (link2 rx r)
4111- | otherwise = glue l r
4135+ link2 l@ (Bin lsz lkx lx ll lr) r@ (Bin rsz rkx rx rl rr)
4136+ | delta* lsz < rsz = balanceL rkx rx (link2R_ lsz l rl) rr
4137+ | delta* rsz < lsz = balanceR lkx lx ll (link2L_ lr rsz r)
4138+ | otherwise = glue l r
4139+
4140+ link2L_ :: Map k a -> Int -> Map k a -> Map k a
4141+ link2L_ l ! rsz r = case l of
4142+ Bin lsz lkx lx ll lr
4143+ | delta* rsz < lsz -> balanceR lkx lx ll (link2L_ lr rsz r)
4144+ | otherwise -> glue l r
4145+ Tip -> r
4146+
4147+ link2R_ :: Int -> Map k a -> Map k a -> Map k a
4148+ link2R_ ! lsz l r = case r of
4149+ Bin rsz rkx rx rl rr
4150+ | delta* lsz < rsz -> balanceL rkx rx (link2R_ lsz l rl) rr
4151+ | otherwise -> glue l r
4152+ Tip -> l
41124153
41134154{- -------------------------------------------------------------------
41144155 [glue l r]: glues two trees together.
0 commit comments