Skip to content

Commit 3b64a3b

Browse files
committed
Introduce KeyMap and KeySet
1 parent ada1b3d commit 3b64a3b

File tree

12 files changed

+189
-81
lines changed

12 files changed

+189
-81
lines changed

.hlint.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
- Development.IDE.Graph.Internal.Database
6060
- Development.IDE.Graph.Internal.Paths
6161
- Development.IDE.Graph.Internal.Profile
62+
- Development.IDE.Graph.Internal.Types
6263
- Ide.Types
6364
- Test.Hls
6465
- Test.Hls.Command

ghcide/src/Development/IDE/Core/FileStore.hs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ import qualified Development.IDE.Types.Logger as L
5555

5656
import qualified Data.Binary as B
5757
import qualified Data.ByteString.Lazy as LBS
58-
import qualified Data.HashSet as HSet
5958
import Data.List (foldl')
6059
import qualified Data.Text as Text
6160
import Development.IDE.Core.IdeConfiguration (isWorkspaceFile)
@@ -256,7 +255,7 @@ setSomethingModified vfs state keys reason = do
256255
atomically $ do
257256
writeTQueue (indexQueue $ hiedbWriter $ shakeExtras state) (\withHieDb -> withHieDb deleteMissingRealFiles)
258257
modifyTVar' (dirtyKeys $ shakeExtras state) $ \x ->
259-
foldl' (flip HSet.insert) x keys
258+
foldl' (flip insertKeySet) x keys
260259
void $ restartShakeSession (shakeExtras state) vfs reason []
261260

262261
registerFileWatches :: [String] -> LSP.LspT Config IO Bool

ghcide/src/Development/IDE/Core/Shake.hs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ import System.Time.Extra
178178
data Log
179179
= LogCreateHieDbExportsMapStart
180180
| LogCreateHieDbExportsMapFinish !Int
181-
| LogBuildSessionRestart !String ![DelayedActionInternal] !(HashSet Key) !Seconds !(Maybe FilePath)
181+
| LogBuildSessionRestart !String ![DelayedActionInternal] !(KeySet) !Seconds !(Maybe FilePath)
182182
| LogBuildSessionRestartTakingTooLong !Seconds
183183
| LogDelayedAction !(DelayedAction ()) !Seconds
184184
| LogBuildSessionFinish !(Maybe SomeException)
@@ -197,7 +197,7 @@ instance Pretty Log where
197197
vcat
198198
[ "Restarting build session due to" <+> pretty reason
199199
, "Action Queue:" <+> pretty (map actionName actionQueue)
200-
, "Keys:" <+> pretty (map show $ HSet.toList keyBackLog)
200+
, "Keys:" <+> pretty (map show $ toListKeySet keyBackLog)
201201
, "Aborting previous build session took" <+> pretty (showDuration abortDuration) <+> pretty shakeProfilePath ]
202202
LogBuildSessionRestartTakingTooLong seconds ->
203203
"Build restart is taking too long (" <> pretty seconds <> " seconds)"
@@ -279,7 +279,7 @@ data ShakeExtras = ShakeExtras
279279
,clientCapabilities :: ClientCapabilities
280280
, withHieDb :: WithHieDb -- ^ Use only to read.
281281
, hiedbWriter :: HieDbWriter -- ^ use to write
282-
, persistentKeys :: TVar (HMap.HashMap Key GetStalePersistent)
282+
, persistentKeys :: TVar (KeyMap GetStalePersistent)
283283
-- ^ Registery for functions that compute/get "stale" results for the rule
284284
-- (possibly from disk)
285285
, vfsVar :: TVar VFS
@@ -290,7 +290,7 @@ data ShakeExtras = ShakeExtras
290290
-- We don't need a STM.Map because we never update individual keys ourselves.
291291
, defaultConfig :: Config
292292
-- ^ Default HLS config, only relevant if the client does not provide any Config
293-
, dirtyKeys :: TVar (HashSet Key)
293+
, dirtyKeys :: TVar KeySet
294294
-- ^ Set of dirty rule keys since the last Shake run
295295
}
296296

@@ -324,7 +324,7 @@ getPluginConfig plugin = do
324324
addPersistentRule :: IdeRule k v => k -> (NormalizedFilePath -> IdeAction (Maybe (v,PositionDelta,TextDocumentVersion))) -> Rules ()
325325
addPersistentRule k getVal = do
326326
ShakeExtras{persistentKeys} <- getShakeExtrasRules
327-
void $ liftIO $ atomically $ modifyTVar' persistentKeys $ HMap.insert (newKey k) (fmap (fmap (first3 toDyn)) . getVal)
327+
void $ liftIO $ atomically $ modifyTVar' persistentKeys $ insertKeyMap (newKey k) (fmap (fmap (first3 toDyn)) . getVal)
328328

