Пример #1
0
static void set_cache_decisions(struct mail_cache *cache,
				const char *set, const char *fields,
				enum mail_cache_decision_type dec)
{
	struct mail_cache_field field;
	const char *const *arr;
	unsigned int idx;

	if (fields == NULL || *fields == '\0')
		return;

	for (arr = t_strsplit_spaces(fields, " ,"); *arr != NULL; arr++) {
		const char *name = *arr;

		idx = mail_cache_register_lookup(cache, name);
		if (idx != UINT_MAX) {
			field = *mail_cache_register_get_field(cache, idx);
		} else if (strncasecmp(name, "hdr.", 4) == 0) {
			memset(&field, 0, sizeof(field));
			field.name = name;
			field.type = MAIL_CACHE_FIELD_HEADER;
		} else {
			i_error("%s: Unknown cache field name '%s', ignoring",
				set, *arr);
			continue;
		}

		field.decision = dec;
		mail_cache_register_fields(cache, &field, 1);
	}
}
Пример #2
0
static void index_cache_register_defaults(struct mailbox *box)
{
	struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(box);
	const struct mail_storage_settings *set = box->storage->set;
	struct mail_cache *cache = box->cache;

	ibox->cache_fields = i_malloc(sizeof(global_cache_fields));
	memcpy(ibox->cache_fields, global_cache_fields,
	       sizeof(global_cache_fields));
	mail_cache_register_fields(cache, ibox->cache_fields,
				   MAIL_INDEX_CACHE_FIELD_COUNT);

	if (strcmp(set->mail_never_cache_fields, "*") == 0) {
		/* all caching disabled for now */
		box->mail_cache_disabled = TRUE;
		return;
	}

	set_cache_decisions(cache, "mail_cache_fields",
			    set->mail_cache_fields,
			    MAIL_CACHE_DECISION_TEMP);
	set_cache_decisions(cache, "mail_always_cache_fields",
			    set->mail_always_cache_fields,
			    MAIL_CACHE_DECISION_YES |
			    MAIL_CACHE_DECISION_FORCED);
	set_cache_decisions(cache, "mail_never_cache_fields",
			    set->mail_never_cache_fields,
			    MAIL_CACHE_DECISION_NO |
			    MAIL_CACHE_DECISION_FORCED);
}
Пример #3
0
static struct mailbox_header_lookup_ctx *
mailbox_header_lookup_init_real(struct mailbox *box,
				const char *const headers[])
{
	struct mail_cache_field *fields, header_field = {
		.type = MAIL_CACHE_FIELD_HEADER,
		.decision = MAIL_CACHE_DECISION_TEMP
	};
	struct mailbox_header_lookup_ctx *ctx;
	const char *const *name;
	const char **sorted_headers, **dest_name;
	pool_t pool;
	unsigned int i, count;

	i_assert(*headers != NULL);

	for (count = 0, name = headers; *name != NULL; name++)
		count++;

	/* @UNSAFE: headers need to be sorted for filter stream. */
	sorted_headers = t_new(const char *, count);
	memcpy(sorted_headers, headers, count * sizeof(*sorted_headers));
	i_qsort(sorted_headers, count, sizeof(*sorted_headers), i_strcasecmp_p);
	headers = sorted_headers;

	/* @UNSAFE */
	fields = t_new(struct mail_cache_field, count);
	for (i = 0; i < count; i++) {
		header_field.name = t_strconcat("hdr.", headers[i], NULL);
		fields[i] = header_field;
	}
	mail_cache_register_fields(box->cache, fields, count);

	pool = pool_alloconly_create("mailbox_header_lookup_ctx", 1024);
	ctx = p_new(pool, struct mailbox_header_lookup_ctx, 1);
	ctx->box = box;
	ctx->refcount = 1;
	ctx->pool = pool;
	ctx->count = count;

	ctx->idx = p_new(pool, unsigned int, count);

	/* @UNSAFE */
	dest_name = p_new(pool, const char *, count + 1);
	for (i = 0; i < count; i++) {
		ctx->idx[i] = fields[i].idx;
		dest_name[i] = p_strdup(pool, headers[i]);
	}
	ctx->name = dest_name;
	return ctx;
}
static unsigned int
get_header_field_idx(struct mailbox *box, const char *field,
		     enum mail_cache_decision_type decision)
{
	struct mail_cache_field header_field;

	memset(&header_field, 0, sizeof(header_field));
	header_field.type = MAIL_CACHE_FIELD_HEADER;
	header_field.decision = decision;
	T_BEGIN {
		header_field.name = t_strconcat("hdr.", field, NULL);
		mail_cache_register_fields(box->cache, &header_field, 1);
	} T_END;
	return header_field.idx;
}
Пример #5
0
static void
index_storage_mailbox_update_cache(struct mailbox *box,
				   const struct mailbox_update *update)
{
	const struct mailbox_cache_field *updates = update->cache_updates;
	ARRAY(struct mail_cache_field) new_fields;
	const struct mail_cache_field *old_fields;
	struct mail_cache_field field;
	unsigned int i, j, old_count;

	old_fields = mail_cache_register_get_list(box->cache,
						  pool_datastack_create(),
						  &old_count);

	/* There shouldn't be many fields, so don't worry about O(n^2). */
	t_array_init(&new_fields, 32);
	for (i = 0; updates[i].name != NULL; i++) {
		/* see if it's an existing field */
		for (j = 0; j < old_count; j++) {
			if (strcmp(updates[i].name, old_fields[j].name) == 0)
				break;
		}
		if (j != old_count) {
			field = old_fields[j];
		} else if (strncmp(updates[i].name, "hdr.", 4) == 0) {
			/* new header */
			memset(&field, 0, sizeof(field));
			field.name = updates[i].name;
			field.type = MAIL_CACHE_FIELD_HEADER;
		} else {
			/* new unknown field. we can't do anything about
			   this since we don't know its type */
			continue;
		}
		field.decision = updates[i].decision;
		if (updates[i].last_used != (time_t)-1)
			field.last_used = updates[i].last_used;
		array_append(&new_fields, &field, 1);
	}
	if (array_count(&new_fields) > 0) {
		mail_cache_register_fields(box->cache,
					   array_idx_modifiable(&new_fields, 0),
					   array_count(&new_fields));
	}
}