<commit_before>/* Copyright (c) 2007-2010 Dovecot authors, see the included COPYING file */

#include "lib.h"
#include "array.h"
#include "mail-index-modseq.h"
#include "index-storage.h"
#include "dbox-storage.h"
#include "dbox-sync-rebuild.h"

static void
dbox_sync_index_copy_cache(struct dbox_sync_rebuild_context *ctx,
			   struct mail_index_view *view,
			   uint32_t old_seq, uint32_t new_seq)
{
	struct mail_index_map *map;
	const void *data;
	uint32_t reset_id;
	bool expunged;

	if (ctx->cache_ext_id == (uint32_t)-1)
		return;

	mail_index_lookup_ext_full(view, old_seq, ctx->cache_ext_id,
				   &map, &data, &expunged);
	if (expunged)
		return;

	if (!mail_index_ext_get_reset_id(view, map, ctx->cache_ext_id,
					 &reset_id) || reset_id == 0)
		return;

	if (!ctx->cache_used) {
		/* set reset id */
		ctx->cache_used = TRUE;
		ctx->cache_reset_id = reset_id;
		mail_index_ext_reset(ctx->trans, ctx->cache_ext_id,
				     ctx->cache_reset_id, TRUE);
	}
	if (ctx->cache_reset_id == reset_id) {
		mail_index_update_ext(ctx->trans, new_seq,
				      ctx->cache_ext_id, data, NULL);
	}
}

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);
}

void dbox_sync_rebuild_index_metadata(struct dbox_sync_rebuild_context *ctx,
				      uint32_t new_seq, uint32_t uid)
{
	uint32_t old_seq;

	if (mail_index_lookup_seq(ctx->view, uid, &old_seq)) {
		/* the message exists in the old index.
		   copy the metadata from it. */
		dbox_sync_index_copy_from_old(ctx, ctx->view, old_seq, new_seq);
	} else if (ctx->backup_view != NULL &&
		   mail_index_lookup_seq(ctx->backup_view, uid, &old_seq)) {
		/* copy the metadata from backup index. */
		dbox_sync_index_copy_from_old(ctx, ctx->backup_view,
					      old_seq, new_seq);
	}
}

static void dbox_sync_rebuild_header(struct dbox_sync_rebuild_context *ctx)
{
	const struct mail_index_header *hdr, *backup_hdr;
	struct mail_index *index = mail_index_view_get_index(ctx->view);
	struct mail_index_modseq_header modseq_hdr;
	uint32_t uid_validity, next_uid;
	uint64_t modseq;

	hdr = mail_index_get_header(ctx->view);
	backup_hdr = ctx->backup_view == NULL ? NULL :
		mail_index_get_header(ctx->backup_view);

	/* set uidvalidity */
	if (hdr->uid_validity != 0)
		uid_validity = hdr->uid_validity;
	else if (backup_hdr != NULL && backup_hdr->uid_validity != 0)
		uid_validity = backup_hdr->uid_validity;
	else
		uid_validity = dbox_get_uidvalidity_next(ctx->box->list);
	mail_index_update_header(ctx->trans,
		offsetof(struct mail_index_header, uid_validity),
		&uid_validity, sizeof(uid_validity), TRUE);

	/* set next-uid */
	if (hdr->next_uid != 0)
		next_uid = hdr->next_uid;
	else if (backup_hdr != NULL && backup_hdr->next_uid != 0)
		next_uid = backup_hdr->next_uid;
	else
		next_uid = dbox_get_uidvalidity_next(ctx->box->list);
	mail_index_update_header(ctx->trans,
				 offsetof(struct mail_index_header, next_uid),
				 &next_uid, sizeof(next_uid), FALSE);

	/* set highest-modseq */
	memset(&modseq_hdr, 0, sizeof(modseq_hdr));
	modseq_hdr.highest_modseq = mail_index_modseq_get_highest(ctx->view);
	if (ctx->backup_view != NULL) {
		modseq = mail_index_modseq_get_highest(ctx->backup_view);
		if (modseq_hdr.highest_modseq < modseq)
			modseq_hdr.highest_modseq = modseq;
	}
	mail_index_update_header_ext(ctx->trans, index->modseq_ext_id,
				     0, &modseq_hdr, sizeof(modseq_hdr));
}