329329
class Typeable a => IsIdeGlobal a where
330330

@@ -399,7 +399,7 @@ lastValueIO s@ShakeExtras{positionMapping,persistentKeys,state} k file = do
399399
pmap <- readTVarIO persistentKeys
400400
mv <- runMaybeT $ do
401401
liftIO $ Logger.logDebug (logger s) $ T.pack $ "LOOKUP PERSISTENT FOR: " ++ show k
402-
f <- MaybeT $ pure $ HMap.lookup (newKey k) pmap
402+
f <- MaybeT $ pure $ lookupKeyMap (newKey k) pmap
403403
(dv,del,ver) <- MaybeT $ runIdeAction "lastValueIO" s $ f file
404404
MaybeT $ pure $ (,del,ver) <$> fromDynamic dv
405405
case mv of
@@ -509,7 +509,7 @@ deleteValue
509509
-> STM ()
510510
deleteValue ShakeExtras{dirtyKeys, state} key file = do
511511
STM.delete (toKey key file) state
512-
modifyTVar' dirtyKeys $ HSet.insert (toKey key file)
512+
modifyTVar' dirtyKeys $ insertKeySet (toKey key file)
513513

514514
recordDirtyKeys
515515
:: Shake.ShakeValue k
@@ -518,7 +518,7 @@ recordDirtyKeys
518518
-> [NormalizedFilePath]
519519
-> STM (IO ())
520520
recordDirtyKeys ShakeExtras{dirtyKeys} key file = do
521-
modifyTVar' dirtyKeys $ \x -> foldl' (flip HSet.insert) x (toKey key <$> file)
521+
modifyTVar' dirtyKeys $ \x -> foldl' (flip insertKeySet) x (toKey key <$> file)
522522
return $ withEventTrace "recordDirtyKeys" $ \addEvent -> do
523523
addEvent (fromString $ unlines $ "dirty " <> show key : map fromNormalizedFilePath file)
524524

@@ -594,7 +594,7 @@ shakeOpen recorder lspEnv defaultConfig idePlugins logger debouncer
594594
positionMapping <- STM.newIO
595595
knownTargetsVar <- newTVarIO $ hashed HMap.empty
596596
let restartShakeSession = shakeRestart recorder ideState
597-
persistentKeys <- newTVarIO HMap.empty
597+
persistentKeys <- newTVarIO mempty
598598
indexPending <- newTVarIO HMap.empty
599599
indexCompleted <- newTVarIO 0
600600
indexProgressToken <- newVar Nothing
@@ -637,7 +637,7 @@ shakeOpen recorder lspEnv defaultConfig idePlugins logger debouncer
637637

638638
-- monitoring
639639
let readValuesCounter = fromIntegral . countRelevantKeys checkParents <$> getStateKeys shakeExtras
640-
readDirtyKeys = fromIntegral . countRelevantKeys checkParents . HSet.toList <$> readTVarIO(dirtyKeys shakeExtras)
640+
readDirtyKeys = fromIntegral . countRelevantKeys checkParents . toListKeySet <$> readTVarIO(dirtyKeys shakeExtras)
641641
readIndexPending = fromIntegral . HMap.size <$> readTVarIO (indexPending $ hiedbWriter shakeExtras)
642642
readExportsMap = fromIntegral . HMap.size . getExportsMap <$> readTVarIO (exportsMap shakeExtras)
643643
readDatabaseCount = fromIntegral . countRelevantKeys checkParents . map fst <$> shakeGetDatabaseKeys shakeDb
@@ -797,10 +797,10 @@ newSession recorder extras@ShakeExtras{..} vfsMod shakeDb acts reason = do
797797
workRun restore = withSpan "Shake session" $ \otSpan -> do
798798
setTag otSpan "reason" (fromString reason)
799799
setTag otSpan "queue" (fromString $ unlines $ map actionName reenqueued)
800-
whenJust allPendingKeys $ \kk -> setTag otSpan "keys" (BS8.pack $ unlines $ map show $ toList kk)
800+
whenJust allPendingKeys $ \kk -> setTag otSpan "keys" (BS8.pack $ unlines $ map show $ toListKeySet kk)
801801
let keysActs = pumpActionThread otSpan : map (run otSpan) (reenqueued ++ acts)
802802
res <- try @SomeException $
803-
restore $ shakeRunDatabaseForKeys (HSet.toList <$> allPendingKeys) shakeDb keysActs
803+
restore $ shakeRunDatabaseForKeys (toListKeySet <$> allPendingKeys) shakeDb keysActs
804804
return $ do
805805
let exception =
806806
case res of
@@ -890,7 +890,7 @@ garbageCollectKeys label maxAge checkParents agedKeys = do
890890
= atomicallyNamed "GC" $ do
891891
gotIt <- STM.focus (Focus.member <* Focus.delete) k values
892892
when gotIt $
893-
modifyTVar' dk (HSet.insert k)
893+
modifyTVar' dk (insertKeySet k)
894894
return $ if gotIt then (counter+1, k:keys) else st
895895
| otherwise = pure st
896896

