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

#include "lib.h"
#include "array.h"
#include "buffer.h"
#include "mail-index-view-private.h"
#include "mail-transaction-log.h"

void mail_index_view_clone(struct mail_index_view *dest,
			   const struct mail_index_view *src)
{
	memset(dest, 0, sizeof(dest));
	dest->refcount = 1;
	dest->v = src->v;
	dest->index = src->index;
	if (src->log_view != NULL) {
		dest->log_view =
			mail_transaction_log_view_open(src->index->log);
	}

	dest->indexid = src->indexid;
	dest->inconsistency_id = src->inconsistency_id;
	dest->map = src->map;
	if (dest->map != NULL)
		dest->map->refcount++;

	dest->log_file_expunge_seq = src->log_file_expunge_seq;
	dest->log_file_expunge_offset = src->log_file_expunge_offset;
	dest->log_file_head_seq = src->log_file_head_seq;
	dest->log_file_head_offset = src->log_file_head_offset;

	i_array_init(&dest->module_contexts,
		     I_MIN(5, mail_index_module_register.id));
}

void mail_index_view_ref(struct mail_index_view *view)
{
	view->refcount++;
}

static void view_close(struct mail_index_view *view)
{
	i_assert(view->refcount == 0);

	mail_transaction_log_view_close(&view->log_view);

	if (array_is_created(&view->syncs_hidden))
		array_free(&view->syncs_hidden);
	mail_index_unmap(&view->map);
	if (array_is_created(&view->map_refs)) {
		mail_index_view_unref_maps(view);
		array_free(&view->map_refs);
	}
	array_free(&view->module_contexts);
	i_free(view);
}

bool mail_index_view_is_inconsistent(struct mail_index_view *view)
{
	if (view->index->indexid != view->indexid ||
	    view->index->inconsistency_id != view->inconsistency_id)
		view->inconsistent = TRUE;
	return view->inconsistent;
}

struct mail_index *mail_index_view_get_index(struct mail_index_view *view)
{
	return view->index;
}

void mail_index_view_transaction_ref(struct mail_index_view *view)
{
	view->transactions++;
}

void mail_index_view_transaction_unref(struct mail_index_view *view)
{
	i_assert(view->transactions > 0);

	view->transactions--;
}

static void mail_index_view_ref_map(struct mail_index_view *view,
				    struct mail_index_map *map)
{
	struct mail_index_map *const *maps;
	unsigned int i, count;

	if (array_is_created(&view->map_refs)) {
		maps = array_get(&view->map_refs, &count);

		/* if map is already referenced, do nothing */
		for (i = 0; i < count; i++) {
			if (maps[i] == map)
				return;
		}
	} else {
		i_array_init(&view->map_refs, 4);
	}

	/* reference the given mapping. the reference is dropped when the view
	   is synchronized or closed. */
	map->refcount++;
	array_append(&view->map_refs, &map, 1);
}

void mail_index_view_unref_maps(struct mail_index_view *view)
{
	struct mail_index_map **maps;
	unsigned int i, count;

	if (!array_is_created(&view->map_refs))
		return;

	maps = array_get_modifiable(&view->map_refs, &count);
	for (i = 0; i < count; i++)
		mail_index_unmap(&maps[i]);

	array_clear(&view->map_refs);
}

static uint32_t view_get_messages_count(struct mail_index_view *view)
{
	return view->map->hdr.messages_count;
}

static const struct mail_index_header *
view_get_header(struct mail_index_view *view)
{
	return &view->map->hdr;
}

static const struct mail_index_record *
view_lookup_full(struct mail_index_view *view, uint32_t seq,
		 struct mail_index_map **map_r, bool *expunged_r)
{
	static struct mail_index_record broken_rec;
	struct mail_index_map *map;
	const struct mail_index_record *rec, *head_rec;

	i_assert(seq > 0 && seq <= mail_index_view_get_messages_count(view));

