@@ -125,16 +125,19 @@ builder db@Database{..} keys = do
125125cleanupAsync :: IORef [Async a ] -> IO ()
126126cleanupAsync ref = mapConcurrently_ uninterruptibleCancel =<< readIORef ref
127127
128-
129128-- | Check if we need to run the database.
130129check :: Database -> Key -> Id -> Maybe Result -> IO Result
131130check db key id result@ (Just me@ Result {resultDeps= Just deps}) = do
132- amDirty <- isDirty db id
133- mode <- if amDirty
131+ dirtySet <- getDirtySet db
132+ let allDirty = reverseDepsAllDirty (databaseReverseDeps db)
133+ let isDirty id = allDirty
134+ || HSet. member id dirtySet
135+ mode <- if isDirty id
134136 -- Event if I am dirty, it is still possible that all my dependencies are unchanged
135137 -- thanks to early cutoff, and therefore we must check to avoid redundant work
136138 then do
137- res <- builder db $ map Left deps
139+ let dirtyDeps = if allDirty then deps else filter isDirty deps
140+ res <- builder db $ map Left dirtyDeps
138141 let dirty = any (\ (_,dep) -> resultBuilt me < resultChanged dep) res
139142 return $ if dirty then Shake. RunDependenciesChanged else Shake. RunDependenciesSame
140143 -- If I am not dirty then none of my dependencies are, so they must be unchanged
@@ -205,12 +208,6 @@ flushDirty Database{databaseReverseDeps} = do
205208 cleanIds <- atomicModifyIORef' (reverseDepsClean databaseReverseDeps) (mempty ,)
206209 atomicModifyIORef'_ (reverseDepsDirty databaseReverseDeps) (`HSet.difference` cleanIds)
207210
208- isDirty :: Database -> Id -> IO Bool
209- isDirty db@ Database {databaseReverseDeps} id
210- | reverseDepsAllDirty databaseReverseDeps = pure True
211- | otherwise =
212- HSet. member id <$> getDirtySet db
213-
214211getDirtySet :: Database -> IO (HSet. HashSet Id )
215212getDirtySet db = readIORef (reverseDepsDirty $ databaseReverseDeps db)
216213
0 commit comments