Skip to content

Add custom cache layer for session loading #1197

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 29, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion ghcide/session-loader/Development/IDE/Session.hs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ import NameCache
import Packages
import Control.Exception (evaluate)
import Data.Void
import Control.Applicative (Alternative((<|>)))


data CacheDirs = CacheDirs
Expand Down Expand Up @@ -113,6 +114,11 @@ loadSessionWithOptions SessionLoadingOptions{..} dir = do
hscEnvs <- newVar Map.empty :: IO (Var HieMap)
-- Mapping from a Filepath to HscEnv
fileToFlags <- newVar Map.empty :: IO (Var FlagsMap)
-- Mapping from a Filepath to its 'hie.yaml' location.
-- Should hold the same Filepaths as 'fileToFlags', otherwise
-- they are inconsistent. So, everywhere you modify 'fileToFlags',
-- you have to modify 'filesMap' as well.
filesMap <- newVar HM.empty :: IO (Var FilesMap)
-- Version of the mappings above
version <- newVar 0
let returnWithVersion fun = IdeGhcSession fun <$> liftIO (readVar version)
Expand Down Expand Up @@ -271,6 +277,8 @@ loadSessionWithOptions SessionLoadingOptions{..} dir = do

modifyVar_ fileToFlags $ \var -> do
pure $ Map.insert hieYaml (HM.fromList (concatMap toFlagsMap all_targets)) var
modifyVar_ filesMap $ \var -> do
evaluate $ HM.union var (HM.fromList (zip (map fst $ concatMap toFlagsMap all_targets) (repeat hieYaml)))

extendKnownTargets all_targets

Expand Down Expand Up @@ -329,6 +337,8 @@ loadSessionWithOptions SessionLoadingOptions{..} dir = do
let res = (map (renderCradleError ncfp) err, Nothing)
modifyVar_ fileToFlags $ \var -> do
pure $ Map.insertWith HM.union hieYaml (HM.singleton ncfp (res, dep_info)) var
modifyVar_ filesMap $ \var -> do
evaluate $ HM.insert ncfp hieYaml var
return (res, maybe [] pure hieYaml ++ concatMap cradleErrorDependencies err)

-- This caches the mapping from hie.yaml + Mod.hs -> [String]
Expand Down Expand Up @@ -358,8 +368,10 @@ loadSessionWithOptions SessionLoadingOptions{..} dir = do
-- before attempting to do so.
let getOptions :: FilePath -> IO (IdeResult HscEnvEq, [FilePath])
getOptions file = do
ncfp <- toNormalizedFilePath' <$> canonicalizePath file
cachedHieYamlLocation <- HM.lookup ncfp <$> readVar filesMap
hieYaml <- cradleLoc file
sessionOpts (hieYaml, file) `catch` \e ->
sessionOpts (join cachedHieYamlLocation <|> hieYaml, file) `catch` \e ->
return (([renderPackageSetupException file e], Nothing), maybe [] pure hieYaml)

returnWithVersion $ \file -> do
Expand Down Expand Up @@ -543,7 +555,11 @@ renderCradleError nfp (CradleError _ _ec t) =
-- See Note [Multi Cradle Dependency Info]
type DependencyInfo = Map.Map FilePath (Maybe UTCTime)
type HieMap = Map.Map (Maybe FilePath) (HscEnv, [RawComponentInfo])
-- | Maps a "hie.yaml" location to all its Target Filepaths and options.
type FlagsMap = Map.Map (Maybe FilePath) (HM.HashMap NormalizedFilePath (IdeResult HscEnvEq, DependencyInfo))
-- | Maps a Filepath to its respective "hie.yaml" location.
-- It aims to be the reverse of 'FlagsMap'.
type FilesMap = HM.HashMap NormalizedFilePath (Maybe FilePath)

-- This is pristine information about a component
data RawComponentInfo = RawComponentInfo
Expand Down