File: search_query.h

package info (click to toggle)
cyrus-imapd 3.6.1-4%2Bdeb12u3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 80,688 kB
  • sloc: ansic: 255,928; perl: 97,730; javascript: 9,266; sh: 5,537; yacc: 2,651; cpp: 2,128; makefile: 2,099; lex: 660; xml: 621; python: 388; awk: 303; asm: 262
file content (206 lines) | stat: -rw-r--r-- 7,656 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
/* search_query.h -- search query routines
 *
 * Copyright (c) 1994-2018 Carnegie Mellon University.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The name "Carnegie Mellon University" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For permission or any legal
 *    details, please contact
 *      Carnegie Mellon University
 *      Center for Technology Transfer and Enterprise Creation
 *      4615 Forbes Avenue
 *      Suite 302
 *      Pittsburgh, PA  15213
 *      (412) 268-7393, fax: (412) 268-7395
 *      innovation@andrew.cmu.edu
 *
 * 4. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by Computing Services
 *     at Carnegie Mellon University (http://www.cmu.edu/computing/)."
 *
 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef __CYRUS_SEARCH_RESULT_H__
#define __CYRUS_SEARCH_RESULT_H__

#include "mailbox.h"
#include "message.h"
#include "conversations.h"
#include "util.h"
#include "bitvector.h"
#include "ptrarray.h"
#include "dynarray.h"
#include "search_engines.h"

struct sortcrit;            /* imapd.h */
struct searchargs;          /* imapd.h */
typedef struct search_subquery search_subquery_t;
typedef struct search_query search_query_t;
typedef struct search_folder search_folder_t;

struct search_folder_partnum {
    uint32_t uid;
    uint32_t partnum;
};

struct search_folder {
    char *mboxname;
    uint32_t uidvalidity;
    uint64_t highest_modseq; /* of returned messages, not the folder */
    uint64_t first_modseq; /* of returned messages, not the folder */
    uint64_t last_modseq; /* of returned messages, not the folder */
    int id;
    bitvector_t uids;
    bitvector_t found_uids;
    int found_dirty;
    dynarray_t partnums; /* list of struct search_folder_partnum */
};

struct search_subquery {
    char *mboxname;             /* may be NULL */
    search_expr_t *indexed;     /* may be NULL */
    search_expr_t *expr;
};

struct search_saved_msgdata {
    /* Used to remember MsgData** arrays returned by
     * index_msgdata_load() for later freeing. */
    struct msgdata **msgdata;
    int n;
};

struct search_query {

    /*
     * A query may report results from multiple folders, but we need
     * this one specific folder to tell us the username to limit the
     * search engine scope.  Also, for most IMAP search commands we
     * start with a selected folder anyway so we need to avoid
     * double-opening it.
     */
    struct index_state *state;

    int (*checkfolder)(const char *mboxname, void *rock);
    void *checkfolderrock;
    /*
     * Input parameters of the query.  Set these after
     * search_query_new() and before search_query_run().
     */
    struct searchargs *searchargs;
    const struct sortcrit *sortcrit;
    int multiple;
    int need_ids;
    int need_expunge;
    int want_expunged;
    uint32_t want_mbtype;
    int verbose;
    int ignore_timer;
    int attachments_in_any;
    int want_partids;

    /*
     * A query comprises multiple sub-queries logically ORed together.
     * The sub-queries are organised by the first of three criteria
     * which might apply:
     *
     *  - subs_by_indexed: one or more indexed match nodes (need to scan
     *  all messages reported by a given search engine lookup)
     *
     *  - subs_by_folder: a single positive folder match node (need to
     *  scan all messages in a given folder)
     *
     *  - global_sub: neither indexed nor folder (need to scan all
     *  messages in many folders)
     */
    hash_table subs_by_indexed;
    unsigned int indexed_count;
    hash_table subs_by_folder;
    unsigned int folder_count;
    search_subquery_t global_sub;

    /* Used as a temporary holder for errors, e.g. to pass an error from
     * a hashtable enumeration callback back up to the caller */
    int error;
    /*
     * Resulting messages from a search engine query or a folder scan
     * need to be organised per-folder both for the secondary scan
     * (which needs to proceed per-folder to minimise the number of
     * index_open() calls) and for reporting back to the IMAP client.
     */
    hash_table folders_by_name;
    /*
     * Some callers need a unique and contiguous 0-based set of integer
     * ids for folders which have any results.  Note that the
     * folders_by_name hash table may contain folders with no results in
     * them, e.g. when the search engine returns hits for a folder which
     * all subsequently prove to be deleted.
     */
    ptrarray_t folders_by_id;
    /*
     * Array of search_saved_msgdata objects for later freeing
     */
    ptrarray_t saved_msgdata;
    /*
     * When sorting in requested, this array contains the final merged
     * sort results as an array of MsgData*.  The MsgData objects might
     * be "fake" ones if the results were retrieved from the cache DB,
     * but the following fields are guaranteed to be usable: uid, cid,
     * folder, guid.
     */
    ptrarray_t merged_msgdata;

    /* A map from string message part ids to a unique numeric
     * identifier. This allows to save good chunk of string mallocs */
    hashu64_table partid_by_num;
    hash_table partnum_by_id;
    uint32_t partnum_seq;

};

extern search_query_t *search_query_new(struct index_state *state,
                                        struct searchargs *);
extern int search_query_run(search_query_t *query);
extern void search_query_free(search_query_t *query);

extern search_folder_t *search_query_find_folder(search_query_t *query,
                                                 const char *mboxname);
extern void search_folder_use_msn(search_folder_t *, struct index_state *);
extern seqset_t *search_folder_get_seqset(const search_folder_t *);
extern int search_folder_get_array(const search_folder_t *, unsigned int **);
extern uint32_t search_folder_get_min(const search_folder_t *);
extern uint32_t search_folder_get_max(const search_folder_t *);
extern unsigned int search_folder_get_count(const search_folder_t *);
#define search_folder_foreach(folder, u) \
    for ((u) = bv_next_set(&(folder)->uids, 0) ; \
         (u) != -1 ; \
         (u) = bv_next_set(&(folder)->uids, (u)+1))
extern uint64_t search_folder_get_highest_modseq(const search_folder_t *);
extern uint64_t search_folder_get_first_modseq(const search_folder_t *);
extern uint64_t search_folder_get_last_modseq(const search_folder_t *);

extern void search_build_query(search_builder_t *bx, search_expr_t *e);

extern int search_is_mutable(struct sortcrit *sortcrit, search_expr_t *e);


#endif /* __CYRUS_SEARCH_RESULT_H__ */