Optimized for speed:
_mh_message_save(): scan the message while saving it. If expunge==0, do not create temporary, operate directly on the message file instead. mh_append_message(): Do not rescan appended message. mh_scan_message(): Do not rescan the message if it's not changed
Showing
1 changed file
with
54 additions
and
18 deletions
... | @@ -71,9 +71,10 @@ struct _mh_message | ... | @@ -71,9 +71,10 @@ struct _mh_message |
71 | int attr_flags; /* Attribute flags */ | 71 | int attr_flags; /* Attribute flags */ |
72 | int deleted; /* Was the message originally deleted */ | 72 | int deleted; /* Was the message originally deleted */ |
73 | 73 | ||
74 | size_t header_lines; | 74 | time_t mtime; /* Time of last modification */ |
75 | size_t body_lines; | 75 | size_t header_lines; /* Number of lines in the header part */ |
76 | 76 | size_t body_lines; /* Number of lines in the body */ | |
77 | |||
77 | message_t message; /* Corresponding message_t */ | 78 | message_t message; /* Corresponding message_t */ |
78 | struct _mh_data *mhd; /* Back pointer. */ | 79 | struct _mh_data *mhd; /* Back pointer. */ |
79 | }; | 80 | }; |
... | @@ -479,19 +480,26 @@ static int | ... | @@ -479,19 +480,26 @@ static int |
479 | _mh_message_save (struct _mh_data *mhd, struct _mh_message *mhm, int expunge) | 480 | _mh_message_save (struct _mh_data *mhd, struct _mh_message *mhm, int expunge) |
480 | { | 481 | { |
481 | stream_t stream = NULL; | 482 | stream_t stream = NULL; |
482 | char *name, *buf = NULL, *msg_name; | 483 | char *name = NULL, *buf = NULL, *msg_name; |
483 | size_t n, off = 0; | 484 | size_t n, off = 0; |
484 | size_t bsize; | 485 | size_t bsize; |
486 | size_t nlines; | ||
485 | FILE *fp; | 487 | FILE *fp; |
486 | message_t msg = mhm->message; | 488 | message_t msg = mhm->message; |
487 | header_t hdr; | 489 | header_t hdr; |
488 | int status; | 490 | int status; |
489 | attribute_t attr; | 491 | attribute_t attr; |
490 | body_t body; | 492 | body_t body; |
491 | |||
492 | (void)expunge; | ||
493 | 493 | ||
494 | fp = _mh_tempfile (mhm->mhd, &name); | 494 | if (expunge) |
495 | fp = _mh_tempfile (mhm->mhd, &name); | ||
496 | else | ||
497 | { | ||
498 | msg_name = _mh_message_name (mhm, mhm->deleted); | ||
499 | fp = fopen (msg_name, "w"); | ||
500 | free (msg_name); | ||
501 | } | ||
502 | |||
495 | if (!fp) | 503 | if (!fp) |
496 | { | 504 | { |
497 | free (mhm); | 505 | free (mhm); |
... | @@ -515,11 +523,14 @@ _mh_message_save (struct _mh_data *mhd, struct _mh_message *mhm, int expunge) | ... | @@ -515,11 +523,14 @@ _mh_message_save (struct _mh_data *mhd, struct _mh_message *mhm, int expunge) |
515 | message_get_header (msg, &hdr); | 523 | message_get_header (msg, &hdr); |
516 | header_get_stream (hdr, &stream); | 524 | header_get_stream (hdr, &stream); |
517 | off = 0; | 525 | off = 0; |
526 | nlines = 0; | ||
518 | while ((status = stream_readline (stream, buf, bsize, off, &n)) == 0 | 527 | while ((status = stream_readline (stream, buf, bsize, off, &n)) == 0 |
519 | && n != 0) | 528 | && n != 0) |
520 | { | 529 | { |
521 | if (buf[0] == '\n') | 530 | if (buf[0] == '\n') |
522 | break; | 531 | break; |
532 | |||
533 | nlines++; | ||
523 | 534 | ||
524 | if (!(strncasecmp (buf, "status:", 7) == 0 | 535 | if (!(strncasecmp (buf, "status:", 7) == 0 |
525 | || strncasecmp (buf, "x-imapbase:", 11) == 0 | 536 | || strncasecmp (buf, "x-imapbase:", 11) == 0 |
... | @@ -527,6 +538,10 @@ _mh_message_save (struct _mh_data *mhd, struct _mh_message *mhm, int expunge) | ... | @@ -527,6 +538,10 @@ _mh_message_save (struct _mh_data *mhd, struct _mh_message *mhm, int expunge) |
527 | fprintf (fp, "%s", buf); | 538 | fprintf (fp, "%s", buf); |
528 | off += n; | 539 | off += n; |
529 | } | 540 | } |
541 | |||
542 | mhm->header_lines = nlines; | ||
543 | mhm->body_start = off; | ||
544 | |||
530 | /* Add imapbase */ | 545 | /* Add imapbase */ |
531 | if (!mhd->msg_head || (mhd->msg_head == mhm)) /*FIXME*/ | 546 | if (!mhd->msg_head || (mhd->msg_head == mhm)) /*FIXME*/ |
532 | fprintf (fp, "X-IMAPbase: %lu %u\n", mhd->uidvalidity, mhd->uidnext); | 547 | fprintf (fp, "X-IMAPbase: %lu %u\n", mhd->uidvalidity, mhd->uidnext); |
... | @@ -545,19 +560,30 @@ _mh_message_save (struct _mh_data *mhd, struct _mh_message *mhm, int expunge) | ... | @@ -545,19 +560,30 @@ _mh_message_save (struct _mh_data *mhd, struct _mh_message *mhm, int expunge) |
545 | message_get_body (msg, &body); | 560 | message_get_body (msg, &body); |
546 | body_get_stream (body, &stream); | 561 | body_get_stream (body, &stream); |
547 | off = 0; | 562 | off = 0; |
563 | nlines = 0; | ||
548 | while (stream_read (stream, buf, bsize, off, &n) == 0 && n != 0) | 564 | while (stream_read (stream, buf, bsize, off, &n) == 0 && n != 0) |
549 | { | 565 | { |
566 | char *p; | ||
567 | for (p = buf; p < buf + n; p++) | ||
568 | if (*p == '\n') | ||
569 | nlines++; | ||
550 | fwrite (buf, 1, n, fp); | 570 | fwrite (buf, 1, n, fp); |
551 | off += n; | 571 | off += n; |
552 | } | 572 | } |
553 | 573 | ||
574 | mhm->body_lines = nlines; | ||
575 | mhm->body_end = off; | ||
576 | |||
554 | free (buf); | 577 | free (buf); |
555 | fclose (fp); | 578 | fclose (fp); |
556 | 579 | ||
557 | msg_name = _mh_message_name (mhm, mhm->deleted); | 580 | if (expunge) |
558 | rename (name, msg_name); | 581 | { |
559 | free (name); | 582 | msg_name = _mh_message_name (mhm, mhm->deleted); |
560 | free (msg_name); | 583 | rename (name, msg_name); |
584 | free (name); | ||
585 | free (msg_name); | ||
586 | } | ||
561 | 587 | ||
562 | return 0; | 588 | return 0; |
563 | } | 589 | } |
... | @@ -584,8 +610,6 @@ mh_append_message (mailbox_t mailbox, message_t msg) | ... | @@ -584,8 +610,6 @@ mh_append_message (mailbox_t mailbox, message_t msg) |
584 | mhm->message = NULL; | 610 | mhm->message = NULL; |
585 | /* Insert and re-scan the message */ | 611 | /* Insert and re-scan the message */ |
586 | _mh_message_insert (mhd, mhm); | 612 | _mh_message_insert (mhd, mhm); |
587 | mh_message_stream_open (mhm); | ||
588 | mh_message_stream_close (mhm); | ||
589 | return status; | 613 | return status; |
590 | } | 614 | } |
591 | 615 | ||
... | @@ -851,9 +875,7 @@ _mh_message_delete (struct _mh_data *mhd, struct _mh_message *msg) | ... | @@ -851,9 +875,7 @@ _mh_message_delete (struct _mh_data *mhd, struct _mh_message *msg) |
851 | } | 875 | } |
852 | 876 | ||
853 | /* Scan given message and fill mh_message_t fields. | 877 | /* Scan given message and fill mh_message_t fields. |
854 | NOTE: the function assumes mhm->stream != NULL. | 878 | NOTE: the function assumes mhm->stream != NULL. */ |
855 | FIXME: Cache all the information and do not rescan the message when | ||
856 | re-opening it. */ | ||
857 | static int | 879 | static int |
858 | mh_scan_message (struct _mh_message *mhm) | 880 | mh_scan_message (struct _mh_message *mhm) |
859 | { | 881 | { |
... | @@ -867,6 +889,21 @@ mh_scan_message (struct _mh_message *mhm) | ... | @@ -867,6 +889,21 @@ mh_scan_message (struct _mh_message *mhm) |
867 | size_t blines = 0; | 889 | size_t blines = 0; |
868 | size_t body_start = 0; | 890 | size_t body_start = 0; |
869 | 891 | ||
892 | /* Check if the message was modified after the last scan */ | ||
893 | if (mhm->mtime) | ||
894 | { | ||
895 | struct stat st; | ||
896 | char *msg_name = _mh_message_name (mhm, mhm->deleted); | ||
897 | |||
898 | if (stat (msg_name, &st) == 0 && st.st_mtime == mhm->mtime) | ||
899 | { | ||
900 | /* Nothing to do */ | ||
901 | free (msg_name); | ||
902 | return 0; | ||
903 | } | ||
904 | free (msg_name); | ||
905 | } | ||
906 | |||
870 | while ((status = stream_readline (stream, buf, sizeof (buf), off, &n) == 0) | 907 | while ((status = stream_readline (stream, buf, sizeof (buf), off, &n) == 0) |
871 | && n != 0) | 908 | && n != 0) |
872 | { | 909 | { |
... | @@ -1391,8 +1428,7 @@ mh_envelope_date (envelope_t envelope, char *buf, size_t len, | ... | @@ -1391,8 +1428,7 @@ mh_envelope_date (envelope_t envelope, char *buf, size_t len, |
1391 | } | 1428 | } |
1392 | 1429 | ||
1393 | static int | 1430 | static int |
1394 | mh_envelope_sender (envelope_t envelope, char *buf, size_t len, | 1431 | mh_envelope_sender (envelope_t envelope, char *buf, size_t len, size_t *psize) |
1395 | size_t *psize) | ||
1396 | { | 1432 | { |
1397 | message_t msg = envelope_get_owner (envelope); | 1433 | message_t msg = envelope_get_owner (envelope); |
1398 | struct _mh_message *mhm = message_get_owner (msg); | 1434 | struct _mh_message *mhm = message_get_owner (msg); | ... | ... |
-
Please register or sign in to post a comment