Skip to content

Commit 6f83ff0

Browse files
committed
Improve asymptotics
1 parent 0dda71b commit 6f83ff0

File tree

1 file changed

+14
-6
lines changed

1 file changed

+14
-6
lines changed

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

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import Control.Monad.Trans.Class (lift)
1818
import Data.Foldable (for_)
1919
import Data.Functor (($>))
2020
import qualified Data.HashMap.Strict as HMap
21+
import Data.Maybe (isJust)
2122
import qualified Data.Text as T
2223
import Data.Unique
2324
import Development.IDE.GHC.Orphans ()
@@ -46,7 +47,6 @@ noProgressReporting = return $ ProgressReporting
4647
, inProgress = const id
4748
, progressStop = pure ()
4849
}
49-
5050
data State
5151
= NotStarted
5252
| Completed
@@ -65,6 +65,8 @@ updateState _ (Event KickCompleted) st = pure st
6565
updateState _ StopProgress (Running a) = cancel a $> Stopped
6666
updateState _ StopProgress st = pure st
6767

68+
data InProgress = InProgress {todo, done :: !Int, current :: !(HMap.HashMap NormalizedFilePath Int)}
69+
6870
-- | A 'ProgressReporting' that enqueues Begin and End notifications in a new
6971
-- thread, with a grace period (nothing will be sent if 'KickCompleted' arrives
7072
-- before the end of the grace period).
@@ -76,7 +78,7 @@ delayedProgressReporting
7678
-> ProgressReportingStyle
7779
-> IO ProgressReporting
7880
delayedProgressReporting before after lspEnv optProgressStyle = do
79-
inProgressVar <- newVar (HMap.empty @NormalizedFilePath @Int)
81+
inProgressVar <- newVar $ InProgress 0 0 mempty
8082
progressState <- newVar NotStarted
8183
let progressUpdate event = modifyVar_ progressState $ updateState (mRunLspT lspEnv $ lspShakeProgress inProgressVar) (Event event)
8284
progressStop = modifyVar_ progressState $ updateState (mRunLspT lspEnv $ lspShakeProgress inProgressVar) StopProgress
@@ -115,9 +117,7 @@ delayedProgressReporting before after lspEnv optProgressStyle = do
115117
}
116118
}
117119
loop id prev = do
118-
current <- liftIO $ readVar inProgress
119-
let done = length $ filter (== 0) $ HMap.elems current
120-
let todo = HMap.size current
120+
InProgress{..} <- liftIO $ readVar inProgress
121121
if todo == 0 then loop id 0 else do
122122
let next = 100 * fromIntegral done / fromIntegral todo
123123
liftIO $ sleep after
@@ -144,7 +144,15 @@ delayedProgressReporting before after lspEnv optProgressStyle = do
144144
-- This functions are deliberately eta-expanded to avoid space leaks.
145145
-- Do not remove the eta-expansion without profiling a session with at
146146
-- least 1000 modifications.
147-
where f shift = void $ modifyVar' var $ HMap.insertWith (\_ x -> shift x) file (shift 0)
147+
where
148+
f shift = void $ modifyVar' var $ \InProgress{..} ->
149+
case HMap.alterF alter file current of
150+
((prev, new), m') ->
151+
let todo' = if isJust prev then todo else todo + 1
152+
done' = if new == 0 then done+1 else done
153+
in InProgress todo' done' m'
154+
where
155+
alter x = let x' = maybe (shift 0) shift x in ((x,x'), Just x')
148156

149157
mRunLspT :: Applicative m => Maybe (LSP.LanguageContextEnv c ) -> LSP.LspT c m () -> m ()
150158
mRunLspT (Just lspEnv) f = LSP.runLspT lspEnv f

0 commit comments

Comments
 (0)