bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2011-2018 Dovecot authors, see the included COPYING file */
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainen void (*listen_callback)(struct indexer_queue *);
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainen /* username+mailbox -> indexer_request */
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen HASH_TABLE(struct indexer_request *, struct indexer_request *) requests;
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainenstatic unsigned int
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainenindexer_request_hash(const struct indexer_request *request)
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainen return str_hash(request->username) ^ str_hash(request->mailbox);
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainenstatic int indexer_request_cmp(const struct indexer_request *r1,
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainen return strcmp(r1->username, r2->username) == 0 &&
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainen strcmp(r1->mailbox, r2->mailbox) == 0 ? 0 : 1;
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainenindexer_queue_init(indexer_status_callback_t *callback)
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainen hash_table_create(&queue->requests, default_pool, 0,
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainenvoid indexer_queue_deinit(struct indexer_queue **_queue)
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainenvoid indexer_queue_set_listen_callback(struct indexer_queue *queue,
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainenindexer_queue_lookup(struct indexer_queue *queue,
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainen return hash_table_lookup(queue->requests, &lookup_request);
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainenstatic void request_add_context(struct indexer_request *request, void *context)
7fb611afeb56b9647c57e3f56772b2a3ebf9541eTimo Sirainen array_append(&request->contexts, &context, 1);
294f579cd3803e2d9997231fdc46523c23774a8fTimo Sirainenindexer_queue_append_request(struct indexer_queue *queue, bool append,
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainen request = indexer_queue_lookup(queue, username, mailbox);
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainen hash_table_insert(queue->requests, request, request);
7c0e7d96e104a59df7b5aecdc0cbe4f6e304b7c7Timo Sirainen if (request->max_recent_msgs > max_recent_msgs)
218095792e0af7c1609da4901cfb60e78139595eTimo Sirainen /* we're already indexing this mailbox. */
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainen /* keep the request in its old position */
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainen /* move request to beginning of the queue */
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainen DLLIST2_REMOVE(&queue->head, &queue->tail, request);
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainen DLLIST2_APPEND(&queue->head, &queue->tail, request);
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainen DLLIST2_PREPEND(&queue->head, &queue->tail, request);
294f579cd3803e2d9997231fdc46523c23774a8fTimo Sirainenstatic void indexer_queue_append_finish(struct indexer_queue *queue)
294f579cd3803e2d9997231fdc46523c23774a8fTimo Sirainenvoid indexer_queue_append(struct indexer_queue *queue, bool append,
a8dcd4e2332c73087e9b148d34259230a77edb28Timo Sirainen const char *session_id, unsigned int max_recent_msgs,
294f579cd3803e2d9997231fdc46523c23774a8fTimo Sirainen request = indexer_queue_append_request(queue, append, username, mailbox,
294f579cd3803e2d9997231fdc46523c23774a8fTimo Sirainenvoid indexer_queue_append_optimize(struct indexer_queue *queue,
294f579cd3803e2d9997231fdc46523c23774a8fTimo Sirainen request = indexer_queue_append_request(queue, TRUE, username, mailbox,
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainenstruct indexer_request *indexer_queue_request_peek(struct indexer_queue *queue)
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainenvoid indexer_queue_request_remove(struct indexer_queue *queue)
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainen struct indexer_request *request = queue->head;
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainen DLLIST2_REMOVE(&queue->head, &queue->tail, request);
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainenstatic void indexer_queue_request_status_int(struct indexer_queue *queue,
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainen unsigned int i;
218095792e0af7c1609da4901cfb60e78139595eTimo Sirainen for (i = 0; i < request->working_context_idx; i++) {
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainenvoid indexer_queue_request_status(struct indexer_queue *queue,
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainen i_assert(percentage >= 0 && percentage < 100);
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainen indexer_queue_request_status_int(queue, request, percentage);
218095792e0af7c1609da4901cfb60e78139595eTimo Sirainenvoid indexer_queue_request_work(struct indexer_request *request)
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainenvoid indexer_queue_request_finish(struct indexer_queue *queue,
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainen indexer_queue_request_status_int(queue, request, success ? 100 : -1);
218095792e0af7c1609da4901cfb60e78139595eTimo Sirainen if (request->reindex_head || request->reindex_tail) {
218095792e0af7c1609da4901cfb60e78139595eTimo Sirainen DLLIST2_PREPEND(&queue->head, &queue->tail, request);
218095792e0af7c1609da4901cfb60e78139595eTimo Sirainen DLLIST2_APPEND(&queue->head, &queue->tail, request);
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainenvoid indexer_queue_cancel_all(struct indexer_queue *queue)
29ffe706625d0d592b05855fe4e99311c916701bTimo Sirainen /* remove all reindex-markers so when the current requests finish
29ffe706625d0d592b05855fe4e99311c916701bTimo Sirainen (or are cancelled) we don't try to retry them (especially during
29ffe706625d0d592b05855fe4e99311c916701bTimo Sirainen deinit where it crashes) */
29ffe706625d0d592b05855fe4e99311c916701bTimo Sirainen iter = hash_table_iterate_init(queue->requests);
29ffe706625d0d592b05855fe4e99311c916701bTimo Sirainen while (hash_table_iterate(iter, queue->requests, &request, &request))
29ffe706625d0d592b05855fe4e99311c916701bTimo Sirainen request->reindex_head = request->reindex_tail = FALSE;
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainen while ((request = indexer_queue_request_peek(queue)) != NULL) {
71e32f990a6b19e00238826e832ac8f8c939115fPhil Carmody indexer_queue_request_finish(queue, &request, FALSE);
d9e404180ff26dbbaea68534a5f176765022b76bTimo Sirainenbool indexer_queue_is_empty(struct indexer_queue *queue)
cfa8a04466cd46bdc422bd9eba8e6794758d677bTimo Sirainenunsigned int indexer_queue_count(struct indexer_queue *queue)