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