@@ -27,7 +27,7 @@ import Control.Monad.Trans.Reader
27
27
import qualified Control.Monad.Trans.State.Strict as State
28
28
import Data.Dynamic
29
29
import Data.Either
30
- import Data.Foldable (traverse_ )
30
+ import Data.Foldable (for_ , traverse_ )
31
31
import Data.HashSet (HashSet )
32
32
import qualified Data.HashSet as HSet
33
33
import Data.IORef.Extra
@@ -51,27 +51,27 @@ newDatabase databaseExtra databaseRules = do
51
51
52
52
-- | Increment the step and mark dirty
53
53
incDatabase :: Database -> Maybe [Key ] -> STM ()
54
- -- all keys are dirty
55
- incDatabase db Nothing = incDatabaseGen (const True ) db
56
54
-- only some keys are dirty
57
55
incDatabase db (Just kk) = do
56
+ modifyTVar' (databaseStep db) $ \ (Step i) -> Step $ i + 1
58
57
transitiveDirtyKeys <- transitiveDirtySet db kk
59
- incDatabaseGen (`HSet.member` transitiveDirtyKeys) db
58
+ for_ transitiveDirtyKeys $ \ k ->
59
+ SMap. focus updateDirty k (databaseValues db)
60
60
61
- incDatabaseGen :: ( Key -> Bool ) -> Database -> STM ()
62
- incDatabaseGen pred db = do
61
+ -- all keys are dirty
62
+ incDatabase db Nothing = do
63
63
modifyTVar' (databaseStep db) $ \ (Step i) -> Step $ i + 1
64
64
let list = SMap. listT (databaseValues db)
65
- reset k (KeyDetails status rdeps) =
65
+ flip ListT. traverse_ list $ \ (k,_) -> do
66
+ SMap. focus updateDirty k (databaseValues db)
67
+
68
+ updateDirty :: Monad m => Focus. Focus KeyDetails m ()
69
+ updateDirty = Focus. adjust $ \ (KeyDetails status rdeps) ->
66
70
let status'
67
- | Running _ _ x <- status = Dirty x
68
- | Clean x <- status
69
- , pred k = Dirty (Just x)
71
+ | Running _ _ _ x <- status = Dirty x
72
+ | Clean x <- status = Dirty (Just x)
70
73
| otherwise = status
71
74
in KeyDetails status' rdeps
72
- flip ListT. traverse_ list $ \ (k,v) -> do
73
- SMap. insert (reset k v) k (databaseValues db)
74
-
75
75
-- | Unwrap and build a list of keys in parallel
76
76
build
77
77
:: forall key value . (RuleResult key ~ value , Typeable key , Show key , Hashable key , Eq key , Typeable value )
@@ -92,19 +92,19 @@ builder
92
92
builder db@ Database {.. } keys = withRunInIO $ \ (RunInIO run) -> do
93
93
-- Things that I need to force before my results are ready
94
94
toForce <- liftIO $ newTVarIO []
95
- results <- liftIO $ atomically $ do
96
- for keys $ \ id -> do
95
+ current <- liftIO $ readTVarIO databaseStep
96
+ results <- liftIO $ atomically $ for keys $ \ id -> do
97
97
-- Spawn the id if needed
98
98
status <- SMap. lookup id databaseValues
99
- val <- case maybe (Dirty Nothing ) keyStatus status of
99
+ val <- case viewDirty current $ maybe (Dirty Nothing ) keyStatus status of
100
100
Clean r -> pure r
101
- Running force val _ -> do
101
+ Running _ force val _ -> do
102
102
modifyTVar' toForce (Wait force : )
103
103
pure val
104
104
Dirty s -> do
105
105
let act = run (refresh db id s)
106
106
(force, val) = splitIO (join act)
107
- SMap. focus (updateStatus $ Running force val s) id databaseValues
107
+ SMap. focus (updateStatus $ Running current force val s) id databaseValues
108
108
modifyTVar' toForce (Spawn force: )
109
109
pure val
110
110
0 commit comments