This way, the user gets a steady (but bursty) stream of reults. We
double the chunk size each time since each successive chunk has to
redo work from all previous chunks.
Of course, the overall time is thereby slower, as the price we pay for
increased responsiveness. With a search returning about 17000 thread
results I measured a total time of 48.8 seconds before this change and
58.4 seconds afterwards.
(tag-name, search-specification). The database is responsible for
ensuring that the virtual tag is always consistent.
(tag-name, search-specification). The database is responsible for
ensuring that the virtual tag is always consistent.
+Think about optimizing chunked searches (max-threads > 0) to avoid
+repeating work. That would be saving state from the previous chunk and
+reusing it if the next search is the next chunk with the same search
+string.
+
General
-------
Audit everything for dealing with out-of-memory (and drop xutil.c).
General
-------
Audit everything for dealing with out-of-memory (and drop xutil.c).
#include "notmuch-client.h"
#include "notmuch-client.h"
-/* If the user asks for a *lot* of threads, lets give some results as
- * quickly as possible and let the user read those while we compute
- * the remainder. */
-#define NOTMUCH_SHOW_INITIAL_BURST 100
-
-static void
+/* If the user asks for more than this number of threads, then break
+ the results down into chunks so that results start appearing
+ quickly rather than the user having to wait until all results are
+ available before anything appears.
+
+ Since each subsequent chunk ends up having to re-do threading work
+ done by all previous chunks, we double the chunk size repeatedly
+ until all desired results have been returned.
+*/
+#define NOTMUCH_SEARCH_INITIAL_CHUNK_SIZE 100
+
+/* Do the actual search for a chunk of threads and display the results,
+ (returning the number of threads found in this chunk). */
+static int
do_search_threads (const void *ctx,
notmuch_query_t *query,
notmuch_sort_t sort,
do_search_threads (const void *ctx,
notmuch_query_t *query,
notmuch_sort_t sort,
notmuch_tags_t *tags;
time_t date;
const char *relative_date;
notmuch_tags_t *tags;
time_t date;
const char *relative_date;
for (threads = notmuch_query_search_threads (query, first, max_threads);
notmuch_threads_has_more (threads);
for (threads = notmuch_query_search_threads (query, first, max_threads);
notmuch_threads_has_more (threads);
int first_tag = 1;
thread = notmuch_threads_get (threads);
int first_tag = 1;
thread = notmuch_threads_get (threads);
if (sort == NOTMUCH_SORT_OLDEST_FIRST)
date = notmuch_thread_get_oldest_date (thread);
if (sort == NOTMUCH_SORT_OLDEST_FIRST)
date = notmuch_thread_get_oldest_date (thread);
notmuch_thread_destroy (thread);
}
notmuch_thread_destroy (thread);
}
int i, first = 0, max_threads = -1;
char *opt, *end;
notmuch_sort_t sort = NOTMUCH_SORT_NEWEST_FIRST;
int i, first = 0, max_threads = -1;
char *opt, *end;
notmuch_sort_t sort = NOTMUCH_SORT_NEWEST_FIRST;
+ int chunk_size;
+ int threads_in_chunk;
for (i = 0; i < argc && argv[i][0] == '-'; i++) {
if (strcmp (argv[i], "--") == 0) {
for (i = 0; i < argc && argv[i][0] == '-'; i++) {
if (strcmp (argv[i], "--") == 0) {
notmuch_query_set_sort (query, sort);
notmuch_query_set_sort (query, sort);
- if (max_threads < 0 || max_threads > NOTMUCH_SHOW_INITIAL_BURST)
- {
- do_search_threads (ctx, query, sort,
- first, NOTMUCH_SHOW_INITIAL_BURST);
+ /* If we receive a max-threads option, then the user is
+ responsible for any chunking and we return all results at
+ once. */
+ if (max_threads < 0)
+ chunk_size = NOTMUCH_SEARCH_INITIAL_CHUNK_SIZE;
+ else
+ chunk_size = max_threads;
+
+ do {
+ threads_in_chunk = do_search_threads (ctx, query, sort,
+ first, chunk_size);
+ if (chunk_size == max_threads)
+ break;
- first += NOTMUCH_SHOW_INITIAL_BURST;
- if (max_threads > 0)
- max_threads -= NOTMUCH_SHOW_INITIAL_BURST;
- }
+ first += chunk_size;
+
+ chunk_size *= 2;
- do_search_threads (ctx, query, sort, first, max_threads);
+ } while (threads_in_chunk);
notmuch_query_destroy (query);
notmuch_database_close (notmuch);
notmuch_query_destroy (query);
notmuch_database_close (notmuch);