diff --git a/pie/src/context/bottom_up.rs b/pie/src/context/bottom_up.rs index 4a3c3dd..9eec5d1 100644 --- a/pie/src/context/bottom_up.rs +++ b/pie/src/context/bottom_up.rs @@ -32,7 +32,7 @@ impl<'p, 's> BottomUpContext<'p, 's> { /// Schedule tasks affected by `resource`. #[inline] - pub fn schedule_affected_by(&mut self, resource: &dyn KeyObj) { + pub fn schedule_tasks_affected_by(&mut self, resource: &dyn KeyObj) { let track_end = self.session.tracker.schedule_affected_by_resource(resource); let node = self.session.store.get_or_create_resource_node(resource); for (task_node, dependency) in self.session.store.get_read_and_write_dependencies_to_resource(&node) { diff --git a/pie/src/lib.rs b/pie/src/lib.rs index 0fde04b..f010914 100644 --- a/pie/src/lib.rs +++ b/pie/src/lib.rs @@ -54,7 +54,7 @@ pub trait Task: KeyBounds { } /// Programmatic incremental build context, enabling tasks to require other tasks and read/write from/to resources, -/// programmatically creating precise dependencies that are used to incrementally execute tasks. +/// programmatically creating precise dynamic dependencies that are used to incrementally execute tasks. /// /// Tasks can [require](Self::require) other tasks, creating a task dependency and getting their consistent (i.e., /// most up-to-date) output value. @@ -171,21 +171,24 @@ pub trait ResourceChecker: KeyBounds { /// Stamps `resource` with a `reader` for that resource. /// /// The `reader` is fresh: it is first passed to this checker before being passed to a task. However, because it is - /// later passed to a task, `reader` must be _left in a fresh state after stamping_. For example, a buffered reader - /// must be rewound after using it. + /// later passed to a task, `reader` must be _left in a fresh state after stamping_. For example, a + /// [buffered reader](std::io::BufReader) must be [rewound](std::io::Seek::rewind) after using it. fn stamp_reader(&self, resource: &R, reader: &mut R::Reader<'_>) -> Result; /// Stamps `resource` with a `writer` for that resource. /// /// The `writer` is dirty: it was first used by a task to write data. Therefore, be sure to restore the `writer` to a - /// fresh state before reading from it. For example, a file must be rewound after using it. + /// fresh state before reading from it. For example, a [file](std::fs::File) must be [rewound](std::io::Seek::rewind) + /// before using it. /// /// There is no guarantee that `resource` still exists, as it may have been removed by a task. Therefore, `writer` may - /// contain stale data for certain resources. If that can be the case, be sure to check whether `writer` is still - /// consistent w.r.t. `resource. + /// contain stale metadata for certain resources. For example, a [file](std::fs::File) can be + /// [removed](std::fs::remove_file), but its [file](std::fs::File) descriptor will still return cached (stale) + /// [metadata](std::fs::File::metadata). If that can be the case, be sure to check whether `writer` is still + /// consistent with `resource`. fn stamp_writer(&self, resource: &R, writer: R::Writer<'_>) -> Result; - /// Type of inconsistency used for debugging/logging purposes. The `'i` lifetime represents this checker, or the - /// resource/state/stamp passed to [Self::get_inconsistency]. + /// Type of inconsistency used for debugging/logging purposes. The `'i` lifetime represents this checker and the + /// lifetime of the `resource`, `state`, and `stamp` passed to [Self::get_inconsistency]. type Inconsistency<'i>: Debug; /// Checks whether `resource` is inconsistent w.r.t. `stamp`, with access to `state`. Returns `Some(inconsistency)` /// when inconsistent, `None` when consistent. @@ -262,28 +265,34 @@ impl<'p> Session<'p> { self.0.require(task) } - /// Creates a bottom-up build. Call [BottomUp::changed_resource] to schedule tasks affected by changed resources. Then - /// call [BottomUp::update_affected_tasks] to update all affected tasks in a bottom-up build. + /// Creates a bottom-up build. Call [schedule_tasks_affected_by](BottomUpBuild::schedule_tasks_affected_by) for each + /// changed resource to schedule tasks affected by changed resources. + /// + /// Then call [update_affected_tasks](BottomUpBuild::update_affected_tasks) to update all affected tasks in a + /// bottom-up build. + /// + /// Finally, use [require](Self::require) of this session to get up-to-date task outputs if needed. #[inline] #[must_use] - pub fn bottom_up_build<'s>(&'s mut self) -> BottomUp<'p, 's> { - BottomUp(self.0.bottom_up_build()) + pub fn create_bottom_up_build<'s>(&'s mut self) -> BottomUpBuild<'p, 's> { + BottomUpBuild(self.0.create_bottom_up_build()) } /// Gets all errors produced during dependency checks. #[inline] + #[must_use] pub fn dependency_check_errors(&self) -> impl Iterator + ExactSizeIterator { self.0.dependency_check_errors() } } #[repr(transparent)] -pub struct BottomUp<'p, 's>(pie::BottomUpInternal<'p, 's>); -impl<'p, 's> BottomUp<'p, 's> { +pub struct BottomUpBuild<'p, 's>(pie::BottomUpBuildInternal<'p, 's>); +impl<'p, 's> BottomUpBuild<'p, 's> { /// Schedule tasks affected by `resource`. #[inline] - pub fn changed_resource(&mut self, resource: &dyn KeyObj) { - self.0.changed_resource(resource); + pub fn schedule_tasks_affected_by(&mut self, resource: &dyn KeyObj) { + self.0.schedule_tasks_affected_by(resource); } /// Update all tasks affected by resource changes. #[inline] diff --git a/pie/src/pie.rs b/pie/src/pie.rs index 0c43879..6919ebe 100644 --- a/pie/src/pie.rs +++ b/pie/src/pie.rs @@ -82,8 +82,8 @@ impl<'p> SessionInternal<'p> { } #[inline] - pub fn bottom_up_build<'s>(&'s mut self) -> BottomUpInternal<'p, 's> { - BottomUpInternal(BottomUpContext::new(self)) + pub fn create_bottom_up_build<'s>(&'s mut self) -> BottomUpBuildInternal<'p, 's> { + BottomUpBuildInternal(BottomUpContext::new(self)) } #[inline] @@ -92,13 +92,13 @@ impl<'p> SessionInternal<'p> { } } -/// Internals for [`BottomUpInternal`]. +/// Internals for [`BottomUpBuildInternal`]. #[repr(transparent)] -pub struct BottomUpInternal<'p, 's>(BottomUpContext<'p, 's>); -impl<'p, 's> BottomUpInternal<'p, 's> { +pub struct BottomUpBuildInternal<'p, 's>(BottomUpContext<'p, 's>); +impl<'p, 's> BottomUpBuildInternal<'p, 's> { #[inline] - pub fn changed_resource(&mut self, resource: &dyn KeyObj) { - self.0.schedule_affected_by(resource); + pub fn schedule_tasks_affected_by(&mut self, resource: &dyn KeyObj) { + self.0.schedule_tasks_affected_by(resource); } #[inline] pub fn update_affected_tasks(mut self) { diff --git a/pie/tests/bottom_up.rs b/pie/tests/bottom_up.rs index d45193d..abdc863 100644 --- a/pie/tests/bottom_up.rs +++ b/pie/tests/bottom_up.rs @@ -50,7 +50,7 @@ fn test_directly_affected_task() -> TestResult { // Change the file that the task requires, directly affecting it. write_until_modified(&path, "hello world!")?; - pie.bottom_up_build_then_assert(|b| b.changed_resource(&path), |tracker| { + pie.bottom_up_build_then_assert(|b| b.schedule_tasks_affected_by(&path), |tracker| { assert_matches!(tracker.first_execute_end(&task), Some(d) => { assert_eq!(d.output.cast(), Ok("hello world!")); }); @@ -75,7 +75,7 @@ fn test_indirectly_affected_tasks() -> TestResult { // Change the file that ReadFile requires, directly affecting it, indirectly affecting ToLower. write_until_modified(&path, "HELLO WORLD!!")?; - pie.bottom_up_build_then_assert(|b| b.changed_resource(&path), |tracker| { + pie.bottom_up_build_then_assert(|b| b.schedule_tasks_affected_by(&path), |tracker| { // ReadFile let read_task_end = assert_matches!(tracker.first_execute_end(&read_task), Some(d) => { assert_eq!(d.output.cast(), Ok("HELLO WORLD!!")); @@ -110,7 +110,7 @@ fn test_indirectly_affected_tasks_early_cutoff() -> TestResult { // Change the file that ReadFile requires, directly affecting it, indirectly affecting ToLower, but not affecting // WriteFile because the output from ToLower does not change. write_until_modified(&read_path, "hello world!")?; - pie.bottom_up_build_then_assert(|b| b.changed_resource(&read_path), |tracker| { + pie.bottom_up_build_then_assert(|b| b.schedule_tasks_affected_by(&read_path), |tracker| { // ReadFile let read_task_end = assert_matches!(tracker.first_execute_end(&read_task), Some(d) => { assert_eq!(d.output.cast(), Ok("hello world!")); @@ -153,7 +153,7 @@ fn test_indirectly_affected_multiple_tasks() -> TestResult { // Change the file that ReadFile requires, directly affecting it, indirectly affecting ToLower and // ToUpper, but not their WriteFile tasks. write_until_modified(&read_path, "hello world!")?; - pie.bottom_up_build_then_assert(|b| b.changed_resource(&read_path), |tracker| { + pie.bottom_up_build_then_assert(|b| b.schedule_tasks_affected_by(&read_path), |tracker| { // ReadFile let read_task_end = assert_matches!(tracker.first_execute_end(&read_task), Some(d) => { assert_eq!(d.output.cast(), Ok("hello world!")); @@ -179,7 +179,7 @@ fn test_indirectly_affected_multiple_tasks() -> TestResult { // Change the file that ReadFile requires, directly affecting it, indirectly affecting all other tasks. write_until_modified(&read_path, "hello world!!")?; - pie.bottom_up_build_then_assert(|b| b.changed_resource(&read_path), |tracker| { + pie.bottom_up_build_then_assert(|b| b.schedule_tasks_affected_by(&read_path), |tracker| { // ReadFile let read_task_end = assert_matches!(tracker.first_execute_end(&read_task), Some(d) => { assert_eq!(d.output.cast(), Ok("hello world!!")); @@ -253,8 +253,8 @@ fn test_require_now() -> TestResult { // Change the file that ReadFile reads, which `to_lower_task` depends on, thus `to_lower_task` is affected and should be executed. write_until_modified(&read_path, "hello world!!")?; pie.bottom_up_build_then_assert(|b| { - b.changed_resource(&read_path); - b.changed_resource(&marker_path) + b.schedule_tasks_affected_by(&read_path); + b.schedule_tasks_affected_by(&marker_path) }, |tracker| { let task_end = assert_matches!(tracker.first_execute_end_index(&task), Some(i) => i); let to_lower_task_end = assert_matches!(tracker.first_execute_end_index(&to_lower_task), Some(i) => i); diff --git a/pie/tests/util/mod.rs b/pie/tests/util/mod.rs index a950374..f8a7f56 100644 --- a/pie/tests/util/mod.rs +++ b/pie/tests/util/mod.rs @@ -1,6 +1,6 @@ use std::io::{BufWriter, Stdout}; -use pie::{BottomUp, Pie, Session, Task}; +use pie::{BottomUpBuild, Pie, Session, Task}; use pie::tracker::CompositeTracker; use pie::tracker::event::EventTracker; use pie::tracker::writing::WritingTracker; @@ -58,11 +58,11 @@ pub trait TestPieExt { fn bottom_up_build_then_assert( &mut self, - bottom_up_func: impl FnOnce(&mut BottomUp), + bottom_up_func: impl FnOnce(&mut BottomUpBuild), test_assert_func: impl FnOnce(&EventTracker), ) { self.assert_in_session(|s| { - let mut bottom_up = s.bottom_up_build(); + let mut bottom_up = s.create_bottom_up_build(); bottom_up_func(&mut bottom_up); bottom_up.update_affected_tasks(); }, test_assert_func)