mirror of
https://github.com/unisonweb/unison.git
synced 2024-09-22 07:48:10 +03:00
Improve performance of Relation.difference, Relation3.difference
This commit is contained in:
parent
023a86c585
commit
3a19e522b3
@ -9,6 +9,7 @@ module Unison.Util.Relation
|
||||
fromManyRan,
|
||||
fromMap,
|
||||
fromMultimap,
|
||||
|
||||
fromSet,
|
||||
unsafeFromMultimaps,
|
||||
|
||||
@ -75,6 +76,7 @@ module Unison.Util.Relation
|
||||
|
||||
-- ** Combinations
|
||||
difference,
|
||||
difference1,
|
||||
intersection,
|
||||
joinDom,
|
||||
joinRan,
|
||||
@ -149,12 +151,26 @@ unsafeFromMultimaps domain range =
|
||||
|
||||
-- * Functions about relations
|
||||
|
||||
-- | Compute the difference of two relations.
|
||||
difference :: (Ord a, Ord b) => Relation a b -> Relation a b -> Relation a b
|
||||
difference a b = fromList . S.toList $ diffSet
|
||||
difference (Relation d1 r1) (Relation d2 r2) =
|
||||
Relation
|
||||
(Map.differenceWith setDifference1 d1 d2)
|
||||
(Map.differenceWith setDifference1 r1 r2)
|
||||
where
|
||||
diffSet = S.difference seta setb
|
||||
seta = S.fromList . toList $ a
|
||||
setb = S.fromList . toList $ b
|
||||
-- Set difference, but return Nothing if the difference is empty.
|
||||
setDifference1 :: Ord a => Set a -> Set a -> Maybe (Set a)
|
||||
setDifference1 xs ys =
|
||||
if S.null zs then Nothing else Just zs
|
||||
where
|
||||
zs = S.difference xs ys
|
||||
|
||||
-- | Like 'difference', but returns @Nothing@ if the difference is empty.
|
||||
difference1 :: (Ord a, Ord b) => Relation a b -> Relation a b -> Maybe (Relation a b)
|
||||
difference1 xs ys =
|
||||
if null zs then Nothing else Just zs
|
||||
where
|
||||
zs = difference xs ys
|
||||
|
||||
-- The size is calculated using the domain.
|
||||
|
||||
@ -373,6 +389,8 @@ filterManyDom r = filterDom (`manyDom` r) r
|
||||
|
||||
-- |
|
||||
-- True if the relation @r@ is the 'empty' relation.
|
||||
--
|
||||
-- /O(1)/.
|
||||
null :: Relation a b -> Bool
|
||||
null r = M.null $ domain r
|
||||
|
||||
@ -402,7 +420,7 @@ dom :: Relation a b -> Set a
|
||||
dom r = M.keysSet (domain r)
|
||||
|
||||
-- | Returns the range of the relation, as a Set, in its entirety.
|
||||
--
|
||||
--
|
||||
-- /O(b)/.
|
||||
ran :: Relation a b -> Set b
|
||||
ran r = M.keysSet (range r)
|
||||
|
@ -96,12 +96,13 @@ insertAll, deleteAll :: Foldable f => Ord a => Ord b => Ord c
|
||||
insertAll f r = foldl' (\r x -> uncurry3 insert x r) r f
|
||||
deleteAll f r = foldl' (\r x -> uncurry3 delete x r) r f
|
||||
|
||||
|
||||
difference :: (Ord a, Ord b, Ord c)
|
||||
=> Relation3 a b c
|
||||
-> Relation3 a b c
|
||||
-> Relation3 a b c
|
||||
difference a b = deleteAll (Unison.Util.Relation3.toList b) a
|
||||
-- | Compute the difference of two relations.
|
||||
difference :: (Ord a, Ord b, Ord c) => Relation3 a b c -> Relation3 a b c -> Relation3 a b c
|
||||
difference (Relation3 a1 b1 c1) (Relation3 a2 b2 c2) =
|
||||
Relation3
|
||||
(Map.differenceWith R.difference1 a1 a2)
|
||||
(Map.differenceWith R.difference1 b1 b2)
|
||||
(Map.differenceWith R.difference1 c1 c2)
|
||||
|
||||
delete a b c Relation3{..} =
|
||||
Relation3
|
||||
|
Loading…
Reference in New Issue
Block a user