	/* look up the record */
	rec = MAIL_INDEX_MAP_IDX(view->map, seq-1);
	if (rec->uid == 0) {
		if (!view->inconsistent) {
			mail_index_set_error(view->index,
				"Corrupted Index file %s: Record [%u].uid=0",
				view->index->filepath, seq);
			(void)mail_index_fsck(view->index);
			view->inconsistent = TRUE;
		}

		/* we'll need to return something so the caller doesn't crash */
		*map_r = view->map;
		*expunged_r = TRUE;<commit_msg>index: Minor optimization.<commit_after>/* Copyright (c) 2003-2009 Dovecot authors, see the included COPYING file */

#include "lib.h"
#include "array.h"
#include "buffer.h"
#include "mail-index-view-private.h"
#include "mail-transaction-log.h"

void mail_index_view_clone(struct mail_index_view *dest,
			   const struct mail_index_view *src)
{
	memset(dest, 0, sizeof(dest));
	dest->refcount = 1;
	dest->v = src->v;
	dest->index = src->index;
	if (src->log_view != NULL) {
		dest->log_view =
			mail_transaction_log_view_open(src->index->log);
	}

	dest->indexid = src->indexid;
	dest->inconsistency_id = src->inconsistency_id;
	dest->map = src->map;
	if (dest->map != NULL)
		dest->map->refcount++;

	dest->log_file_expunge_seq = src->log_file_expunge_seq;
	dest->log_file_expunge_offset = src->log_file_expunge_offset;
	dest->log_file_head_seq = src->log_file_head_seq;
	dest->log_file_head_offset = src->log_file_head_offset;

	i_array_init(&dest->module_contexts,
		     I_MIN(5, mail_index_module_register.id));
}

void mail_index_view_ref(struct mail_index_view *view)
{
	view->refcount++;
}

static void view_close(struct mail_index_view *view)
{
	i_assert(view->refcount == 0);

	mail_transaction_log_view_close(&view->log_view);

	if (array_is_created(&view->syncs_hidden))
		array_free(&view->syncs_hidden);
	mail_index_unmap(&view->map);
	if (array_is_created(&view->map_refs)) {
		mail_index_view_unref_maps(view);
		array_free(&view->map_refs);
	}
	array_free(&view->module_contexts);
	i_free(view);
}

bool mail_index_view_is_inconsistent(struct mail_index_view *view)
{
	if (view->index->indexid != view->indexid ||
	    view->index->inconsistency_id != view->inconsistency_id)
		view->inconsistent = TRUE;
	return view->inconsistent;
}

struct mail_index *mail_index_view_get_index(struct mail_index_view *view)
{
	return view->index;
}

void mail_index_view_transaction_ref(struct mail_index_view *view)
{
	view->transactions++;
}

void mail_index_view_transaction_unref(struct mail_index_view *view)
{
	i_assert(view->transactions > 0);

	view->transactions--;
}

static void mail_index_view_ref_map(struct mail_index_view *view,
				    struct mail_index_map *map)
{
	struct mail_index_map *const *maps;
	unsigned int i, count;

	if (array_is_created(&view->map_refs)) {
		maps = array_get(&view->map_refs, &count);

		/* if map is already referenced, do nothing */
		for (i = 0; i < count; i++) {
			if (maps[i] == map)
				return;
		}
	} else {
		i_array_init(&view->map_refs, 4);
	}

	/* reference the given mapping. the reference is dropped when the view
	   is synchronized or closed. */
	map->refcount++;
	array_append(&view->map_refs, &map, 1);
}

void mail_index_view_unref_maps(struct mail_index_view *view)
{
	struct mail_index_map **maps;
	unsigned int i, count;

	if (!array_is_created(&view->map_refs))
		return;

	maps = array_get_modifiable(&view->map_refs, &count);
	for (i = 0; i < count; i++)
		mail_index_unmap(&maps[i]);

	array_clear(&view->map_refs);
}

static uint32_t view_get_messages_count(struct mail_index_view *view)
{
	return view->map->hdr.messages_count;
}

static const struct mail_index_header *
view_get_header(struct mail_index_view *view)
{
	return &view->map->hdr;
}

static const struct mail_index_record *
view_lookup_full(struct mail_index_view *view, uint32_t seq,
		 struct mail_index_map **map_r, bool *expunged_r)
{
	static struct mail_index_record broken_rec;
	struct mail_index_map *map;
	const struct mail_index_record *rec, *head_rec;

	i_assert(seq > 0 && seq <= mail_index_view_get_messages_count(view));

	/* look up the record */
	rec = MAIL_INDEX_MAP_IDX(view->map, seq-1);
	if (unlikely(rec->uid == 0)) {
		if (!view->inconsistent) {
			mail_index_set_error(view->index,
				"Corrupted Index file %s: Record [%u].uid=0",
				view->index->filepath, seq);
			(void)mail_index_fsck(view->index);
			view->inconsistent = TRUE;
		}

		/* we'll need to return something so the caller doesn't crash */
		*map_r = view->map;
		*expunged_r = TRUE;
{'fraction_non_alphanumeric': 0.13616489693941286, 'fraction_numerical': 0.006246096189881324, 'mean_word_length': 5.206201550387597, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 145, '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': '4489416', 'n_tokens_mistral': 3162, 'n_tokens_neox': 2953, 'n_words': 577}