/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 | | } |