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;