struct dbox_sync_rebuild_context *
dbox_sync_index_rebuild_init(struct mailbox *box,
			     struct mail_index_view *view,
			     struct mail_index_transaction *trans)
{<commit_msg>dbox: When rebuilding index, don't try to shrink next_uid.<commit_after>/* Copyright (c) 2007-2010 Dovecot authors, see the included COPYING file */

#include "lib.h"
#include "array.h"
#include "mail-index-modseq.h"
#include "index-storage.h"
#include "dbox-storage.h"
#include "dbox-sync-rebuild.h"

static void
dbox_sync_index_copy_cache(struct dbox_sync_rebuild_context *ctx,
			   struct mail_index_view *view,
			   uint32_t old_seq, uint32_t new_seq)
{
	struct mail_index_map *map;
	const void *data;
	uint32_t reset_id;
	bool expunged;

	if (ctx->cache_ext_id == (uint32_t)-1)
		return;

	mail_index_lookup_ext_full(view, old_seq, ctx->cache_ext_id,
				   &map, &data, &expunged);
	if (expunged)
		return;

	if (!mail_index_ext_get_reset_id(view, map, ctx->cache_ext_id,
					 &reset_id) || reset_id == 0)
		return;

	if (!ctx->cache_used) {
		/* set reset id */
		ctx->cache_used = TRUE;
		ctx->cache_reset_id = reset_id;
		mail_index_ext_reset(ctx->trans, ctx->cache_ext_id,
				     ctx->cache_reset_id, TRUE);
	}
	if (ctx->cache_reset_id == reset_id) {
		mail_index_update_ext(ctx->trans, new_seq,
				      ctx->cache_ext_id, data, NULL);
	}
}

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);
}

void dbox_sync_rebuild_index_metadata(struct dbox_sync_rebuild_context *ctx,
				      uint32_t new_seq, uint32_t uid)
{
	uint32_t old_seq;

	if (mail_index_lookup_seq(ctx->view, uid, &old_seq)) {
		/* the message exists in the old index.
		   copy the metadata from it. */
		dbox_sync_index_copy_from_old(ctx, ctx->view, old_seq, new_seq);
	} else if (ctx->backup_view != NULL &&
		   mail_index_lookup_seq(ctx->backup_view, uid, &old_seq)) {
		/* copy the metadata from backup index. */
		dbox_sync_index_copy_from_old(ctx, ctx->backup_view,
					      old_seq, new_seq);
	}
}

static void dbox_sync_rebuild_header(struct dbox_sync_rebuild_context *ctx)
{
	const struct mail_index_header *hdr, *backup_hdr, *trans_hdr;
	struct mail_index *index = mail_index_view_get_index(ctx->view);
	struct mail_index_modseq_header modseq_hdr;
	struct mail_index_view *trans_view;
	uint32_t uid_validity, next_uid;
	uint64_t modseq;

	hdr = mail_index_get_header(ctx->view);
	backup_hdr = ctx->backup_view == NULL ? NULL :
		mail_index_get_header(ctx->backup_view);
	trans_view = mail_index_transaction_open_updated_view(ctx->trans);
	trans_hdr = mail_index_get_header(trans_view);

	/* set uidvalidity */
	if (hdr->uid_validity != 0)
		uid_validity = hdr->uid_validity;
	else if (backup_hdr != NULL && backup_hdr->uid_validity != 0)
		uid_validity = backup_hdr->uid_validity;
	else
		uid_validity = dbox_get_uidvalidity_next(ctx->box->list);
	mail_index_update_header(ctx->trans,
		offsetof(struct mail_index_header, uid_validity),
		&uid_validity, sizeof(uid_validity), TRUE);

	/* set next-uid */
	if (hdr->next_uid != 0)
		next_uid = hdr->next_uid;
	else if (backup_hdr != NULL && backup_hdr->next_uid != 0)
		next_uid = backup_hdr->next_uid;
	else
		next_uid = dbox_get_uidvalidity_next(ctx->box->list);
	if (next_uid > trans_hdr->next_uid) {
		mail_index_update_header(ctx->trans,
			offsetof(struct mail_index_header, next_uid),
			&next_uid, sizeof(next_uid), FALSE);
	}

	/* set highest-modseq */
	memset(&modseq_hdr, 0, sizeof(modseq_hdr));
	modseq_hdr.highest_modseq = mail_index_modseq_get_highest(ctx->view);
	if (ctx->backup_view != NULL) {
		modseq = mail_index_modseq_get_highest(ctx->backup_view);
		if (modseq_hdr.highest_modseq < modseq)
			modseq_hdr.highest_modseq = modseq;
	}
	mail_index_update_header_ext(ctx->trans, index->modseq_ext_id,
				     0, &modseq_hdr, sizeof(modseq_hdr));
	mail_index_view_close(&trans_view);
}

struct dbox_sync_rebuild_context *
dbox_sync_index_rebuild_init(struct mailbox *box,
			     struct mail_index_view *view,
			     struct mail_index_transaction *trans)
{
{'fraction_non_alphanumeric': 0.11465592334494773, 'fraction_numerical': 0.009146341463414634, 'mean_word_length': 5.181022880215343, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 94, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6739011', 'n_tokens_mistral': 3777, 'n_tokens_neox': 3482, 'n_words': 638}