Re: [PATCH] emacs: wash: make word-wrap bound message width
[notmuch-archives.git] / 77 / 37fdd907051b90f6515fe7713319bd4768ace4
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
8 X-Spam-Flag: NO\r
9 X-Spam-Score: 0\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none]\r
12         autolearn=disabled\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
43 Precedence: list\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
54 \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
60 them.\r
61 \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
66 their progress.\r
67 ---\r
68  notmuch-new.c |  156 ++++++++++++++++++++++++++++++++++++---------------------\r
69  1 files changed, 98 insertions(+), 58 deletions(-)\r
70 \r
71 diff --git a/notmuch-new.c b/notmuch-new.c\r
72 index d71e497..fa7a76d 100644\r
73 --- a/notmuch-new.c\r
74 +++ b/notmuch-new.c\r
75 @@ -28,6 +28,7 @@ typedef struct _filename_node {\r
76  } _filename_node_t;\r
77  \r
78  typedef struct _filename_list {\r
79 +    unsigned count;\r
80      _filename_node_t *head;\r
81      _filename_node_t **tail;\r
82  } _filename_list_t;\r
83 @@ -50,12 +51,12 @@ typedef struct {\r
84      _filename_list_t *message_ids_to_sync;\r
85  } add_files_state_t;\r
86  \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
89  \r
90  static void\r
91  handle_sigalrm (unused (int signal))\r
92  {\r
93 -    do_add_files_print_progress = 1;\r
94 +    do_print_progress = 1;\r
95  }\r
96  \r
97  static volatile sig_atomic_t interrupted;\r
98 @@ -81,6 +82,7 @@ _filename_list_create (const void *ctx)\r
99  \r
100      list->head = NULL;\r
101      list->tail = &list->head;\r
102 +    list->count = 0;\r
103  \r
104      return list;\r
105  }\r
106 @@ -91,6 +93,8 @@ _filename_list_add (_filename_list_t *list,\r
107  {\r
108      _filename_node_t *node = talloc (list, _filename_node_t);\r
109  \r
110 +    list->count++;\r
111 +\r
112      node->filename = talloc_strdup (list, filename);\r
113      node->next = NULL;\r
114  \r
115 @@ -99,28 +103,28 @@ _filename_list_add (_filename_list_t *list,\r
116  }\r
117  \r
118  static void\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
122  {\r
123      struct timeval tv_now;\r
124      double elapsed_overall, rate_overall;\r
125  \r
126      gettimeofday (&tv_now, NULL);\r
127  \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
132  \r
133 -    printf ("Processed %d", state->processed_files);\r
134 +    printf ("%s %d ", action, processed);\r
135  \r
136 -    if (state->total_files) {\r
137 +    if (total) {\r
138         double time_remaining;\r
139  \r
140 -       time_remaining = ((state->total_files - state->processed_files) /\r
141 -                         rate_overall);\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
148      } else {\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
151      }\r
152  \r
153      fflush (stdout);\r
154 @@ -479,9 +483,10 @@ add_files_recursive (notmuch_database_t *notmuch,\r
155             message = NULL;\r
156         }\r
157  \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
165         }\r
166  \r
167         talloc_free (next);\r
168 @@ -540,38 +545,56 @@ add_files_recursive (notmuch_database_t *notmuch,\r
169      return ret;\r
170  }\r
171  \r
172 +static void\r
173 +setup_progress_printing_timer (void)\r
174 +{\r
175 +    struct sigaction action;\r
176 +    struct itimerval timerval;\r
177 +\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
184 +\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
191 +}\r
192 +\r
193 +static void\r
194 +stop_progress_printing_timer (void)\r
195 +{\r
196 +    struct sigaction action;\r
197 +    struct itimerval timerval;\r
198 +\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
205 +\r
206 +    /* And disable the signal handler. */\r
207 +    action.sa_handler = SIG_IGN;\r
208 +    sigaction (SIGALRM, &action, NULL);\r
209 +}\r
210 +\r
211 +\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
218            const char *path,\r
219            add_files_state_t *state)\r
220  {\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
225      struct stat st;\r
226  \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
234 -\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
241 -\r
242 -       timer_is_active = TRUE;\r
243 -    }\r
244 -\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
249  \r
250      status = add_files_recursive (notmuch, path, state);\r
251  \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
259 -\r
260 -       /* And disable the signal handler. */\r
261 -       action.sa_handler = SIG_IGN;\r
262 -       sigaction (SIGALRM, &action, NULL);\r
263 -    }\r
264 -\r
265      return status;\r
266  }\r
267  \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
271      double elapsed;\r
272 -    struct timeval tv_now;\r
273 +    struct timeval tv_now, tv_start;\r
274      int ret = 0;\r
275      struct stat st;\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
280      int i;\r
281 +    notmuch_bool_t timer_is_active = FALSE;\r
282  \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
286             return 1;\r
287         }\r
288      }\r
289 -\r
290      config = notmuch_config_open (ctx, NULL, NULL);\r
291      if (config == NULL)\r
292         return 1;\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
296  \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
301 +    }\r
302 +\r
303      ret = add_files (notmuch, db_path, &add_files_state);\r
304  \r
305      removed_files = 0;\r
306      renamed_files = 0;\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
311             renamed_files++;\r
312         else\r
313             removed_files++;\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
319 +       }\r
320      }\r
321  \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
330 +               tv_start, i,\r
331 +               add_files_state.removed_directories->count);\r
332 +       }\r
333      }\r
334  \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
346              node;\r
347 -            node = node->next)\r
348 +            node = node->next, i++)\r
349         {\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
358 +           }\r
359         }\r
360      }\r
361  \r
362      talloc_free (add_files_state.message_ids_to_sync);\r
363      add_files_state.message_ids_to_sync = NULL;\r
364  \r
365 +    if (timer_is_active)\r
366 +       stop_progress_printing_timer ();\r
367 +\r
368      gettimeofday (&tv_now, NULL);\r
369      elapsed = notmuch_time_elapsed (add_files_state.tv_start,\r
370                                     tv_now);\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
374         if (elapsed > 1) {\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
378         } else {\r
379 -           printf (".                    \n");\r
380 +           printf (".\033[K\n");\r
381         }\r
382      }\r
383  \r
384 -- \r
385 1.7.2.3\r
386 \r