pub struct ConcurrentWrapper<P: ProgressLog = ProgressLogger> { /* private fields */ }Expand description
A ConcurrentProgressLog implementation that wraps a ProgressLog in
an Arc/Mutex.
The methods update and
update_with_count buffer the increment
and add it to the underlying logger only when the buffer reaches a
threshold; this prevents locking the underlying logger too often. The
threshold is set at creation using the methods
with_threshold and
wrap_with_threshold, or by calling the method
threshold; it is always clamped to
MAX_THRESHOLD.
The method light_update, as in the case of
ProgressLogger, further delays updates using an even faster check.
§Examples
In this example, we manually spawn processes:
let mut cpl = concurrent_progress_logger![item_name = "pumpkin"];
cpl.start("Smashing pumpkins (using many threads)...");
std::thread::scope(|s| {
for i in 0..100 {
let mut pl = cpl.clone();
s.spawn(move || {
for _ in 0..100000 {
// do something on each pumpkin
pl.update();
}
});
}
});
cpl.done();You can obtain the same behavior with
rayon using methods such as
for_each_with
and
map_with:
let mut cpl = concurrent_progress_logger![item_name = "pumpkin"];
cpl.start("Smashing pumpkins (using many threads)...");
(0..1000000).into_par_iter().
with_min_len(1000). // optional, might reduce the amount of cloning
for_each_with(cpl.clone(), |pl, i| {
// do something on each pumpkin
pl.update();
}
);
cpl.done();Note that you have to pass cpl.clone() to avoid a move that would make the
call to done impossible. Also, since
for_each_with
might perform excessive cloning if jobs are too short, you can use
with_min_len
to reduce the amount of cloning.
Implementations§
Source§impl ConcurrentWrapper
impl ConcurrentWrapper
Sourcepub fn new() -> Self
pub fn new() -> Self
Creates a new ConcurrentWrapper based on a default
ProgressLogger, using the default
threshold.
Sourcepub fn with_threshold(threshold: u32) -> Self
pub fn with_threshold(threshold: u32) -> Self
Creates a new ConcurrentWrapper wrapping a default
ProgressLogger, using the given threshold.
The threshold is clamped to MAX_THRESHOLD.
Source§impl<P: ProgressLog> ConcurrentWrapper<P>
impl<P: ProgressLog> ConcurrentWrapper<P>
Sourcepub const DEFAULT_THRESHOLD: u32
pub const DEFAULT_THRESHOLD: u32
The default threshold for updating the underlying logger.
Sourcepub const LIGHT_UPDATE_MASK: u32
pub const LIGHT_UPDATE_MASK: u32
Calls to light_update will cause a call
to update_with_count only if the
current local count is a multiple of this mask plus one and at least
equal to the threshold.
Note that this constant is significantly smaller than the one used in
ProgressLogger, as updates will be further delayed by the threshold
mechanism.
Sourcepub const MAX_THRESHOLD: u32
pub const MAX_THRESHOLD: u32
The maximum possible threshold for updating the underlying logger.
Thresholds passed to with_threshold,
wrap_with_threshold, and
threshold are clamped to this value, which
guarantees that the internal counter used by
light_update cannot overflow.
Sourcepub fn threshold(&mut self, threshold: u32) -> &mut Self
pub fn threshold(&mut self, threshold: u32) -> &mut Self
Sets the threshold for updating the underlying logger.
The threshold is clamped to MAX_THRESHOLD.
Note that concurrent loggers with the same underlying logger have independent thresholds.
Sourcepub fn wrap(inner: P) -> Self
pub fn wrap(inner: P) -> Self
Wraps a given ProgressLog in a ConcurrentWrapper
using the default threshold.
Sourcepub fn wrap_with_threshold(inner: P, threshold: u32) -> Self
pub fn wrap_with_threshold(inner: P, threshold: u32) -> Self
Wraps a given ProgressLog in a ConcurrentWrapper using a
given threshold.
The threshold is clamped to MAX_THRESHOLD.
Sourcepub fn flush(&mut self)
pub fn flush(&mut self)
Forces an update of the underlying logger with the current local count, if nonzero.
If the local count is zero, this method has no effect; in particular,
dropping a wrapper after stop or
done will not log spuriously. If the mutex
guarding the underlying logger has been poisoned by a panic in another
thread, the local count is discarded.
Source§impl<P: ProgressLog + Clone> ConcurrentWrapper<P>
impl<P: ProgressLog + Clone> ConcurrentWrapper<P>
Sourcepub fn dup(&self) -> Self
pub fn dup(&self) -> Self
Duplicates the concurrent wrapper, obtaining a new one with the same
threshold, with a local count of zero, and with an inner
ProgressLog that is a clone of the original one.
Trait Implementations§
Source§impl<P: ProgressLog + Clone> Clone for ConcurrentWrapper<P>
impl<P: ProgressLog + Clone> Clone for ConcurrentWrapper<P>
Source§fn clone(&self) -> Self
fn clone(&self) -> Self
Clones the concurrent wrapper, obtaining a new one with the same
threshold, with a local count of zero, and with the same inner
ProgressLog.
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl<P: ProgressLog + Clone + Send> ConcurrentProgressLog for ConcurrentWrapper<P>
impl<P: ProgressLog + Clone + Send> ConcurrentProgressLog for ConcurrentWrapper<P>
Source§type Duplicated = ConcurrentWrapper<P>
type Duplicated = ConcurrentWrapper<P>
dup.Source§impl Default for ConcurrentWrapper
impl Default for ConcurrentWrapper
Source§fn default() -> Self
fn default() -> Self
Creates a new ConcurrentWrapper based on a default
ProgressLogger, with a threshold of
DEFAULT_THRESHOLD.
Source§impl<P: ProgressLog + Display> Display for ConcurrentWrapper<P>
impl<P: ProgressLog + Display> Display for ConcurrentWrapper<P>
Source§impl<P: ProgressLog> Drop for ConcurrentWrapper<P>
This implementation just calls flush,
to guarantee that all updates are correctly passed to the underlying logger.
impl<P: ProgressLog> Drop for ConcurrentWrapper<P>
This implementation just calls flush,
to guarantee that all updates are correctly passed to the underlying logger.
Source§impl<P: ProgressLog + Clone + Send> ProgressLog for ConcurrentWrapper<P>
impl<P: ProgressLog + Clone + Send> ProgressLog for ConcurrentWrapper<P>
Source§type Concurrent = ConcurrentWrapper<P>
type Concurrent = ConcurrentWrapper<P>
concurrent.Source§fn add_to_count(&mut self, count: usize)
fn add_to_count(&mut self, count: usize)
Source§fn display_memory(&mut self, display_memory: bool) -> &mut Self
fn display_memory(&mut self, display_memory: bool) -> &mut Self
Source§fn log_interval(&mut self, log_interval: Duration) -> &mut Self
fn log_interval(&mut self, log_interval: Duration) -> &mut Self
Source§fn expected_updates(
&mut self,
expected_updates: impl Into<Option<usize>>,
) -> &mut Self
fn expected_updates( &mut self, expected_updates: impl Into<Option<usize>>, ) -> &mut Self
Source§fn time_unit(&mut self, time_unit: impl Into<Option<TimeUnit>>) -> &mut Self
fn time_unit(&mut self, time_unit: impl Into<Option<TimeUnit>>) -> &mut Self
Source§fn local_speed(&mut self, local_speed: bool) -> &mut Self
fn local_speed(&mut self, local_speed: bool) -> &mut Self
Source§fn push_log_target(&mut self, suffix: impl AsRef<str>) -> &mut Self
fn push_log_target(&mut self, suffix: impl AsRef<str>) -> &mut Self
Source§fn pop_log_target(&mut self) -> &mut Self
fn pop_log_target(&mut self) -> &mut Self
push_log_target. Read moreSource§fn start(&mut self, msg: impl AsRef<str>)
fn start(&mut self, msg: impl AsRef<str>)
Source§fn update_with_count_and_time(&mut self, count: usize, now: Instant)
fn update_with_count_and_time(&mut self, count: usize, now: Instant)
Source§fn update_with_count(&mut self, count: usize)
fn update_with_count(&mut self, count: usize)
Source§fn light_update(&mut self)
fn light_update(&mut self)
Source§fn update_and_display(&mut self)
fn update_and_display(&mut self)
Source§fn done(&mut self)
fn done(&mut self)
Completed., and displays the final stats.
The number of expected updates will be cleared.Source§fn done_with_count(&mut self, count: usize)
fn done_with_count(&mut self, count: usize)
Completed., and displays the
final stats. The number of expected updates will be cleared. Read moreSource§fn elapsed(&self) -> Option<Duration>
fn elapsed(&self) -> Option<Duration>
None if the
logger has not been started.Source§fn refresh(&mut self)
fn refresh(&mut self)
display_memory. There is no need to
call this method unless the logger is displayed manually.