bool index_mailbox_is_recent(struct mailbox *box, uint32_t uid) { struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(box); return array_is_created(&ibox->recent_flags) && seq_range_exists(&ibox->recent_flags, uid); }
static void search_seqset_arg(struct mail_search_arg *arg, struct index_search_context *ctx) { if (arg->type == SEARCH_SEQSET) { if (seq_range_exists(&arg->value.seqset, ctx->mail_ctx.seq)) ARG_SET_RESULT(arg, 1); else ARG_SET_RESULT(arg, 0); } }
static void test_seq_range_array_invert(void) { static const unsigned int input_min = 1, input_max = 5; static const unsigned int input[] = { 1, 2, 3, 4, 5, UINT_MAX, 2, 3, 4, UINT_MAX, 1, 2, 4, 5, UINT_MAX, 1, 3, 5, UINT_MAX, 1, UINT_MAX, 5, UINT_MAX, UINT_MAX }; ARRAY_TYPE(seq_range) range = ARRAY_INIT; unsigned int i, j, seq, start, num; bool old_exists, success; for (i = num = 0; input[i] != UINT_MAX; num++, i++) { success = TRUE; start = i; for (; input[i] != UINT_MAX; i++) { seq_range_array_add_with_init(&range, 32, input[i]); for (j = start; j < i; j++) { if (!seq_range_exists(&range, input[j])) success = FALSE; } } seq_range_array_invert(&range, input_min, input_max); for (seq = input_min; seq <= input_max; seq++) { for (j = start; input[j] != UINT_MAX; j++) { if (input[j] == seq) break; } old_exists = input[j] != UINT_MAX; if (seq_range_exists(&range, seq) == old_exists) success = FALSE; } test_out(t_strdup_printf("seq_range_array_invert(%u)", num), success); array_free(&range); } }
void mailbox_search_result_add(struct mail_search_result *result, uint32_t uid) { i_assert(uid > 0); if (seq_range_exists(&result->uids, uid)) return; seq_range_array_add(&result->uids, uid); if (array_is_created(&result->added_uids)) { seq_range_array_add(&result->added_uids, uid); seq_range_array_remove(&result->removed_uids, uid); } }
static void fts_search_apply_results_level(struct mail_search_context *ctx, struct mail_search_arg *args, unsigned int *idx) { struct fts_search_context *fctx = FTS_CONTEXT(ctx); const struct fts_search_level *level; level = array_idx(&fctx->levels, *idx); if (array_is_created(&level->definite_seqs) && seq_range_exists(&level->definite_seqs, ctx->seq)) fts_search_deserialize_add_matches(args, level->args_matches); else if (!array_is_created(&level->maybe_seqs) || !seq_range_exists(&level->maybe_seqs, ctx->seq)) fts_search_deserialize_add_nonmatches(args, level->args_matches); for (; args != NULL; args = args->next) { if (args->type != SEARCH_OR && args->type != SEARCH_SUB) continue; *idx += 1; fts_search_apply_results_level(ctx, args->value.subargs, idx); } }
void index_mailbox_set_recent_uid(struct mailbox *box, uint32_t uid) { struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(box); if (uid <= ibox->recent_flags_prev_uid) { if (seq_range_exists(&ibox->recent_flags, uid)) return; mail_storage_set_critical(box->storage, "Recent flags state corrupted for mailbox %s", box->vname); array_clear(&ibox->recent_flags); ibox->recent_flags_count = 0; } ibox->recent_flags_prev_uid = uid; seq_range_array_add_with_init(&ibox->recent_flags, 64, uid); ibox->recent_flags_count++; }
/* Returns >0 = matched, 0 = not matched, -1 = unknown */ static int search_arg_match_index(struct index_search_context *ctx, struct mail_search_arg *arg, const struct mail_index_record *rec) { enum mail_flags flags; uint64_t modseq; int ret; switch (arg->type) { case SEARCH_UIDSET: case SEARCH_INTHREAD: return seq_range_exists(&arg->value.seqset, rec->uid); case SEARCH_FLAGS: /* recent flag shouldn't be set, but indexes from v1.0.x may contain it. */ flags = rec->flags & ~MAIL_RECENT; if ((arg->value.flags & MAIL_RECENT) != 0 && index_mailbox_is_recent(ctx->box, rec->uid)) flags |= MAIL_RECENT; return (flags & arg->value.flags) == arg->value.flags; case SEARCH_KEYWORDS: T_BEGIN { ret = search_arg_match_keywords(ctx, arg); } T_END; return ret; case SEARCH_MODSEQ: { if (arg->value.flags != 0) { modseq = mail_index_modseq_lookup_flags(ctx->view, arg->value.flags, ctx->mail_ctx.seq); } else if (arg->value.keywords != NULL) { modseq = mail_index_modseq_lookup_keywords(ctx->view, arg->value.keywords, ctx->mail_ctx.seq); } else { modseq = mail_index_modseq_lookup(ctx->view, ctx->mail_ctx.seq); } return modseq >= arg->value.modseq->modseq; } default: return -1; } }