[baobab/wip/vala: 19/41] threaded scanner: document the design
- From: Paolo Borelli <pborelli src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [baobab/wip/vala: 19/41] threaded scanner: document the design
- Date: Sun, 8 Jan 2012 19:14:09 +0000 (UTC)
commit f90e1c00a84c2f4c3a9d575e1a4696b825c2cdaa
Author: Ryan Lortie <desrt desrt ca>
Date: Thu Jan 5 19:54:47 2012 -0500
threaded scanner: document the design
Add a big comment to baobab-threaded-scanner.vala explaining the design.
src/baobab-threaded-scanner.vala | 40 +++++++++++++++++++++++++++++++++++++-
1 files changed, 39 insertions(+), 1 deletions(-)
---
diff --git a/src/baobab-threaded-scanner.vala b/src/baobab-threaded-scanner.vala
index a1b23cc..48fcc68 100644
--- a/src/baobab-threaded-scanner.vala
+++ b/src/baobab-threaded-scanner.vala
@@ -2,9 +2,43 @@ namespace Baobab {
class ThreadedScanner : Scanner {
AsyncQueue<ResultsArray> results_queue;
ThreadedScanner? self;
-
File directory;
+ /* General overview:
+ *
+ * We cannot directly modify the treemodel from the worker thread, so we have to have a way to dispatch
+ * the results back to the main thread.
+ *
+ * Each scanned directory gets a 'Results' struct created for it. If the directory has a parent
+ * directory, then the 'parent' pointer is set. The 'display_name' and 'parse_name' fields are filled
+ * in as soon as the struct is created. This part is done as soon as the directory is encountered.
+ *
+ * In order to determine all of the information for a particular directory (and finish filling in the
+ * results structure), we must scan it and all of its children. We must also scan all of the siblings
+ * of the directory so that we know what percentage of the total size of the parent directory the
+ * directory in question is responsible for.
+ *
+ * After a directory, all of its children and all of its siblings have been scanned, we can do the
+ * percentage calculation. We do this from the iteration that takes care of the parent directory: we
+ * collect an array of all of the child directory result structs and when we have them all, we assign
+ * the proper percentage to each. At this point we can report this array of result structs back to the
+ * main thread to be added to the treemodel.
+ *
+ * Back in the main thread, we receive a Results object. If the results object has not yet had a
+ * TreeIter assigned to it, we create it one. We use the parent results object to determine the correct
+ * place in the tree (assigning the parent an iter if required, recursively). When we create the iter,
+ * we fill in the data that existed from the start (ie: display name and parse name) and mark the status
+ * of the iter as 'scanning'.
+ *
+ * For the iter that was actually directly reported (ie: the one that's ready) we record the information
+ * into the treemodel and free the results structure (or Vala does it for us).
+ *
+ * We can be sure that the 'parent' field always points to valid memory because of the nature of the
+ * recursion and the queue. At the time we queue a Results struct for dispatch back to the main thread,
+ * its 'parent' is held on the stack by a higher invocation of add_directory(). This invocation will
+ * never finish without first pushing its own Results struct onto the queue -- after ours. It is
+ * therefore guaranteed that the 'parent' Results object will not be freed before each child.
+ */
[Compact]
class ResultsArray {
internal Results[] results;
@@ -110,6 +144,10 @@ namespace Baobab {
child_results.percent = 100 * ((double) child_results.size) / ((double) results.size);
}
+ /* No early exit. In order to avoid a potential crash, we absolutely *must* push this onto the
+ * queue after having passed it to any recursive invocation of add_directory() above. See the large
+ * comment at the top of this class for why.
+ */
results_queue.push ((owned) results_array);
return results;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]