Mercurial > dovecot > original-hg > dovecot-1.2
comparison src/lib-storage/index/maildir/maildir-sync.c @ 1954:2f6e137cdc44 HEAD
Syncing optimizations.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 02 May 2004 21:07:24 +0300 |
parents | 777da553d1d3 |
children | 0f0128b4af5d |
comparison
equal
deleted
inserted
replaced
1953:a1c00aa3a078 | 1954:2f6e137cdc44 |
---|---|
28 #define MAILDIR_FILENAME_FLAG_FOUND 128 | 28 #define MAILDIR_FILENAME_FLAG_FOUND 128 |
29 | 29 |
30 struct maildir_sync_context { | 30 struct maildir_sync_context { |
31 struct index_mailbox *ibox; | 31 struct index_mailbox *ibox; |
32 const char *new_dir, *cur_dir; | 32 const char *new_dir, *cur_dir; |
33 int partial; | |
33 | 34 |
34 struct maildir_uidlist_sync_ctx *uidlist_sync_ctx; | 35 struct maildir_uidlist_sync_ctx *uidlist_sync_ctx; |
35 }; | 36 }; |
36 | 37 |
37 static int maildir_expunge(struct index_mailbox *ibox, const char *path, | 38 static int maildir_expunge(struct index_mailbox *ibox, const char *path, |
122 if (maildir_sync_record(ibox, view, &sync_rec) < 0) { | 123 if (maildir_sync_record(ibox, view, &sync_rec) < 0) { |
123 ret = -1; | 124 ret = -1; |
124 break; | 125 break; |
125 } | 126 } |
126 } | 127 } |
127 if (mail_index_sync_end(sync_ctx) < 0) | 128 if (mail_index_sync_end(sync_ctx, 0, 0) < 0) |
128 ret = -1; | 129 ret = -1; |
129 } | 130 } |
130 | 131 |
131 if (ret == 0) { | 132 if (ret == 0) { |
132 ibox->commit_log_file_seq = 0; | 133 ibox->commit_log_file_seq = 0; |
259 } | 260 } |
260 | 261 |
261 static int maildir_sync_quick_check(struct maildir_sync_context *ctx, | 262 static int maildir_sync_quick_check(struct maildir_sync_context *ctx, |
262 int *new_changed_r, int *cur_changed_r) | 263 int *new_changed_r, int *cur_changed_r) |
263 { | 264 { |
265 const struct mail_index_header *hdr; | |
264 struct index_mailbox *ibox = ctx->ibox; | 266 struct index_mailbox *ibox = ctx->ibox; |
265 struct stat st; | 267 struct stat st; |
266 time_t new_mtime, cur_mtime; | 268 time_t new_mtime, cur_mtime; |
267 | 269 |
268 *new_changed_r = *cur_changed_r = FALSE; | 270 *new_changed_r = *cur_changed_r = FALSE; |
278 mail_storage_set_critical(ibox->box.storage, | 280 mail_storage_set_critical(ibox->box.storage, |
279 "stat(%s) failed: %m", ctx->cur_dir); | 281 "stat(%s) failed: %m", ctx->cur_dir); |
280 return -1; | 282 return -1; |
281 } | 283 } |
282 cur_mtime = st.st_mtime; | 284 cur_mtime = st.st_mtime; |
285 | |
286 if (ibox->last_cur_mtime == 0) { | |
287 /* first sync in this session, get cur stamp from index */ | |
288 if (mail_index_get_header(ibox->view, &hdr) == 0) | |
289 ibox->last_cur_mtime = hdr->sync_stamp; | |
290 } | |
283 | 291 |
284 if (new_mtime != ibox->last_new_mtime || | 292 if (new_mtime != ibox->last_new_mtime || |
285 new_mtime >= ibox->last_sync - MAILDIR_SYNC_SECS) { | 293 new_mtime >= ibox->last_sync - MAILDIR_SYNC_SECS) { |
286 *new_changed_r = TRUE; | 294 *new_changed_r = TRUE; |
287 ibox->last_new_mtime = new_mtime; | 295 ibox->last_new_mtime = new_mtime; |
288 } | 296 } |
297 | |
289 if (cur_mtime != ibox->last_cur_mtime || | 298 if (cur_mtime != ibox->last_cur_mtime || |
290 (cur_mtime >= ibox->last_sync - MAILDIR_SYNC_SECS && | 299 (ibox->last_cur_dirty && |
291 ioloop_time - ibox->last_sync > MAILDIR_SYNC_SECS)) { | 300 ioloop_time - ibox->last_sync > MAILDIR_SYNC_SECS)) { |
292 /* cur/ changed, or delayed cur/ check */ | 301 /* cur/ changed, or delayed cur/ check */ |
293 *cur_changed_r = TRUE; | 302 *cur_changed_r = TRUE; |
294 ibox->last_cur_mtime = cur_mtime; | 303 ibox->last_cur_mtime = cur_mtime; |
295 } | 304 } |
296 ibox->last_sync = ioloop_time; | 305 ibox->last_sync = ioloop_time; |
306 ibox->last_cur_dirty = cur_mtime >= ibox->last_sync - MAILDIR_SYNC_SECS; | |
297 | 307 |
298 return 0; | 308 return 0; |
299 } | 309 } |
300 | 310 |
301 static int maildir_sync_index(struct maildir_sync_context *ctx) | 311 static int maildir_sync_index(struct maildir_sync_context *ctx) |
306 struct maildir_uidlist_iter_ctx *iter; | 316 struct maildir_uidlist_iter_ctx *iter; |
307 struct mail_index_transaction *trans; | 317 struct mail_index_transaction *trans; |
308 struct mail_index_view *view; | 318 struct mail_index_view *view; |
309 const struct mail_index_header *hdr; | 319 const struct mail_index_header *hdr; |
310 const struct mail_index_record *rec; | 320 const struct mail_index_record *rec; |
311 uint32_t seq, uid, uflags; | 321 uint32_t seq, uid; |
322 enum maildir_uidlist_rec_flag uflags; | |
312 const char *filename; | 323 const char *filename; |
313 enum mail_flags flags; | 324 enum mail_flags flags; |
314 custom_flags_mask_t custom_flags; | 325 custom_flags_mask_t custom_flags; |
326 uint32_t sync_stamp; | |
315 int ret; | 327 int ret; |
316 | 328 |
317 if (mail_index_sync_begin(ibox->index, &sync_ctx, &view, | 329 if (mail_index_sync_begin(ibox->index, &sync_ctx, &view, |
318 (uint32_t)-1, (uoff_t)-1) <= 0) { | 330 (uint32_t)-1, (uoff_t)-1) <= 0) { |
319 mail_storage_set_index_error(ibox); | 331 mail_storage_set_index_error(ibox); |
330 while (maildir_uidlist_iter_next(iter, &uid, &uflags, &filename)) { | 342 while (maildir_uidlist_iter_next(iter, &uid, &uflags, &filename)) { |
331 maildir_filename_get_flags(filename, &flags, custom_flags); | 343 maildir_filename_get_flags(filename, &flags, custom_flags); |
332 | 344 |
333 __again: | 345 __again: |
334 seq++; | 346 seq++; |
347 if ((uflags & MAILDIR_UIDLIST_REC_FLAG_NONSYNCED) != 0) { | |
348 /* partial syncing */ | |
349 continue; | |
350 } | |
351 | |
335 if (seq > hdr->messages_count) { | 352 if (seq > hdr->messages_count) { |
336 mail_index_append(trans, uid, &seq); | 353 mail_index_append(trans, uid, &seq); |
337 mail_index_update_flags(trans, seq, MODIFY_REPLACE, | 354 mail_index_update_flags(trans, seq, MODIFY_REPLACE, |
338 flags, custom_flags); | 355 flags, custom_flags); |
339 continue; | 356 continue; |
370 flags, custom_flags); | 387 flags, custom_flags); |
371 } | 388 } |
372 } | 389 } |
373 maildir_uidlist_iter_deinit(iter); | 390 maildir_uidlist_iter_deinit(iter); |
374 | 391 |
392 if (!ctx->partial) { | |
393 /* expunge the rest */ | |
394 for (seq++; seq <= hdr->messages_count; seq++) | |
395 mail_index_expunge(trans, seq); | |
396 } | |
397 | |
375 if (ret < 0) | 398 if (ret < 0) |
376 mail_index_transaction_rollback(trans); | 399 mail_index_transaction_rollback(trans); |
377 else { | 400 else { |
378 uint32_t seq; | 401 uint32_t seq; |
379 uoff_t offset; | 402 uoff_t offset; |
391 if (maildir_sync_record(ibox, view, &sync_rec) < 0) { | 414 if (maildir_sync_record(ibox, view, &sync_rec) < 0) { |
392 ret = -1; | 415 ret = -1; |
393 break; | 416 break; |
394 } | 417 } |
395 } | 418 } |
396 if (mail_index_sync_end(sync_ctx) < 0) | 419 |
420 sync_stamp = ibox->last_cur_dirty ? 0 : ibox->last_cur_mtime; | |
421 if (mail_index_sync_end(sync_ctx, sync_stamp, 0) < 0) | |
397 ret = -1; | 422 ret = -1; |
398 | 423 |
399 if (ret == 0) { | 424 if (ret == 0) { |
400 ibox->commit_log_file_seq = 0; | 425 ibox->commit_log_file_seq = 0; |
401 ibox->commit_log_file_offset = 0; | 426 ibox->commit_log_file_offset = 0; |
414 return -1; | 439 return -1; |
415 | 440 |
416 if (!new_changed && !cur_changed) | 441 if (!new_changed && !cur_changed) |
417 return 0; | 442 return 0; |
418 | 443 |
419 // FIXME: don't sync cur/ directory if not needed | 444 ctx->partial = !cur_changed; |
420 ctx->uidlist_sync_ctx = maildir_uidlist_sync_init(ctx->ibox->uidlist); | 445 ctx->uidlist_sync_ctx = |
446 maildir_uidlist_sync_init(ctx->ibox->uidlist, ctx->partial); | |
421 | 447 |
422 if (maildir_scan_dir(ctx, TRUE) < 0) | 448 if (maildir_scan_dir(ctx, TRUE) < 0) |
423 return -1; | 449 return -1; |
424 if (maildir_scan_dir(ctx, FALSE) < 0) | 450 if (cur_changed) { |
425 return -1; | 451 if (maildir_scan_dir(ctx, FALSE) < 0) |
452 return -1; | |
453 } | |
426 | 454 |
427 ret = maildir_uidlist_sync_deinit(ctx->uidlist_sync_ctx); | 455 ret = maildir_uidlist_sync_deinit(ctx->uidlist_sync_ctx); |
428 ctx->uidlist_sync_ctx = NULL; | 456 ctx->uidlist_sync_ctx = NULL; |
429 | 457 |
430 if (ret == 0) | 458 if (ret == 0) |
434 | 462 |
435 static int maildir_sync_context_readonly(struct maildir_sync_context *ctx) | 463 static int maildir_sync_context_readonly(struct maildir_sync_context *ctx) |
436 { | 464 { |
437 int ret; | 465 int ret; |
438 | 466 |
439 ctx->uidlist_sync_ctx = maildir_uidlist_sync_init(ctx->ibox->uidlist); | 467 ctx->uidlist_sync_ctx = |
468 maildir_uidlist_sync_init(ctx->ibox->uidlist, FALSE); | |
440 | 469 |
441 if (maildir_scan_dir(ctx, TRUE) < 0) | 470 if (maildir_scan_dir(ctx, TRUE) < 0) |
442 return -1; | 471 return -1; |
443 if (maildir_scan_dir(ctx, FALSE) < 0) | 472 if (maildir_scan_dir(ctx, FALSE) < 0) |
444 return -1; | 473 return -1; |