@@ -125,16 +125,19 @@ builder db@Database{..} keys = do
125
125
cleanupAsync :: IORef [Async a ] -> IO ()
126
126
cleanupAsync ref = mapConcurrently_ uninterruptibleCancel =<< readIORef ref
127
127
128
-
129
128
-- | Check if we need to run the database.
130
129
check :: Database -> Key -> Id -> Maybe Result -> IO Result
131
130
check 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
134
136
-- Event if I am dirty, it is still possible that all my dependencies are unchanged
135
137
-- thanks to early cutoff, and therefore we must check to avoid redundant work
136
138
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
138
141
let dirty = any (\ (_,dep) -> resultBuilt me < resultChanged dep) res
139
142
return $ if dirty then Shake. RunDependenciesChanged else Shake. RunDependenciesSame
140
143
-- If I am not dirty then none of my dependencies are, so they must be unchanged
@@ -205,12 +208,6 @@ flushDirty Database{databaseReverseDeps} = do
205
208
cleanIds <- atomicModifyIORef' (reverseDepsClean databaseReverseDeps) (mempty ,)
206
209
atomicModifyIORef'_ (reverseDepsDirty databaseReverseDeps) (`HSet.difference` cleanIds)
207
210
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
-
214
211
getDirtySet :: Database -> IO (HSet. HashSet Id )
215
212
getDirtySet db = readIORef (reverseDepsDirty $ databaseReverseDeps db)
216
213
0 commit comments