@@ -1160,7 +1160,7 @@ defineEarlyCutoff' doDiagnostics cmp key file old mode action = do
11601160
(if eq then ChangedRecomputeSame else ChangedRecomputeDiff)
11611161
(encodeShakeValue bs) $
11621162
A res
1163-
liftIO $ atomicallyNamed "define - dirtyKeys" $ modifyTVar' dirtyKeys (HSet.delete $ toKey key file)
1163+
liftIO $ atomicallyNamed "define - dirtyKeys" $ modifyTVar' dirtyKeys (deleteKeySet $ toKey key file)
11641164
return res
11651165
where
11661166
-- Highly unsafe helper to compute the version of a file

hls-graph/hls-graph.cabal

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ library
4747
Development.IDE.Graph.Classes
4848
Development.IDE.Graph.Database
4949
Development.IDE.Graph.Rule
50+
Development.IDE.Graph.KeyMap
51+
Development.IDE.Graph.KeySet
5052
Development.IDE.Graph.Internal.Action
5153
Development.IDE.Graph.Internal.Options
5254
Development.IDE.Graph.Internal.Rules

hls-graph/src/Development/IDE/Graph.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,13 @@ module Development.IDE.Graph(
2020
-- * Actions for inspecting the keys in the database
2121
getDirtySet,
2222
getKeysAndVisitedAge,
23+
module Development.IDE.Graph.KeyMap,
24+
module Development.IDE.Graph.KeySet,
2325
) where
2426

2527
import Development.IDE.Graph.Database
28+
import Development.IDE.Graph.KeyMap
29+
import Development.IDE.Graph.KeySet
2630
import Development.IDE.Graph.Internal.Action
2731
import Development.IDE.Graph.Internal.Options
2832
import Development.IDE.Graph.Internal.Rules

hls-graph/src/Development/IDE/Graph/Database.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ shakeGetBuildEdges :: ShakeDatabase -> IO Int
7979
shakeGetBuildEdges (ShakeDatabase _ _ db) = do
8080
keys <- getDatabaseValues db
8181
let ress = mapMaybe (getResult . snd) keys
82-
return $ sum $ map (length . getResultDepsDefault mempty . resultDeps) ress
82+
return $ sum $ map (lengthKeySet . getResultDepsDefault mempty . resultDeps) ress
8383

