Example #1
0
static void
dbox_sync_index_copy_from_old(struct dbox_sync_rebuild_context *ctx,
			      struct mail_index_view *view,
			      uint32_t old_seq, uint32_t new_seq)
{
	struct mail_index *index = mail_index_view_get_index(view);
	const struct mail_index_record *rec;
	ARRAY_TYPE(keyword_indexes) old_keywords;
	struct mail_keywords *kw;
	uint64_t modseq;

	/* copy flags */
	rec = mail_index_lookup(view, old_seq);
	mail_index_update_flags(ctx->trans, new_seq,
				MODIFY_REPLACE, rec->flags);

	/* copy keywords */
	t_array_init(&old_keywords, 32);
	mail_index_lookup_keywords(view, old_seq, &old_keywords);
	kw = mail_index_keywords_create_from_indexes(index, &old_keywords);
	mail_index_update_keywords(ctx->trans, new_seq, MODIFY_REPLACE, kw);
	mail_index_keywords_unref(&kw);

	/* copy modseq */
	modseq = mail_index_modseq_lookup(view, old_seq);
	mail_index_update_modseq(ctx->trans, new_seq, modseq);

	dbox_sync_index_copy_cache(ctx, view, old_seq, new_seq);
}
Example #2
0
const ARRAY_TYPE(keyword_indexes) *
index_mail_get_keyword_indexes(struct mail *_mail)
{
	struct index_mail *mail = (struct index_mail *)_mail;
	struct index_mail_data *data = &mail->data;

	if (!array_is_created(&data->keyword_indexes)) {
		p_array_init(&data->keyword_indexes, mail->data_pool, 32);
		mail_index_lookup_keywords(_mail->transaction->view,
					   mail->data.seq,
					   &data->keyword_indexes);
	}
	return &data->keyword_indexes;
}
Example #3
0
static int search_arg_match_keywords(struct index_search_context *ctx,
				     struct mail_search_arg *arg)
{
	ARRAY_TYPE(keyword_indexes) keyword_indexes_arr;
	const struct mail_keywords *search_kws = arg->value.keywords;
	const unsigned int *keyword_indexes;
	unsigned int i, j, count;

	t_array_init(&keyword_indexes_arr, 128);
	mail_index_lookup_keywords(ctx->view, ctx->mail_ctx.seq,
				   &keyword_indexes_arr);
	keyword_indexes = array_get(&keyword_indexes_arr, &count);

	/* there probably aren't many keywords, so O(n*m) for now */
	for (i = 0; i < search_kws->count; i++) {
		for (j = 0; j < count; j++) {
			if (search_kws->idx[i] == keyword_indexes[j])
				break;
		}
		if (j == count)
			return 0;
	}
	return 1;
}
Example #4
0
static void
maildir_sync_mail_keywords(struct maildir_index_sync_context *ctx, uint32_t seq)
{
	struct mailbox *box = &ctx->mbox->box;
	struct mail_keywords *kw;
	unsigned int i, j, old_count, new_count;
	const unsigned int *old_indexes, *new_indexes;
	bool have_indexonly_keywords;
	int diff;

	mail_index_lookup_keywords(ctx->view, seq, &ctx->idx_keywords);
	if (index_keyword_array_cmp(&ctx->keywords, &ctx->idx_keywords)) {
		/* no changes - we should get here usually */
		return;
	}

	/* sort the keywords */
	array_sort(&ctx->idx_keywords, uint_cmp);
	array_sort(&ctx->keywords, uint_cmp);

	/* drop keywords that are in index-only. we don't want to touch them. */
	old_indexes = array_get(&ctx->idx_keywords, &old_count);
	have_indexonly_keywords = FALSE;
	for (i = old_count; i > 0; i--) {
		if (maildir_keywords_idx_char(ctx->keywords_sync_ctx,
					      old_indexes[i-1]) == '\0') {
			have_indexonly_keywords = TRUE;
			array_delete(&ctx->idx_keywords, i-1, 1);
		}
	}

	if (!have_indexonly_keywords) {
		/* no index-only keywords found, so something changed.
		   just replace them all. */
		kw = mail_index_keywords_create_from_indexes(box->index,
							     &ctx->keywords);
		mail_index_update_keywords(ctx->trans, seq, MODIFY_REPLACE, kw);
		mail_index_keywords_unref(&kw);
		return;
	}

	/* check again if non-index-only keywords changed */
	if (index_keyword_array_cmp(&ctx->keywords, &ctx->idx_keywords))
		return;

	/* we can't reset all the keywords or we'd drop indexonly keywords too.
	   so first remove the unwanted keywords and then add back the wanted
	   ones. we can get these lists easily by removing common elements
	   from old and new keywords. */
	new_indexes = array_get(&ctx->keywords, &new_count);
	for (i = j = 0; i < old_count && j < new_count; ) {
		diff = (int)old_indexes[i] - (int)new_indexes[j];
		if (diff == 0) {
			array_delete(&ctx->keywords, j, 1);
			array_delete(&ctx->idx_keywords, i, 1);
			old_indexes = array_get(&ctx->idx_keywords, &old_count);
			new_indexes = array_get(&ctx->keywords, &new_count);
		} else if (diff < 0) {
			i++;
		} else {
			j++;
		}
	}

	if (array_count(&ctx->idx_keywords) > 0) {
		kw = mail_index_keywords_create_from_indexes(box->index,
							     &ctx->idx_keywords);
		mail_index_update_keywords(ctx->trans, seq, MODIFY_REMOVE, kw);
		mail_index_keywords_unref(&kw);
	}

	if (array_count(&ctx->keywords) > 0) {
		kw = mail_index_keywords_create_from_indexes(box->index,
							     &ctx->keywords);
		mail_index_update_keywords(ctx->trans, seq, MODIFY_ADD, kw);
		mail_index_keywords_unref(&kw);
	}
}