mirror of
https://github.com/unisonweb/unison.git
synced 2024-11-10 20:00:27 +03:00
make computeFrontier more efficient, rename to computeDirty
This commit is contained in:
parent
875d3847b3
commit
b8257d306f
@ -39,6 +39,7 @@ import Unison.Term ( Term )
|
||||
import Unison.Util.Free ( Free
|
||||
, eval
|
||||
)
|
||||
import Unison.Util.Monoid ( foldMapM )
|
||||
import qualified Unison.Util.Relation as R
|
||||
import Unison.Util.TransitiveClosure ( transitiveClosure )
|
||||
import Unison.Var ( Var )
|
||||
@ -259,7 +260,7 @@ propagate rootNames patch b = case validatePatch patch of
|
||||
[] -> Referent.toString r
|
||||
n : _ -> show n
|
||||
|
||||
initialDirty <- R.dom <$> computeFrontier (eval . GetDependents) patch names0
|
||||
initialDirty <- computeDirty (eval . GetDependents) patch names0
|
||||
|
||||
let initialTypeReplacements = Map.mapMaybe TypeEdit.toReference initialTypeEdits
|
||||
-- TODO: once patches can directly contain constructor replacements, this
|
||||
@ -623,37 +624,25 @@ applyPropagate patch Edits {..} = do
|
||||
-- typePreservingTermEdits Patch {..} = Patch termEdits mempty
|
||||
-- where termEdits = R.filterRan TermEdit.isTypePreserving _termEdits
|
||||
|
||||
-- (d, f) when d is "dirty" (needs update),
|
||||
-- f is in the frontier (an edited dependency of d),
|
||||
-- and d depends on f
|
||||
-- a ⋖ b = a depends directly on b
|
||||
-- dirty(d) ∧ frontier(f) <=> not(edited(d)) ∧ edited(f) ∧ d ⋖ f
|
||||
-- | Compute the set of "dirty" references. They each:
|
||||
--
|
||||
-- The range of this relation is the frontier, and the domain is
|
||||
-- the set of dirty references.
|
||||
computeFrontier
|
||||
-- 1. Depend directly on some reference that was edited in the given patch
|
||||
-- 2. Have a name in the current namespace (the given Names)
|
||||
-- 3. Are not themselves edited in the given patch.
|
||||
computeDirty
|
||||
:: forall m
|
||||
. Monad m
|
||||
=> (Reference -> m (Set Reference)) -- eg Codebase.dependents codebase
|
||||
-> Patch
|
||||
-> Names
|
||||
-> m (R.Relation Reference Reference)
|
||||
computeFrontier getDependents patch names = do
|
||||
-- (r,r2) ∈ dependsOn if r depends on r2
|
||||
dependsOn <- foldM addDependents R.empty edited
|
||||
-- Dirty is everything that `dependsOn` Frontier, minus already edited defns
|
||||
pure $ R.filterDom (not . flip Set.member edited) dependsOn
|
||||
where
|
||||
-> m (Set Reference)
|
||||
computeDirty getDependents patch names =
|
||||
foldMapM (\ref -> keepDirtyDependents <$> getDependents ref) edited
|
||||
where
|
||||
-- Given a set of dependent references (satisfying 1. above), keep only the dirty ones (per 2. and 3. above)
|
||||
keepDirtyDependents :: Set Reference -> Set Reference
|
||||
keepDirtyDependents =
|
||||
(`Set.difference` edited) . Set.filter (Names.contains names)
|
||||
|
||||
edited :: Set Reference
|
||||
edited = R.dom (Patch._termEdits patch) <> R.dom (Patch._typeEdits patch)
|
||||
addDependents
|
||||
:: R.Relation Reference Reference
|
||||
-> Reference
|
||||
-> m (R.Relation Reference Reference)
|
||||
addDependents dependents ref =
|
||||
(\ds -> R.insertManyDom ds ref dependents)
|
||||
. Set.filter isNamed
|
||||
<$> getDependents ref
|
||||
isNamed :: Reference -> Bool
|
||||
isNamed =
|
||||
Names.contains names
|
||||
|
Loading…
Reference in New Issue
Block a user