mail-index-transaction.c revision d810ebb2cc4588d11508a59bae1d1a13cd374b07
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch/* Inside transaction we keep messages stored in sequences in uid fields.
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch Before they're written to transaction log the sequences are changed to
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch UIDs. This is because we're able to compress sequence ranges better. */
2f64a4c88de91c483fb378bc80d10e1caa6f2305Stephan Boschstatic void mail_index_transaction_add_last(struct mail_index_transaction *t);
2f64a4c88de91c483fb378bc80d10e1caa6f2305Stephan Boschmail_index_transaction_begin(struct mail_index_view *view, int hide)
2f64a4c88de91c483fb378bc80d10e1caa6f2305Stephan Bosch /* don't allow syncing view while there's ongoing transactions */
2f64a4c88de91c483fb378bc80d10e1caa6f2305Stephan Bosch t->first_new_seq = mail_index_view_get_message_count(t->view)+1;
2f64a4c88de91c483fb378bc80d10e1caa6f2305Stephan Boschstatic void mail_index_transaction_free(struct mail_index_transaction *t)
45324f1eafa565dbc65e4dd335de9507dead55e6Timo Sirainen recs = buffer_get_modifyable_data(t->extra_rec_updates, &size);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch for (i = 0; i < size; i++) {
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschvoid mail_index_transaction_ref(struct mail_index_transaction *t)
2f64a4c88de91c483fb378bc80d10e1caa6f2305Stephan Boschvoid mail_index_transaction_unref(struct mail_index_transaction *t)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch if (--t->refcount == 0)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschmail_index_buffer_convert_to_uids(struct mail_index_transaction *t,
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch unsigned char *data;
faa8995f1d300e7a8917407a52bbd1b98e10bf25Timo Sirainen /* @UNSAFE */
faa8995f1d300e7a8917407a52bbd1b98e10bf25Timo Sirainen data = buffer_get_modifyable_data(buf, &size);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschmail_index_transaction_convert_to_uids(struct mail_index_transaction *t)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch const struct mail_index_extra_record_info *einfos;
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch einfos = buffer_get_data(index->extra_infos, NULL);
833bed942977673526c72e79bccc09314fc57104Phil Carmody updates = buffer_get_modifyable_data(t->extra_rec_updates,
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch for (i = 0; i < size; i++) {
91a482473f200152d6713181c0e36f7a4f03ef6dTimo Sirainen mail_index_buffer_convert_to_uids(t, updates[i],
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch mail_index_buffer_convert_to_uids(t, t->expunges,
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch sizeof(struct mail_transaction_expunge), TRUE);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch mail_index_buffer_convert_to_uids(t, t->updates,
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch sizeof(struct mail_transaction_flag_update), TRUE);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch mail_index_buffer_convert_to_uids(t, t->cache_updates,
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch sizeof(struct mail_transaction_cache_update), FALSE);
85f3bd5926fff0e70b6d259a5c8074bd8cdeb9adTimo Sirainenint mail_index_transaction_commit(struct mail_index_transaction *t,
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch if (mail_index_view_is_inconsistent(t->view)) {
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch mail_cache_transaction_commit(t->cache_trans_ctx);
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch if (mail_index_transaction_convert_to_uids(t) < 0)
93ed69606237a08623f8294c060fa148880058f8Timo Sirainen ret = mail_transaction_log_append(t, log_file_seq_r,
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschvoid mail_index_transaction_rollback(struct mail_index_transaction *t)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch mail_cache_transaction_rollback(t->cache_trans_ctx);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschmail_index_transaction_lookup(struct mail_index_transaction *t, uint32_t seq)
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch i_assert(seq >= t->first_new_seq && seq <= t->last_new_seq);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch pos = (seq - t->first_new_seq) * sizeof(struct mail_index_record);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch return buffer_get_space_unsafe(t->appends, pos,
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch sizeof(struct mail_index_record));
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschvoid mail_index_append(struct mail_index_transaction *t, uint32_t uid,
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch t->appends = buffer_create_dynamic(default_pool,
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch /* sequence number is visible only inside given view,
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch so let it generate it */
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch rec = buffer_append_space_unsafe(t->appends, sizeof(*rec));
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Boschvoid mail_index_append_assign_uids(struct mail_index_transaction *t,
833bed942977673526c72e79bccc09314fc57104Phil Carmody rec = buffer_get_modifyable_data(t->appends, &size);
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch /* find the first mail with uid = 0 */
faa8995f1d300e7a8917407a52bbd1b98e10bf25Timo Sirainenvoid mail_index_expunge(struct mail_index_transaction *t, uint32_t seq)
711e8e4c5c5d702dfa062f42a1ede5de14c151c9Stephan Bosch i_assert(seq > 0 && seq <= mail_index_view_get_message_count(t->view));
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch /* expunges is a sorted array of {seq1, seq2, ..}, .. */
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch t->expunges = buffer_create_dynamic(default_pool,
b37e11d37fb1ebf50511eef5d9d96d1205818458Stephan Bosch buffer_append(t->expunges, &exp, sizeof(exp));
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch data = buffer_get_modifyable_data(t->expunges, &size);
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch /* quick checks */
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch /* grow last range */
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch buffer_append(t->expunges, &exp, sizeof(exp));
95e0b82fdff1bb511067d703bb8b67c22f242c38Timo Sirainen /* grow down first range */
3fcb3d2d1f3583025ff62bae95ec706920f398b1Stephan Bosch buffer_insert(t->expunges, 0, &exp, sizeof(exp));
95e0b82fdff1bb511067d703bb8b67c22f242c38Timo Sirainen /* somewhere in the middle, array is sorted so find it with
95e0b82fdff1bb511067d703bb8b67c22f242c38Timo Sirainen binary search */
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch /* idx == size couldn't happen because we already handle it above */
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch i_assert(idx < size && data[idx].uid1 >= seq);
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch if (data[idx].uid1 <= seq && data[idx].uid2 >= seq) {
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch /* already expunged */
564e117d86ce5b659f9b9570edddc566f9ebb5dfStephan Bosch buffer_delete(t->expunges, idx * sizeof(*data),
sizeof(*data));
switch (modify_type) {
case MODIFY_REPLACE:
case MODIFY_ADD:
for (i = 0; i < INDEX_KEYWORDS_BYTE_COUNT; i++)
case MODIFY_REMOVE:
for (i = 0; i < INDEX_KEYWORDS_BYTE_COUNT; i++)
INDEX_KEYWORDS_BYTE_COUNT) == 0)
switch (t->last_update_modify_type) {
case MODIFY_REPLACE:
for (i = 0; i < INDEX_KEYWORDS_BYTE_COUNT; i++)
case MODIFY_ADD:
case MODIFY_REMOVE:
idx++;
size++;
void *data;
if (size == 0)
idx = 0;
return TRUE;
return FALSE;
void *old_record)
return FALSE;
return TRUE;
return FALSE;
if (t->last_cache_file_seq == 0)
if (t->first_new_seq != 0) {
*old_offset_r = 0;
return FALSE;
t->last_cache_file_seq = 0;
return FALSE;
return FALSE;
sizeof(*offset_r));
return TRUE;
const void *data)
t->extra_rec_updates =
sizeof(buffer_t *));