77{-# LANGUAGE GeneralizedNewtypeDeriving #-}
88{-# LANGUAGE RecordWildCards #-}
99{-# LANGUAGE ScopedTypeVariables #-}
10+ {-# LANGUAGE PatternSynonyms #-}
11+ {-# LANGUAGE BangPatterns #-}
12+ {-# LANGUAGE ViewPatterns #-}
1013
1114module Development.IDE.Graph.Internal.Types where
1215
@@ -20,6 +23,7 @@ import qualified Data.ByteString as BS
2023import Data.Dynamic
2124import qualified Data.HashMap.Strict as Map
2225import Data.HashSet (HashSet , member )
26+ import qualified Data.IntMap as IM
2327import qualified Data.HashSet as Set
2428import Data.IORef
2529import Data.List (intercalate )
@@ -32,6 +36,7 @@ import qualified ListT
3236import qualified StmContainers.Map as SMap
3337import StmContainers.Map (Map )
3438import System.Time.Extra (Seconds )
39+ import System.IO.Unsafe
3540import UnliftIO (MonadUnliftIO )
3641
3742
@@ -78,16 +83,54 @@ data ShakeDatabase = ShakeDatabase !Int [Action ()] Database
7883newtype Step = Step Int
7984 deriving newtype (Eq ,Ord ,Hashable )
8085
81- data Key = forall a . (Typeable a , Eq a , Hashable a , Show a ) => Key a
86+ ---------------------------------------------------------------------
87+ -- Keys
8288
83- instance Eq Key where
84- Key a == Key b = Just a == cast b
89+ data KeyValue = forall a . (Typeable a , Hashable a , Show a ) => KeyValue a
8590
86- instance Hashable Key where
87- hashWithSalt i (Key x) = hashWithSalt i (typeOf x, x)
91+ newtype Key = UnsafeMkKey Int
92+
93+ pattern Key a <- (lookupKeyValue -> KeyValue a)
94+
95+ data KeyMap = KeyMap ! (Map. HashMap KeyValue Key ) ! (IM. IntMap KeyValue ) {- # UNPACK #-} !Int
96+
97+ keyMap :: IORef KeyMap
98+ keyMap = unsafePerformIO $ newIORef (KeyMap Map. empty IM. empty 0 )
99+
100+ {-# NOINLINE keyMap #-}
88101
102+ newKey :: (Typeable a , Hashable a , Show a ) => a -> Key
103+ newKey k = unsafePerformIO $ do
104+ let ! newKey = KeyValue k
105+ atomicModifyIORef' keyMap $ \ km@ (KeyMap hm im n) ->
106+ let new_key = Map. lookup newKey hm
107+ in case new_key of
108+ Just v -> (km, v)
109+ Nothing ->
110+ let ! new_index = UnsafeMkKey n
111+ in (KeyMap (Map. insert newKey new_index hm) (IM. insert n newKey im) (n+ 1 ), new_index)
112+ {-# NOINLINE newKey #-}
113+
114+ lookupKeyValue :: Key -> KeyValue
115+ lookupKeyValue (UnsafeMkKey x) = unsafePerformIO $ do
116+ KeyMap _ im _ <- readIORef keyMap
117+ pure $! fromJust (IM. lookup x im)
118+
119+ {-# NOINLINE lookupKeyValue #-}
120+
121+ instance Eq Key where
122+ UnsafeMkKey a == UnsafeMkKey b = a == b
123+ instance Hashable Key where
124+ hashWithSalt i (UnsafeMkKey x) = hashWithSalt i x
89125instance Show Key where
90- show (Key x) = show x
126+ show (Key x) = show x
127+
128+ instance Eq KeyValue where
129+ KeyValue a == KeyValue b = Just a == cast b
130+ instance Hashable KeyValue where
131+ hashWithSalt i (KeyValue x) = hashWithSalt i (typeOf x, x)
132+ instance Show KeyValue where
133+ show (KeyValue x) = show x
91134
92135newtype Value = Value Dynamic
93136
@@ -143,24 +186,24 @@ data Result = Result {
143186 resultData :: ! BS. ByteString
144187 }
145188
146- data ResultDeps = UnknownDeps | AlwaysRerunDeps ! [ Key ] | ResultDeps ! [ Key ]
189+ data ResultDeps = UnknownDeps | AlwaysRerunDeps ! ( HashSet Key ) | ResultDeps ! ( HashSet Key )
147190 deriving (Eq , Show )
148191
149- getResultDepsDefault :: [ Key ] -> ResultDeps -> [ Key ]
192+ getResultDepsDefault :: ( HashSet Key ) -> ResultDeps -> ( HashSet Key )
150193getResultDepsDefault _ (ResultDeps ids) = ids
151194getResultDepsDefault _ (AlwaysRerunDeps ids) = ids
152195getResultDepsDefault def UnknownDeps = def
153196
154- mapResultDeps :: ([ Key ] -> [ Key ] ) -> ResultDeps -> ResultDeps
197+ mapResultDeps :: (HashSet Key -> HashSet Key ) -> ResultDeps -> ResultDeps
155198mapResultDeps f (ResultDeps ids) = ResultDeps $ f ids
156199mapResultDeps f (AlwaysRerunDeps ids) = AlwaysRerunDeps $ f ids
157200mapResultDeps _ UnknownDeps = UnknownDeps
158201
159202instance Semigroup ResultDeps where
160203 UnknownDeps <> x = x
161204 x <> UnknownDeps = x
162- AlwaysRerunDeps ids <> x = AlwaysRerunDeps (ids <> getResultDepsDefault [] x)
163- x <> AlwaysRerunDeps ids = AlwaysRerunDeps (getResultDepsDefault [] x <> ids)
205+ AlwaysRerunDeps ids <> x = AlwaysRerunDeps (ids <> getResultDepsDefault mempty x)
206+ x <> AlwaysRerunDeps ids = AlwaysRerunDeps (getResultDepsDefault mempty x <> ids)
164207 ResultDeps ids <> ResultDeps ids' = ResultDeps (ids <> ids')
165208
166209instance Monoid ResultDeps where
0 commit comments