1 Return-Path: <sojkam1@fel.cvut.cz>
\r
2 X-Original-To: notmuch@notmuchmail.org
\r
3 Delivered-To: notmuch@notmuchmail.org
\r
4 Received: from localhost (localhost [127.0.0.1])
\r
5 by olra.theworths.org (Postfix) with ESMTP id 1AC7242D292
\r
6 for <notmuch@notmuchmail.org>; Fri, 21 Jan 2011 01:59:59 -0800 (PST)
\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org
\r
11 X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none]
\r
13 Received: from olra.theworths.org ([127.0.0.1])
\r
14 by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)
\r
15 with ESMTP id QPpawzXo3AEM for <notmuch@notmuchmail.org>;
\r
16 Fri, 21 Jan 2011 01:59:57 -0800 (PST)
\r
17 Received: from mail.loccal.net (gw.loccal.net [94.142.235.206])
\r
18 by olra.theworths.org (Postfix) with ESMTP id 474F742D286
\r
19 for <notmuch@notmuchmail.org>; Fri, 21 Jan 2011 01:59:56 -0800 (PST)
\r
20 Received: from localhost (localhost [127.0.0.1])
\r
21 by mail.loccal.net (Postfix) with ESMTP id 3B8FE563D;
\r
22 Fri, 21 Jan 2011 11:12:32 +0100 (CET)
\r
23 X-Virus-Scanned: amavisd-new at loccal.net
\r
24 Received: from mail.loccal.net ([127.0.0.1])
\r
25 by localhost (mail.loccal.net [127.0.0.1]) (amavisd-new, port 10024)
\r
26 with LMTP id 3IMVpIy8C4cG; Fri, 21 Jan 2011 11:12:27 +0100 (CET)
\r
27 Received: from steelpick.2x.cz (unknown [10.21.129.4])
\r
28 by mail.loccal.net (Postfix) with ESMTPS id 26FB81BDAB;
\r
29 Fri, 21 Jan 2011 11:12:19 +0100 (CET)
\r
30 Received: from wsh by steelpick.2x.cz with local (Exim 4.72)
\r
31 (envelope-from <sojkam1@fel.cvut.cz>)
\r
32 id 1PgDmP-0003jp-Tb; Fri, 21 Jan 2011 10:59:42 +0100
\r
33 From: Michal Sojka <sojkam1@fel.cvut.cz>
\r
34 To: notmuch@notmuchmail.org
\r
35 Subject: [PATCH 3/3] new: Enhance progress reporting
\r
36 Date: Fri, 21 Jan 2011 10:59:37 +0100
\r
37 Message-Id: <1295603977-14326-5-git-send-email-sojkam1@fel.cvut.cz>
\r
38 X-Mailer: git-send-email 1.7.2.3
\r
39 In-Reply-To: <1295603977-14326-1-git-send-email-sojkam1@fel.cvut.cz>
\r
40 References: <1295603977-14326-1-git-send-email-sojkam1@fel.cvut.cz>
\r
41 X-BeenThere: notmuch@notmuchmail.org
\r
42 X-Mailman-Version: 2.1.13
\r
44 List-Id: "Use and development of the notmuch mail system."
\r
45 <notmuch.notmuchmail.org>
\r
46 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,
\r
47 <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>
\r
48 List-Archive: <http://notmuchmail.org/pipermail/notmuch>
\r
49 List-Post: <mailto:notmuch@notmuchmail.org>
\r
50 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>
\r
51 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,
\r
52 <mailto:notmuch-request@notmuchmail.org?subject=subscribe>
\r
53 X-List-Received-Date: Fri, 21 Jan 2011 09:59:59 -0000
\r
55 notmuch new reports progress only during the "first" phase when the
\r
56 files on disk are traversed and indexed. After this phase, other
\r
57 operations like rename detection and maildir flags synchronization are
\r
58 performed, but the user is not informed about them. Since these
\r
59 operations can take significant time, we want to inform the user about
\r
62 This patch enhances the progress reporting facility that was already
\r
63 present. The timer that triggers reporting is not stopped after the
\r
64 first phase but continues to run until all operations are finished. The
\r
65 rename detection and maildir flag synchronization are enhanced to report
\r
68 notmuch-new.c | 156 ++++++++++++++++++++++++++++++++++++---------------------
\r
69 1 files changed, 98 insertions(+), 58 deletions(-)
\r
71 diff --git a/notmuch-new.c b/notmuch-new.c
\r
72 index d71e497..fa7a76d 100644
\r
75 @@ -28,6 +28,7 @@ typedef struct _filename_node {
\r
78 typedef struct _filename_list {
\r
80 _filename_node_t *head;
\r
81 _filename_node_t **tail;
\r
83 @@ -50,12 +51,12 @@ typedef struct {
\r
84 _filename_list_t *message_ids_to_sync;
\r
85 } add_files_state_t;
\r
87 -static volatile sig_atomic_t do_add_files_print_progress = 0;
\r
88 +static volatile sig_atomic_t do_print_progress = 0;
\r
91 handle_sigalrm (unused (int signal))
\r
93 - do_add_files_print_progress = 1;
\r
94 + do_print_progress = 1;
\r
97 static volatile sig_atomic_t interrupted;
\r
98 @@ -81,6 +82,7 @@ _filename_list_create (const void *ctx)
\r
101 list->tail = &list->head;
\r
106 @@ -91,6 +93,8 @@ _filename_list_add (_filename_list_t *list,
\r
108 _filename_node_t *node = talloc (list, _filename_node_t);
\r
112 node->filename = talloc_strdup (list, filename);
\r
115 @@ -99,28 +103,28 @@ _filename_list_add (_filename_list_t *list,
\r
119 -add_files_print_progress (add_files_state_t *state)
\r
120 +generic_print_progress (const char *action, const char *object,
\r
121 + struct timeval tv_start, unsigned processed, unsigned total)
\r
123 struct timeval tv_now;
\r
124 double elapsed_overall, rate_overall;
\r
126 gettimeofday (&tv_now, NULL);
\r
128 - elapsed_overall = notmuch_time_elapsed (state->tv_start, tv_now);
\r
129 - rate_overall = (state->processed_files) / elapsed_overall;
\r
130 + elapsed_overall = notmuch_time_elapsed (tv_start, tv_now);
\r
131 + rate_overall = processed / elapsed_overall;
\r
133 - printf ("Processed %d", state->processed_files);
\r
134 + printf ("%s %d ", action, processed);
\r
136 - if (state->total_files) {
\r
138 double time_remaining;
\r
140 - time_remaining = ((state->total_files - state->processed_files) /
\r
142 - printf (" of %d files (", state->total_files);
\r
143 + time_remaining = ((total - processed) / rate_overall);
\r
144 + printf ("of %d %s (", total, object);
\r
145 notmuch_time_print_formatted_seconds (time_remaining);
\r
146 - printf (" remaining). \r");
\r
147 + printf (" remaining).\033[K\r");
\r
149 - printf (" files (%d files/sec.) \r", (int) rate_overall);
\r
150 + printf ("%s (%d %s/sec.)\033[K\r", object, (int) rate_overall, object);
\r
154 @@ -479,9 +483,10 @@ add_files_recursive (notmuch_database_t *notmuch,
\r
158 - if (do_add_files_print_progress) {
\r
159 - do_add_files_print_progress = 0;
\r
160 - add_files_print_progress (state);
\r
161 + if (do_print_progress) {
\r
162 + do_print_progress = 0;
\r
163 + generic_print_progress ("Processed", "files", state->tv_start,
\r
164 + state->processed_files, state->total_files);
\r
167 talloc_free (next);
\r
168 @@ -540,38 +545,56 @@ add_files_recursive (notmuch_database_t *notmuch,
\r
173 +setup_progress_printing_timer (void)
\r
175 + struct sigaction action;
\r
176 + struct itimerval timerval;
\r
178 + /* Setup our handler for SIGALRM */
\r
179 + memset (&action, 0, sizeof (struct sigaction));
\r
180 + action.sa_handler = handle_sigalrm;
\r
181 + sigemptyset (&action.sa_mask);
\r
182 + action.sa_flags = SA_RESTART;
\r
183 + sigaction (SIGALRM, &action, NULL);
\r
185 + /* Then start a timer to send SIGALRM once per second. */
\r
186 + timerval.it_interval.tv_sec = 1;
\r
187 + timerval.it_interval.tv_usec = 0;
\r
188 + timerval.it_value.tv_sec = 1;
\r
189 + timerval.it_value.tv_usec = 0;
\r
190 + setitimer (ITIMER_REAL, &timerval, NULL);
\r
194 +stop_progress_printing_timer (void)
\r
196 + struct sigaction action;
\r
197 + struct itimerval timerval;
\r
199 + /* Now stop the timer. */
\r
200 + timerval.it_interval.tv_sec = 0;
\r
201 + timerval.it_interval.tv_usec = 0;
\r
202 + timerval.it_value.tv_sec = 0;
\r
203 + timerval.it_value.tv_usec = 0;
\r
204 + setitimer (ITIMER_REAL, &timerval, NULL);
\r
206 + /* And disable the signal handler. */
\r
207 + action.sa_handler = SIG_IGN;
\r
208 + sigaction (SIGALRM, &action, NULL);
\r
212 /* This is the top-level entry point for add_files. It does a couple
\r
213 - * of error checks, sets up the progress-printing timer and then calls
\r
214 - * into the recursive function. */
\r
215 + * of error checks and then calls into the recursive function. */
\r
216 static notmuch_status_t
\r
217 add_files (notmuch_database_t *notmuch,
\r
219 add_files_state_t *state)
\r
221 notmuch_status_t status;
\r
222 - struct sigaction action;
\r
223 - struct itimerval timerval;
\r
224 - notmuch_bool_t timer_is_active = FALSE;
\r
227 - if (state->output_is_a_tty && ! debugger_is_active () && ! state->verbose) {
\r
228 - /* Setup our handler for SIGALRM */
\r
229 - memset (&action, 0, sizeof (struct sigaction));
\r
230 - action.sa_handler = handle_sigalrm;
\r
231 - sigemptyset (&action.sa_mask);
\r
232 - action.sa_flags = SA_RESTART;
\r
233 - sigaction (SIGALRM, &action, NULL);
\r
235 - /* Then start a timer to send SIGALRM once per second. */
\r
236 - timerval.it_interval.tv_sec = 1;
\r
237 - timerval.it_interval.tv_usec = 0;
\r
238 - timerval.it_value.tv_sec = 1;
\r
239 - timerval.it_value.tv_usec = 0;
\r
240 - setitimer (ITIMER_REAL, &timerval, NULL);
\r
242 - timer_is_active = TRUE;
\r
245 if (stat (path, &st)) {
\r
246 fprintf (stderr, "Error reading directory %s: %s\n",
\r
247 path, strerror (errno));
\r
248 @@ -585,19 +608,6 @@ add_files (notmuch_database_t *notmuch,
\r
250 status = add_files_recursive (notmuch, path, state);
\r
252 - if (timer_is_active) {
\r
253 - /* Now stop the timer. */
\r
254 - timerval.it_interval.tv_sec = 0;
\r
255 - timerval.it_interval.tv_usec = 0;
\r
256 - timerval.it_value.tv_sec = 0;
\r
257 - timerval.it_value.tv_usec = 0;
\r
258 - setitimer (ITIMER_REAL, &timerval, NULL);
\r
260 - /* And disable the signal handler. */
\r
261 - action.sa_handler = SIG_IGN;
\r
262 - sigaction (SIGALRM, &action, NULL);
\r
268 @@ -746,7 +756,7 @@ notmuch_new_command (void *ctx, int argc, char *argv[])
\r
269 notmuch_database_t *notmuch;
\r
270 add_files_state_t add_files_state;
\r
272 - struct timeval tv_now;
\r
273 + struct timeval tv_now, tv_start;
\r
276 const char *db_path;
\r
277 @@ -756,6 +766,7 @@ notmuch_new_command (void *ctx, int argc, char *argv[])
\r
278 int renamed_files, removed_files;
\r
279 notmuch_status_t status;
\r
281 + notmuch_bool_t timer_is_active = FALSE;
\r
283 add_files_state.verbose = 0;
\r
284 add_files_state.output_is_a_tty = isatty (fileno (stdout));
\r
285 @@ -768,7 +779,6 @@ notmuch_new_command (void *ctx, int argc, char *argv[])
\r
290 config = notmuch_config_open (ctx, NULL, NULL);
\r
291 if (config == NULL)
\r
293 @@ -831,21 +841,41 @@ notmuch_new_command (void *ctx, int argc, char *argv[])
\r
294 add_files_state.removed_files = _filename_list_create (ctx);
\r
295 add_files_state.removed_directories = _filename_list_create (ctx);
\r
297 + if (! debugger_is_active () && add_files_state.output_is_a_tty
\r
298 + && ! add_files_state.verbose) {
\r
299 + setup_progress_printing_timer ();
\r
300 + timer_is_active = TRUE;
\r
303 ret = add_files (notmuch, db_path, &add_files_state);
\r
307 + gettimeofday (&tv_start, NULL);
\r
308 for (f = add_files_state.removed_files->head; f; f = f->next) {
\r
309 status = notmuch_database_remove_message (notmuch, f->filename);
\r
310 if (status == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID)
\r
314 + if (do_print_progress) {
\r
315 + do_print_progress = 0;
\r
316 + generic_print_progress ("Cleaned up", "messages",
\r
317 + tv_start, removed_files + renamed_files,
\r
318 + add_files_state.removed_files->count);
\r
322 - for (f = add_files_state.removed_directories->head; f; f = f->next) {
\r
323 + gettimeofday (&tv_start, NULL);
\r
324 + for (f = add_files_state.removed_directories->head, i = 0; f; f = f->next, i++) {
\r
325 _remove_directory (ctx, notmuch, f->filename,
\r
326 &renamed_files, &removed_files);
\r
327 + if (do_print_progress) {
\r
328 + do_print_progress = 0;
\r
329 + generic_print_progress ("Cleaned up", "directories",
\r
331 + add_files_state.removed_directories->count);
\r
335 talloc_free (add_files_state.removed_files);
\r
336 @@ -854,22 +884,32 @@ notmuch_new_command (void *ctx, int argc, char *argv[])
\r
337 /* Now that removals are done (hence the database is aware of all
\r
338 * renames), we can synchronize maildir_flags to tags for all
\r
339 * messages that had new filenames appear on this run. */
\r
340 + gettimeofday (&tv_start, NULL);
\r
341 if (add_files_state.synchronize_flags) {
\r
342 _filename_node_t *node;
\r
343 notmuch_message_t *message;
\r
344 - for (node = add_files_state.message_ids_to_sync->head;
\r
345 + for (node = add_files_state.message_ids_to_sync->head, i = 0;
\r
347 - node = node->next)
\r
348 + node = node->next, i++)
\r
350 message = notmuch_database_find_message (notmuch, node->filename);
\r
351 notmuch_message_maildir_flags_to_tags (message);
\r
352 notmuch_message_destroy (message);
\r
353 + if (do_print_progress) {
\r
354 + do_print_progress = 0;
\r
355 + generic_print_progress (
\r
356 + "Synchronized tags for", "messages",
\r
357 + tv_start, i, add_files_state.message_ids_to_sync->count);
\r
362 talloc_free (add_files_state.message_ids_to_sync);
\r
363 add_files_state.message_ids_to_sync = NULL;
\r
365 + if (timer_is_active)
\r
366 + stop_progress_printing_timer ();
\r
368 gettimeofday (&tv_now, NULL);
\r
369 elapsed = notmuch_time_elapsed (add_files_state.tv_start,
\r
371 @@ -880,10 +920,10 @@ notmuch_new_command (void *ctx, int argc, char *argv[])
\r
372 "file" : "total files");
\r
373 notmuch_time_print_formatted_seconds (elapsed);
\r
375 - printf (" (%d files/sec.). \n",
\r
376 + printf (" (%d files/sec.).\033[K\n",
\r
377 (int) (add_files_state.processed_files / elapsed));
\r
380 + printf (".\033[K\n");
\r