mail-index-file.c revision f16b058c2ea114f8e6887c06f797e7be6d04d3fb
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (C) 2003 Timo Sirainen */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct mail_index_record *mail_index_next(struct mail_index *index,
573f0491a5733fe21fa062a455acb4790b4e0499Timo Sirainen i_assert(index->lock_type != MAIL_LOCK_UNLOCK);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen return rec+1 == INDEX_END_RECORD(index) ? NULL : rec+1;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenstatic int compress(struct mail_index *index, unsigned int remove_first_idx,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct mail_index_record *rec = INDEX_RECORD_AT(index, 0);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen count = remove_last_idx - remove_first_idx + 1;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen memmove(rec + remove_first_idx, rec + remove_last_idx + 1,
2dd39e478269d6fb0bb26d12b394aa30ee965e38Timo Sirainen (idx_limit - remove_last_idx - 1) * sizeof(*rec));
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen index->header->used_file_size -= sizeof(*rec) * count;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen index->mmap_used_length -= sizeof(*rec) * count;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen /* not really needed since append() will initialize it as well,
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen but may help preventing problems if change is only partially
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen written to disk */
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen memset((char *) rec + index->mmap_used_length, 0, sizeof(*rec) * count);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainenint mail_index_expunge_record_range(struct mail_index *index,
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen i_assert(index->lock_type == MAIL_LOCK_EXCLUSIVE);
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen first_idx = INDEX_RECORD_INDEX(index, first_rec);
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen last_idx = INDEX_RECORD_INDEX(index, last_rec);
4ba9a1d3facc515b3feb5238a16bcf91f76fac61Timo Sirainen index->header->messages_count -= last_idx - first_idx + 1;
dfaefeabae939803ceb8c503101e86b5496541d1Timo Sirainen mail_index_mark_flag_changes(index, rec, rec->msg_flags, 0);
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainenstruct mail_index_record *mail_index_lookup(struct mail_index *index,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen unsigned int seq)
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen i_assert(index->lock_type != MAIL_LOCK_UNLOCK);
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainenmail_index_lookup_uid_range(struct mail_index *index, unsigned int first_uid,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen unsigned int idx_limit, idx, left_idx, right_idx;
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen i_assert(index->lock_type != MAIL_LOCK_UNLOCK);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen if (rec_p[idx].uid < first_uid || rec_p[idx].uid > last_uid) {
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen /* could still be the next one */
c29216637957d4b3126c6929ac5ba98138256ce1Timo Sirainen rec_p[idx].uid < first_uid || rec_p[idx].uid > last_uid) {
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainenint mail_index_compress(struct mail_index *index)
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen if (index->header_size >= sizeof(struct mail_index_header))
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE))
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen /* make sure the file is large enough */
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen diff = sizeof(struct mail_index_header) - index->header_size;
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen if (index->mmap_used_length + diff > index->mmap_full_length) {
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen /* mmap_update ftruncates the file to multiples of
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen mail_index_record, make sure we grow it enough here. */
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen new_file_size = index->mmap_used_length + diff +
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen (sizeof(struct mail_index_record) -
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen if (file_set_size(index->fd, new_file_size) < 0) {
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen index_set_syscall_error(index, "file_set_size()");
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen /* if we break, we'll have to rebuild it completely */
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen index->header->flags |= MAIL_INDEX_HDR_FLAG_REBUILD;
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen if (!mail_index_fmdatasync(index, index->header_size))
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen memmove((char *) index->mmap_base + sizeof(struct mail_index_header),
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen (char *) index->mmap_base + index->header_size,
b2c1349cf07410aefab0f5b17153af9e5cfcf48fTimo Sirainen index->mmap_used_length - index->header_size);
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen memset((char *) index->mmap_base + index->header_size, 0, diff);
8a13b020f90e080570658b18c042e7e352c8b14fTimo Sirainen index->header_size = sizeof(struct mail_index_header);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen index->header->header_size = sizeof(struct mail_index_header);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen if (!mail_index_fmdatasync(index, index->mmap_used_length))
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen index->header->flags &= ~MAIL_INDEX_HDR_FLAG_REBUILD;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint mail_index_truncate(struct mail_index *index)
bd1b2615928a1e8be190cb0405754f0aec8cac2fTimo Sirainen i_assert(index->lock_type == MAIL_LOCK_EXCLUSIVE);
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen if (index->mmap_full_length <= INDEX_FILE_MIN_SIZE(index) ||
2ebeb22b9a8a8bb7fbe2f2e2908478a220792b87Timo Sirainen /* really truncate the file only when it's almost empty */
a423d985ba7261661475811c22b21b80ec765a71Timo Sirainen empty_space = index->mmap_full_length - index->mmap_used_length;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen index->mmap_full_length / 100 * INDEX_TRUNCATE_PERCENTAGE;
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen index->mmap_full_length = index->mmap_used_length +
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen (empty_space * INDEX_TRUNCATE_KEEP_PERCENTAGE / 100);
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen /* keep the size record-aligned */
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen index->mmap_full_length -= (index->mmap_full_length -
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen if (index->mmap_full_length < INDEX_FILE_MIN_SIZE(index))
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen index->mmap_full_length = INDEX_FILE_MIN_SIZE(index);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen if (ftruncate(index->fd, (off_t)index->mmap_full_length) < 0)
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen return index_set_syscall_error(index, "ftruncate()");