Coverage Report

Created: 2025-12-31 07:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/prodash-30.0.1/src/tree/root.rs
Line
Count
Source
1
use std::{
2
    ops::Deref,
3
    sync::{atomic::AtomicUsize, Arc, Weak},
4
};
5
6
use parking_lot::Mutex;
7
8
use crate::{
9
    messages::{Message, MessageCopyState, MessageRingBuffer},
10
    progress::{Id, Key, Task},
11
    tree::{Item, Root},
12
};
13
14
impl Root {
15
    /// Create a new tree with default configuration.
16
    ///
17
    /// As opposed to [Item](./struct.Item.html) instances, this type can be closed and sent
18
    /// safely across threads.
19
0
    pub fn new() -> Arc<Root> {
20
0
        Options::default().into()
21
0
    }
22
23
    /// Returns the maximum amount of messages we can keep before overwriting older ones.
24
0
    pub fn messages_capacity(&self) -> usize {
25
0
        self.inner.lock().messages.lock().buf.capacity()
26
0
    }
27
28
    /// Returns the current amount of `Item`s stored in the tree.
29
    /// **Note** that this is at most a guess as tasks can be added and removed in parallel.
30
0
    pub fn num_tasks(&self) -> usize {
31
        #[cfg(feature = "progress-tree-hp-hashmap")]
32
        {
33
            self.inner.lock().tree.len()
34
        }
35
        #[cfg(not(feature = "progress-tree-hp-hashmap"))]
36
        {
37
0
            self.inner.lock().tree.len()
38
        }
39
0
    }
40
41
    /// Adds a new child `tree::Item`, whose parent is this instance, with the given `name`.
42
    ///
43
    /// This builds a hierarchy of `tree::Item`s, each having their own progress.
44
    /// Use this method to [track progress](./struct.Item.html) of your first tasks.
45
0
    pub fn add_child(&self, name: impl Into<String>) -> Item {
46
0
        self.inner.lock().add_child(name)
47
0
    }
48
49
    /// Adds a new child `tree::Item`, whose parent is this instance, with the given `name` and `id`.
50
    ///
51
    /// This builds a hierarchy of `tree::Item`s, each having their own progress.
52
    /// Use this method to [track progress](./struct.Item.html) of your first tasks.
53
0
    pub fn add_child_with_id(&self, name: impl Into<String>, id: Id) -> Item {
54
0
        self.inner.lock().add_child_with_id(name, id)
55
0
    }
56
57
    /// Copy the entire progress tree into the given `out` vector, so that
58
    /// it can be traversed from beginning to end in order of hierarchy.
59
0
    pub fn sorted_snapshot(&self, out: &mut Vec<(Key, Task)>) {
60
0
        out.clear();
61
        #[cfg(feature = "progress-tree-hp-hashmap")]
62
        out.extend(self.inner.lock().tree.iter().map(|r| (*r.key(), r.value().clone())));
63
        #[cfg(not(feature = "progress-tree-hp-hashmap"))]
64
0
        self.inner.lock().tree.extend_to(out);
65
0
        out.sort_by_key(|t| t.0);
66
0
    }
67
68
    /// Copy all messages from the internal ring buffer into the given `out`
69
    /// vector. Messages are ordered from oldest to newest.
70
0
    pub fn copy_messages(&self, out: &mut Vec<Message>) {
71
0
        self.inner.lock().messages.lock().copy_all(out);
72
0
    }
73
74
    /// Copy only new messages from the internal ring buffer into the given `out`
75
    /// vector. Messages are ordered from oldest to newest.
76
0
    pub fn copy_new_messages(&self, out: &mut Vec<Message>, prev: Option<MessageCopyState>) -> MessageCopyState {
77
0
        self.inner.lock().messages.lock().copy_new(out, prev)
78
0
    }
79
80
    /// Duplicate all content and return it.
81
    ///
82
    /// This is an expensive operation, whereas `clone()` is not as it is shallow.
83
0
    pub fn deep_clone(&self) -> Arc<Root> {
84
0
        Arc::new(Root {
85
0
            inner: Mutex::new(self.inner.lock().deep_clone()),
86
0
        })
87
0
    }
88
}
89
90
/// A way to configure new [`tree::Root`](./tree/struct.Root.html) instances
91
/// ```rust
92
/// let tree = prodash::tree::root::Options::default().create();
93
/// let tree2 = prodash::tree::root::Options { message_buffer_capacity: 100, ..Default::default() }.create();
94
/// ```
95
#[derive(Clone, Debug)]
96
pub struct Options {
97
    /// The amount of [items][Item] the tree can hold without being forced to allocate.
98
    pub initial_capacity: usize,
99
    /// The amount of messages we can hold before we start overwriting old ones.
100
    pub message_buffer_capacity: usize,
101
}
102
103
impl Options {
104
    /// Create a new [`Root`](./tree/struct.Root.html) instance from the
105
    /// configuration within.
106
0
    pub fn create(self) -> Root {
107
0
        self.into()
108
0
    }
109
}
110
111
impl Default for Options {
112
0
    fn default() -> Self {
113
0
        Options {
114
0
            initial_capacity: 100,
115
0
            message_buffer_capacity: 20,
116
0
        }
117
0
    }
118
}
119
120
impl From<Options> for Arc<Root> {
121
0
    fn from(opts: Options) -> Self {
122
0
        Arc::new(opts.into())
123
0
    }
124
}
125
126
impl From<Options> for Root {
127
0
    fn from(
128
0
        Options {
129
0
            initial_capacity,
130
0
            message_buffer_capacity,
131
0
        }: Options,
132
0
    ) -> Self {
133
0
        Root {
134
0
            inner: Mutex::new(Item {
135
0
                highest_child_id: 0,
136
0
                value: Arc::new(AtomicUsize::default()),
137
0
                key: Key::default(),
138
0
                tree: Arc::new(crate::tree::HashMap::with_capacity(initial_capacity)),
139
0
                messages: Arc::new(Mutex::new(MessageRingBuffer::with_capacity(message_buffer_capacity))),
140
0
            }),
141
0
        }
142
0
    }
143
}
144
145
impl crate::WeakRoot for Weak<Root> {
146
    type Root = Arc<Root>;
147
148
0
    fn upgrade(&self) -> Option<Self::Root> {
149
0
        Weak::upgrade(self)
150
0
    }
151
}
152
153
impl crate::Root for Arc<Root> {
154
    type WeakRoot = Weak<Root>;
155
156
0
    fn messages_capacity(&self) -> usize {
157
0
        self.deref().messages_capacity()
158
0
    }
159
160
0
    fn num_tasks(&self) -> usize {
161
0
        self.deref().num_tasks()
162
0
    }
163
164
0
    fn sorted_snapshot(&self, out: &mut Vec<(Key, Task)>) {
165
0
        self.deref().sorted_snapshot(out)
166
0
    }
167
168
0
    fn copy_messages(&self, out: &mut Vec<Message>) {
169
0
        self.deref().copy_messages(out)
170
0
    }
171
172
0
    fn copy_new_messages(&self, out: &mut Vec<Message>, prev: Option<MessageCopyState>) -> MessageCopyState {
173
0
        self.deref().copy_new_messages(out, prev)
174
0
    }
175
176
0
    fn downgrade(&self) -> Self::WeakRoot {
177
0
        Arc::downgrade(self)
178
0
    }
179
}