8484
-- | Returns an approximation of the database keys,
8585
-- annotated with how long ago (in # builds) they were visited

hls-graph/src/Development/IDE/Graph/Internal/Action.hs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import Control.Monad.Trans.Class
2626
import Control.Monad.Trans.Reader
2727
import Data.Foldable (toList)
2828
import Data.Functor.Identity
29-
import qualified Data.HashSet as HSet
3029
import Data.IORef
3130
import Development.IDE.Graph.Classes
3231
import Development.IDE.Graph.Internal.Database
@@ -122,7 +121,7 @@ apply ks = do
122121
stack <- Action $ asks actionStack
123122
(is, vs) <- liftIO $ build db stack ks
124123
ref <- Action $ asks actionDeps
125-
liftIO $ modifyIORef ref (ResultDeps (HSet.fromList $ toList is) <>)
124+
liftIO $ modifyIORef ref (ResultDeps (fromListKeySet $ toList is) <>)
126125
pure vs
127126

128127
-- | Evaluate a list of keys without recording any dependencies.

hls-graph/src/Development/IDE/Graph/Internal/Database.hs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ import qualified Control.Monad.Trans.State.Strict as State
3030
import Data.Dynamic
3131
import Data.Either
3232
import Data.Foldable (for_, traverse_)
33-
import Data.HashSet (HashSet)
34-
import qualified Data.HashSet as HSet
3533
import Data.IORef.Extra
3634
import Data.List.NonEmpty (unzip)
3735
import Data.Maybe
@@ -61,7 +59,7 @@ incDatabase :: Database -> Maybe [Key] -> IO ()
6159
incDatabase db (Just kk) = do
6260
atomicallyNamed "incDatabase" $ modifyTVar' (databaseStep db) $ \(Step i) -> Step $ i + 1
6361
transitiveDirtyKeys <- transitiveDirtySet db kk
64-
for_ transitiveDirtyKeys $ \k ->
62+
for_ (toListKeySet transitiveDirtyKeys) $ \k ->
6563
-- Updating all the keys atomically is not necessary
6664
-- since we assume that no build is mutating the db.
6765
-- Therefore run one transaction per key to minimise contention.
@@ -146,7 +144,7 @@ refresh :: Database -> Stack -> Key -> Maybe Result -> AIO (IO Result)
146144
-- refresh _ st k _ | traceShow ("refresh", st, k) False = undefined
147145
refresh db stack key result = case (addStack key stack, result) of
148146
(Left e, _) -> throw e
149-
(Right stack, Just me@Result{resultDeps = ResultDeps (HSet.toList -> deps)}) -> do
147+
(Right stack, Just me@Result{resultDeps = ResultDeps (toListKeySet -> deps)}) -> do
150148
res <- builder db stack deps
151149
let isDirty = any (\(_,dep) -> resultBuilt me < resultChanged dep)
152150
case res of
@@ -178,7 +176,7 @@ compute db@Database{..} stack key mode result = do
178176
previousDeps= maybe UnknownDeps resultDeps result
179177
let res = Result runValue built' changed built actualDeps execution runStore
180178
case getResultDepsDefault mempty actualDeps of
181-
deps | not(null deps)
179+
deps | not(nullKeySet deps)
182180
&& runChanged /= ChangedNothing
183181
-> do
184182
-- IMPORTANT: record the reverse deps **before** marking the key Clean.
@@ -236,15 +234,15 @@ splitIO act = do
236234
updateReverseDeps
237235
:: Key -- ^ Id
238236
-> Database
239-
-> HashSet Key -- ^ Previous direct dependencies of Id
240-
-> HashSet Key -- ^ Current direct dependencies of Id
237+
-> KeySet -- ^ Previous direct dependencies of Id
238+
-> KeySet -- ^ Current direct dependencies of Id
241239
-> IO ()
242240
-- mask to ensure that all the reverse dependencies are updated
243241
updateReverseDeps myId db prev new = do
244-
forM_ (HSet.toList $ prev `HSet.difference` new) $ \d ->
245-
doOne (HSet.delete myId) d
246-
forM_ (HSet.toList new) $
247-
doOne (HSet.insert myId)
242+
forM_ (toListKeySet $ prev `differenceKeySet` new) $ \d ->
243+
doOne (deleteKeySet myId) d
244+
forM_ (toListKeySet new) $
245+
doOne (insertKeySet myId)
248246
where
249247
alterRDeps f =
250248
Focus.adjust (onKeyReverseDeps f)
@@ -254,18 +252,18 @@ updateReverseDeps myId db prev new = do
254252
doOne f id = atomicallyNamed "updateReverseDeps" $
255253
SMap.focus (alterRDeps f) id (databaseValues db)
256254

257-
getReverseDependencies :: Database -> Key -> STM (Maybe (HashSet Key))
255+
getReverseDependencies :: Database -> Key -> STM (Maybe KeySet)
258256
getReverseDependencies db = (fmap.fmap) keyReverseDeps . flip SMap.lookup (databaseValues db)
259257

260-
transitiveDirtySet :: Foldable t => Database -> t Key -> IO (HashSet Key)
261-
transitiveDirtySet database = flip State.execStateT HSet.empty . traverse_ loop
258+
transitiveDirtySet :: Foldable t => Database -> t Key -> IO KeySet
259+
transitiveDirtySet database = flip State.execStateT mempty . traverse_ loop
262260
where
263261
loop x = do
264262
seen <- State.get
265-
if x `HSet.member` seen then pure () else do
266-
State.put (HSet.insert x seen)
263+
if x `memberKeySet` seen then pure () else do
264+
State.put (insertKeySet x seen)
267265
next <- lift $ atomically $ getReverseDependencies database x
268-
traverse_ loop (maybe mempty HSet.toList next)
266+
traverse_ loop (maybe mempty toListKeySet next)
269267

270268
--------------------------------------------------------------------------------
271269
-- Asynchronous computations with cancellation

0 commit comments

Comments
 (0)