Skip to content

Commit e1b98c8

Browse files
Merge pull request #5718 from unisonweb/25-05-22-synhash
tweak: don't bother synhashing when synhashes would be the same
2 parents 33666cc + 12f649e commit e1b98c8

File tree

99 files changed

+2164
-2137
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

99 files changed

+2164
-2137
lines changed

codebase2/core/U/Codebase/Reference.hs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ module U.Codebase.Reference
3131
)
3232
where
3333

34+
import Control.DeepSeq (NFData)
3435
import Control.Lens (Lens, Lens', Prism, Prism', Traversal, lens, preview, prism)
3536
import Data.Bifoldable (Bifoldable (..))
3637
import Data.Bitraversable (Bitraversable (..))
@@ -75,6 +76,7 @@ data Reference' t h
7576
= ReferenceBuiltin t
7677
| ReferenceDerived (Id' h)
7778
deriving stock (Eq, Generic, Functor, Ord, Show)
79+
deriving anyclass (NFData)
7880

7981
-- | A type declaration reference.
8082
type TermReference' t h = Reference' t h
@@ -111,7 +113,8 @@ type Pos = Word64
111113

112114
-- | @Pos@ is a position into a cycle, as cycles are hashed together.
113115
data Id' h = Id h Pos
114-
deriving stock (Eq, Ord, Show, Functor, Foldable, Traversable)
116+
deriving stock (Eq, Generic, Ord, Show, Functor, Foldable, Traversable)
117+
deriving anyclass (NFData)
115118

116119
t_ :: Prism (Reference' t h) (Reference' t' h) t t'
117120
t_ = prism ReferenceBuiltin \case

codebase2/core/Unison/NameSegment/Internal.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
-- thus should only be imported by parsers & printers.
77
module Unison.NameSegment.Internal (NameSegment (..)) where
88

9+
import Control.DeepSeq (NFData)
910
import GHC.TypeLits (ErrorMessage ((:$$:)), TypeError)
1011
import GHC.TypeLits qualified as TypeError (ErrorMessage (Text))
1112
import Unison.Prelude
@@ -25,6 +26,7 @@ newtype NameSegment = NameSegment
2526
}
2627
deriving stock (Eq, Generic, Ord, Show)
2728
deriving newtype (Alphabetical)
29+
deriving anyclass (NFData)
2830

2931
instance
3032
( TypeError

codebase2/core/package.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ library:
1010
dependencies:
1111
- base
1212
- containers
13+
- deepseq
1314
- lens
1415
- mtl
1516
- recover-rtti

codebase2/core/unison-core.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ library
5757
build-depends:
5858
base
5959
, containers
60+
, deepseq
6061
, lens
6162
, mtl
6263
, recover-rtti

lib/unison-hash/package.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ ghc-options: -Wall -fno-warn-name-shadowing -fno-warn-missing-pattern-synonym-si
77
dependencies:
88
- base
99
- bytestring
10+
- deepseq
1011
- unison-prelude
1112
- unison-util-base32hex
1213

lib/unison-hash/src/Unison/Hash.hs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ module Unison.Hash
2020
)
2121
where
2222

23+
import Control.DeepSeq (NFData)
2324
import Data.ByteString.Short (ShortByteString)
2425
import Data.ByteString.Short qualified as B.Short
2526
import U.Util.Base32Hex (Base32Hex)
@@ -28,7 +29,8 @@ import Unison.Prelude
2829

2930
-- | A hash.
3031
newtype Hash = Hash {toShort :: ShortByteString}
31-
deriving stock (Eq, Ord, Generic)
32+
deriving stock (Eq, Generic, Ord)
33+
deriving anyclass (NFData)
3234

3335
instance Show Hash where
3436
show = show . toBase32HexText

lib/unison-hash/unison-hash.cabal

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cabal-version: 1.12
22

3-
-- This file has been generated from package.yaml by hpack version 0.37.0.
3+
-- This file has been generated from package.yaml by hpack version 0.36.0.
44
--
55
-- see: https://github.com/sol/hpack
66

@@ -53,6 +53,7 @@ library
5353
build-depends:
5454
base
5555
, bytestring
56+
, deepseq
5657
, unison-prelude
5758
, unison-util-base32hex
5859
default-language: Haskell2010

lib/unison-prelude/src/Unison/Util/Map.hs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,19 @@ module Unison.Util.Map
77
deleteLookup,
88
deleteLookupJust,
99
elemsSet,
10+
foldKeysCommutative,
11+
foldValuesCommutative,
1012
foldM,
1113
foldMapM,
1214
for_,
15+
fromSetA,
1316
insertLookup,
1417
invert,
1518
lookupJust,
1619
mergeMap,
1720
unionWithM,
1821
remap,
22+
thenInsertPair,
1923
traverseKeys,
2024
traverseKeysWith,
2125
swap,
@@ -36,6 +40,7 @@ import Data.Map.Internal qualified as Map (Map (Bin, Tip))
3640
import Data.Map.Merge.Strict qualified as Map
3741
import Data.Map.Strict qualified as Map
3842
import Data.Set qualified as Set
43+
import Data.Set.Internal qualified as Set (Set (..))
3944
import Data.These (These (..))
4045
import Data.Vector (Vector)
4146
import Data.Vector qualified as Vector
@@ -123,6 +128,26 @@ elemsSet :: (Ord v) => Map k v -> Set v
123128
elemsSet =
124129
Set.fromList . Map.elems
125130

131+
-- | Fold the keys of a map strictly with a "commutative" combining function that doesn't receive the elements in any
132+
-- particular order.
133+
foldKeysCommutative :: (k -> acc -> acc) -> acc -> Map k v -> acc
134+
foldKeysCommutative f =
135+
let go !acc = \case
136+
Map.Bin _ k _ l r : xs -> go (f k acc) (l : r : xs)
137+
Map.Tip : xs -> go acc xs
138+
[] -> acc
139+
in \z xs -> go z [xs]
140+
141+
-- | Fold the values of a map strictly with a "commutative" combining function that doesn't receive the elements in any
142+
-- particular order.
143+
foldValuesCommutative :: (v -> acc -> acc) -> acc -> Map k v -> acc
144+
foldValuesCommutative f =
145+
let go !acc = \case
146+
Map.Bin _ _ v l r : xs -> go (f v acc) (l : r : xs)
147+
Map.Tip : xs -> go acc xs
148+
[] -> acc
149+
in \z xs -> go z [xs]
150+
126151
-- | Like 'Map.foldlWithKey'', but with a monadic accumulator.
127152
foldM :: (Monad m) => (acc -> k -> v -> m acc) -> acc -> Map k v -> m acc
128153
foldM f acc0 =
@@ -158,6 +183,15 @@ for_ m f =
158183
f k v
159184
go ys
160185

186+
-- | Like 'Map.fromSet', but in an applicative functor.
187+
fromSetA :: (Applicative m) => (k -> m a) -> Set k -> m (Map k a)
188+
fromSetA f =
189+
go
190+
where
191+
go = \case
192+
Set.Tip -> pure Map.Tip
193+
Set.Bin n k l r -> (\v l' r' -> Map.Bin n k v l' r') <$> f k <*> go l <*> go r
194+
161195
unionWithM ::
162196
forall m k a.
163197
(Monad m, Ord k) =>
@@ -182,6 +216,11 @@ remap :: (Ord k1) => ((k0, v0) -> (k1, v1)) -> Map k0 v0 -> Map k1 v1
182216
remap f =
183217
Map.fromList . map f . Map.toList
184218

219+
-- | Insert a pair in postfix-style.
220+
thenInsertPair :: (Ord k) => Map k v -> (k, v) -> Map k v
221+
thenInsertPair m (k, v) =
222+
Map.insert k v m
223+
185224
traverseKeys :: (Applicative f, Ord k') => (k -> f k') -> Map k v -> f (Map k' v)
186225
traverseKeys f = bitraverse f pure
187226

lib/unison-prelude/src/Unison/Util/Set.hs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
module Unison.Util.Set
22
( asSingleton,
33
difference1,
4+
differenceMap,
5+
foldCommutativeM,
6+
insertMaybe,
47
intersects,
58
mapMaybe,
69
symmetricDifference,
@@ -9,14 +12,19 @@ module Unison.Util.Set
912
flatMap,
1013
filterM,
1114
forMaybe,
15+
thenInsert,
16+
thenInsertMaybe,
1217
)
1318
where
1419

1520
import Data.Function ((&))
1621
import Data.Functor ((<&>))
22+
import Data.Map.Internal qualified as Map.Internal (Map (..))
23+
import Data.Map.Strict (Map)
1724
import Data.Maybe qualified as Maybe
1825
import Data.Set (Set)
1926
import Data.Set qualified as Set
27+
import Data.Set.Internal qualified as Set.Internal (Set (..), merge)
2028
import Unison.Util.Monoid (foldMapM)
2129

2230
-- | Get the only member of a set, iff it's a singleton.
@@ -31,6 +39,36 @@ difference1 xs ys =
3139
where
3240
zs = Set.difference xs ys
3341

42+
-- | Like 'Set.difference', but the second argument is a map.
43+
differenceMap :: (Ord k) => Set k -> Map k a -> Set k
44+
differenceMap Set.Internal.Tip _ = Set.Internal.Tip
45+
differenceMap x Map.Internal.Tip = x
46+
differenceMap x (Map.Internal.Bin _ k _ yl yr)
47+
| Set.size zl + Set.size zr == Set.size x = x
48+
| otherwise = Set.Internal.merge zl zr
49+
where
50+
(xl, xr) = Set.split k x
51+
!zl = differenceMap xl yl
52+
!zr = differenceMap xr yr
53+
54+
-- | Fold a set strictly with a monadic "commutative" combining function that doesn't receive the elements in any
55+
-- particular order.
56+
foldCommutativeM :: (Monad m) => (a -> b -> m b) -> b -> Set a -> m b
57+
foldCommutativeM f =
58+
let go !acc = \case
59+
Set.Internal.Bin _ x l r : xs -> do
60+
!acc1 <- f x acc
61+
go acc1 (l : r : xs)
62+
Set.Internal.Tip : xs -> go acc xs
63+
[] -> pure acc
64+
in \z xs -> go z [xs]
65+
66+
insertMaybe :: (Ord a) => Maybe a -> Set a -> Set a
67+
insertMaybe mx xs =
68+
case mx of
69+
Just x -> Set.insert x xs
70+
Nothing -> xs
71+
3472
-- | Get whether two sets intersect.
3573
intersects :: (Ord a) => Set a -> Set a -> Bool
3674
intersects xs ys =
@@ -64,3 +102,12 @@ filterM p =
64102
p x <&> \case
65103
False -> Set.empty
66104
True -> Set.singleton x
105+
106+
thenInsert :: (Ord a) => Set a -> a -> Set a
107+
thenInsert xs x =
108+
Set.insert x xs
109+
110+
thenInsertMaybe :: (Ord a) => Set a -> Maybe a -> Set a
111+
thenInsertMaybe xs = \case
112+
Just x -> Set.insert x xs
113+
Nothing -> xs

lib/unison-util-relation/src/Unison/Util/BiMultimap.hs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,15 @@ import Prelude hiding (filter)
6161
--
6262
-- "Left-unique" means that for all @(x, y)@ in the relation, @y@ is related only to @x@.
6363
data BiMultimap a b = BiMultimap
64-
{ toMultimap :: (Map a (NESet b)), -- intentionally lazy in case it's not used after `fromRange`
65-
toMapR :: (Map b a)
64+
{ toMultimap :: Map a (NESet b), -- intentionally lazy in case it's not used after `fromRange`
65+
toMapR :: Map b a
6666
}
67-
deriving (Eq, Ord, Show)
67+
deriving stock (Eq, Ord, Show)
6868

6969
-- | An empty left-unique relation.
7070
empty :: (Ord a, Ord b) => BiMultimap a b
71-
empty = BiMultimap mempty mempty
71+
empty =
72+
BiMultimap Map.empty Map.empty
7273

7374
-- | Is a left-unique relation empty?
7475
isEmpty :: BiMultimap a b -> Bool
@@ -167,6 +168,7 @@ withoutRan :: (Ord a, Ord b) => Set b -> BiMultimap a b -> BiMultimap a b
167168
withoutRan ys m =
168169
fromRange (Map.withoutKeys (range m) ys)
169170

171+
-- | /O(1)/.
170172
domain :: BiMultimap a b -> Map a (NESet b)
171173
domain = toMultimap
172174

@@ -216,8 +218,10 @@ ran =
216218

217219
-- | Convert a left-unique relation to a relation (forgetting its left-uniqueness).
218220
toRelation :: (Ord a, Ord b) => BiMultimap a b -> Relation a b
219-
toRelation =
220-
Relation.fromMultimap . Map.map Set.NonEmpty.toSet . domain
221+
toRelation m =
222+
Relation.unsafeFromMultimaps
223+
(Set.NonEmpty.toSet <$> domain m)
224+
(Set.singleton <$> range m)
221225

222226
-- | Insert a pair into a left-unique relation, maintaining left-uniqueness, preferring the latest inserted element.
223227
--

0 commit comments

Comments
 (0)