Changeset 1048
- Timestamp:
- 10/23/06 14:59:59
- Files:
-
- trunk/ChangeLog (modified) (1 diff)
- trunk/libtinymail-camel/camel-lite/camel/camel-folder-summary.c (modified) (7 diffs)
- trunk/libtinymail-camel/camel-lite/camel/camel-folder-summary.h (modified) (1 diff)
- trunk/libtinymail-camel/camel-lite/camel/camel-folder.c (modified) (1 diff)
- trunk/libtinymail-camel/camel-lite/camel/providers/Makefile.am (modified) (1 diff)
- trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c (modified) (17 diffs)
- trunk/libtinymail-camel/camel-lite/camel/providers/nntp/camel-nntp-summary.c (modified) (4 diffs)
- trunk/libtinymail-gnome-desktop/tny-gnome-device-priv.h (modified) (1 diff)
- trunk/libtinymail-gnome-desktop/tny-gnome-device.c (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/ChangeLog
r1046 r1048 1 2006-10-23 Philip Van Hoof <pvanhoof@gnome.org> 2 3 * libtinymail-camel/camel-lite: Drastic reduction of memory 4 consumption on initial download of both IMAP and NNTP folders. 5 * libtinymail-gnome-desktop: Default status of the device is now 6 offline in stead of online (for example in case network manager 7 installation was invalid or not found) 8 1 9 2006-10-20 Sankarshan Mukhopadhyay <sankarshan.mukhopadhyay@gmail.com> 2 10 trunk/libtinymail-camel/camel-lite/camel/camel-folder-summary.c
r1043 r1048 114 114 static void camel_folder_summary_finalize (CamelObject *obj); 115 115 116 117 static void camel_folder_summary_mmap_add(CamelFolderSummary *s, CamelMessageInfo *info); 118 static void camel_folder_summary_unload_mmap (CamelFolderSummary *s); 119 116 120 static CamelObjectClass *camel_folder_summary_parent; 117 121 … … 162 166 } 163 167 164 static void165 camel_folder_summary_finalize (CamelObject *obj) 166 { 167 struct _CamelFolderSummaryPrivate *p; 168 CamelFolderSummary *s = (CamelFolderSummary *)obj; 169 170 p = _PRIVATE(obj); 171 168 static gboolean always_true (gpointer key, gpointer value, gpointer gp) 169 { 170 return TRUE; 171 } 172 173 static void 174 camel_folder_summary_unload_mmap (CamelFolderSummary *s) 175 { 172 176 camel_folder_summary_clear(s); 173 177 if (s->file) … … 176 180 177 181 g_ptr_array_foreach (s->messages, foreach_msginfo, (gpointer)s->message_info_size); 182 if (s->messages->len > 0) 183 g_ptr_array_remove_range (s->messages, 0, s->messages->len-1); 184 g_hash_table_foreach_remove (s->messages_uid, always_true, NULL); 185 186 } 187 188 static void 189 camel_folder_summary_finalize (CamelObject *obj) 190 { 191 struct _CamelFolderSummaryPrivate *p; 192 CamelFolderSummary *s = (CamelFolderSummary *)obj; 193 194 p = _PRIVATE(obj); 195 196 camel_folder_summary_clear(s); 197 if (s->file) 198 g_mapped_file_free (s->file); 199 s->file = NULL; 200 201 g_ptr_array_foreach (s->messages, foreach_msginfo, (gpointer)s->message_info_size); 178 202 g_ptr_array_free(s->messages, TRUE); 179 203 g_hash_table_destroy(s->messages_uid); 204 s->messages_uid = NULL; 180 205 181 206 g_hash_table_foreach(p->filter_charset, free_o_name, 0); … … 592 617 } 593 618 594 camel_folder_summary_ add(s, mi);619 camel_folder_summary_mmap_add(s, mi); 595 620 } 596 621 … … 808 833 809 834 835 836 void 837 camel_folder_summary_dump_mmap (CamelFolderSummary *s) 838 { 839 camel_folder_summary_save (s); 840 camel_folder_summary_unload_mmap (s); 841 camel_folder_summary_load(s); 842 843 return; 844 } 845 810 846 /** 811 847 * camel_folder_summary_add: … … 846 882 } 847 883 884 static void 885 camel_folder_summary_mmap_add(CamelFolderSummary *s, CamelMessageInfo *info) 886 { 887 CAMEL_SUMMARY_LOCK(s, summary_lock); 888 889 /* unnecessary for pooled vectors */ 890 #ifdef DOESTRV 891 /* this is vitally important, and also if this is ever modified, then 892 the hash table needs to be resynced */ 893 info->strings = e_strv_pack(info->strings); 894 #endif 895 896 g_ptr_array_add(s->messages, info); 897 g_hash_table_insert(s->messages_uid, (char *)camel_message_info_uid(info), info); 898 s->flags |= CAMEL_SUMMARY_DIRTY; 899 900 CAMEL_SUMMARY_UNLOCK(s, summary_lock); 901 } 848 902 849 903 /** … … 1091 1145 camel_folder_summary_touch(CamelFolderSummary *s) 1092 1146 { 1093 CAMEL_SUMMARY_LOCK(s, summary_lock);1147 //CAMEL_SUMMARY_LOCK(s, summary_lock); 1094 1148 s->flags |= CAMEL_SUMMARY_DIRTY; 1095 CAMEL_SUMMARY_UNLOCK(s, summary_lock);1149 //CAMEL_SUMMARY_UNLOCK(s, summary_lock); 1096 1150 } 1097 1151 trunk/libtinymail-camel/camel-lite/camel/camel-folder-summary.h
r1043 r1048 309 309 CamelFolderSummary *camel_folder_summary_new (struct _CamelFolder *folder); 310 310 311 void camel_folder_summary_dump_mmap (CamelFolderSummary *s); 312 311 313 unsigned char* 312 314 decode_uint32 (unsigned char *start, guint32 *dest, gboolean is_string); trunk/libtinymail-camel/camel-lite/camel/camel-folder.c
r1025 r1048 2117 2117 GPtrArray *olduids; 2118 2118 char *olduid; 2119 2119 2120 2120 g_assert(info != NULL); 2121 2121 trunk/libtinymail-camel/camel-lite/camel/providers/Makefile.am
r1025 r1048 1 1 ## Process this file with automake to produce Makefile.in 2 2 3 4 SUBDIRS = pop3 smtp imap local 5 3 6 if ENABLE_NNTP 4 NNTP_DIR=nntp 7 SUBDIRS += nntp 5 8 endif 6 9 7 10 if ENABLE_IMAPP 8 IMAPP_DIR=imapp 11 SUBDIRS += imapp 9 12 endif 13 10 14 11 15 if OS_WIN32 12 16 else 13 S ENDMAIL_DIR=sendmail17 SUBDIRS += sendmail 14 18 endif 15 19 16 SUBDIRS = pop3 $(SENDMAIL_DIR) smtp imap $(NNTP_DIR) local $(IMAPP_DIR)17 20 18 trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c
r1043 r1048 2338 2338 CamelException *ex) 2339 2339 { 2340 CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store); 2341 CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); 2342 GPtrArray *fetch_data = NULL, *messages = NULL, *needheaders; 2343 guint32 flags, uidval; 2344 int i, seq, first, size, got; 2345 CamelImapResponseType type; 2346 const char *header_spec; 2347 CamelImapMessageInfo *mi, *info; 2348 CamelStream *stream; 2349 char *uid, *resp; 2350 GData *data; 2351 2352 if (store->server_level >= IMAP_LEVEL_IMAP4REV1) 2353 header_spec = "HEADER.FIELDS (" CAMEL_MESSAGE_INFO_HEADERS MAILING_LIST_HEADERS ")"; 2354 else 2355 header_spec = "0"; 2356 2357 /* Used as a way to fetch all Headers instead of the selective headers. 2358 Support for fetching custom headers could be done in a better way, 2359 using CamelURL and EPlugins. */ 2360 2361 if( g_getenv ("EVO_IMAP_FETCH_ALL_HEADERS") ) 2362 header_spec = "HEADER"; 2363 2340 CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store); 2341 CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder); 2342 GPtrArray *fetch_data = NULL, *messages = NULL, *needheaders; 2343 guint32 flags, uidval; 2344 int i, seq, first, size, got; 2345 CamelImapResponseType type; 2346 const char *header_spec; 2347 CamelImapMessageInfo *mi, *info; 2348 CamelStream *stream; 2349 char *uid, *resp; 2350 GData *data; 2351 gboolean more = TRUE; 2352 unsigned int nextn = 1; 2353 2354 if (store->server_level >= IMAP_LEVEL_IMAP4REV1) 2355 header_spec = "HEADER.FIELDS (" CAMEL_MESSAGE_INFO_HEADERS MAILING_LIST_HEADERS ")"; 2356 else 2357 header_spec = "0"; 2358 2359 /* Used as a way to fetch all Headers instead of the selective headers. 2360 Support for fetching custom headers could be done in a better way, 2361 using CamelURL and EPlugins. */ 2362 2363 if( g_getenv ("EVO_IMAP_FETCH_ALL_HEADERS") ) 2364 header_spec = "HEADER"; 2365 2366 while (more) 2367 { 2368 gint count = 0; 2369 more = FALSE; 2370 2364 2371 /* Figure out if any of the new messages are already cached (which 2365 2372 * may be the case if we're re-syncing after disconnected operation). … … 2375 2382 } else 2376 2383 uidval = 0; 2377 2384 2378 2385 size = (exists - seq) * (IMAP_PRETEND_SIZEOF_FLAGS + IMAP_PRETEND_SIZEOF_SIZE + IMAP_PRETEND_SIZEOF_HEADERS); 2379 2386 got = 0; 2380 2387 if (!camel_imap_command_start (store, folder, ex, 2381 "UID FETCH %d: *(FLAGS RFC822.SIZE INTERNALDATE BODY.PEEK[%s])",2382 uidval + 1, header_spec))2388 "UID FETCH %d:%d (FLAGS RFC822.SIZE INTERNALDATE BODY.PEEK[%s])", 2389 uidval + 1, uidval + 1 + nextn, header_spec)) 2383 2390 return; 2391 2392 /* 1, 7, 19, 43, 91, .. until 1000 (the smaller, the more dumps, 2393 the slower. But too large consumes a lot memory, and also takes longer 2394 to fetch from the service before we can dump) */ 2395 2396 if (nextn < 1000) 2397 nextn += (nextn+5); 2398 else 2399 nextn = 1000; 2400 2384 2401 camel_operation_start (NULL, _("Fetching summary information for new messages in %s"), folder->name); 2385 2402 2386 2403 /* Parse the responses. We can't add a message to the summary 2387 2404 * until we've gotten its headers, and there's no guarantee 2388 2405 * the server will send the responses in a useful order... 2389 2406 */ 2407 2390 2408 fetch_data = g_ptr_array_new (); 2391 2409 messages = g_ptr_array_new (); 2392 2410 while ((type = camel_imap_command_response (store, &resp, ex)) == 2393 CAMEL_IMAP_RESPONSE_UNTAGGED) { 2411 CAMEL_IMAP_RESPONSE_UNTAGGED) 2412 { 2413 more = TRUE; 2394 2414 data = parse_fetch_response (imap_folder, resp); 2395 2415 g_free (resp); 2416 2396 2417 if (!data) 2397 2418 continue; … … 2402 2423 continue; 2403 2424 } 2404 2425 2405 2426 if (g_datalist_get_data (&data, "FLAGS")) 2406 2427 got += IMAP_PRETEND_SIZEOF_FLAGS; … … 2417 2438 g_datalist_set_data (&data, "BODY_PART_STREAM", NULL); 2418 2439 } 2419 2420 camel_operation_progress (NULL, got * 100 / size); 2440 2441 if (size > 0) 2442 camel_operation_progress (NULL, got * 100 / size); 2421 2443 g_ptr_array_add (fetch_data, data); 2422 2444 } 2423 2445 camel_operation_end (NULL); 2424 2446 2425 2447 if (type == CAMEL_IMAP_RESPONSE_ERROR) 2426 2448 goto lose; 2427 2449 2428 2450 /* Free the final tagged response */ 2429 2451 g_free (resp); 2430 2452 2431 2453 /* Figure out which headers we still need to fetch. */ 2432 2454 needheaders = g_ptr_array_new (); 2433 2455 size = got = 0; 2434 for (i = 0; i < fetch_data->len; i++) { 2456 for (i = 0; i < fetch_data->len; i++) 2457 { 2435 2458 data = fetch_data->pdata[i]; 2436 2459 if (g_datalist_get_data (&data, "BODY_PART_LEN")) 2437 2460 continue; 2438 2461 2439 2462 uid = g_datalist_get_data (&data, "UID"); 2440 2463 if (uid) { … … 2443 2466 } 2444 2467 } 2445 2468 2446 2469 /* And fetch them */ 2447 if (needheaders->len) { 2470 if (needheaders->len) 2471 { 2448 2472 char *uidset; 2449 2473 int uid = 0; 2450 2474 2451 2475 qsort (needheaders->pdata, needheaders->len, 2452 sizeof (void *), uid_compar);2453 2476 sizeof (void *), uid_compar); 2477 2454 2478 camel_operation_start (NULL, _("Fetching summary information for new messages in %s"), folder->name); 2455 2456 2479 while (uid < needheaders->len) { 2457 2480 uidset = imap_uid_array_to_set (folder->summary, needheaders, uid, UID_SET_LIMIT, &uid); … … 2465 2488 } 2466 2489 g_free (uidset); 2467 2490 2468 2491 while ((type = camel_imap_command_response (store, &resp, ex)) 2469 2492 == CAMEL_IMAP_RESPONSE_UNTAGGED) { … … 2477 2500 add_message_from_data (folder, messages, first, data); 2478 2501 got += IMAP_PRETEND_SIZEOF_HEADERS; 2479 camel_operation_progress (NULL, got * 100 / size); 2502 if (size > 0) 2503 camel_operation_progress (NULL, got * 100 / size); 2480 2504 } 2481 2505 g_datalist_clear (&data); … … 2488 2512 } 2489 2513 } 2490 2491 2514 g_ptr_array_free (needheaders, TRUE); 2492 2515 camel_operation_end (NULL); 2493 2516 } 2494 2517 2495 2518 /* Now finish up summary entries (fix UIDs, set flags and size) */ 2496 2519 for (i = 0; i < fetch_data->len; i++) { 2497 2520 data = fetch_data->pdata[i]; 2498 2521 2499 2522 seq = GPOINTER_TO_INT (g_datalist_get_data (&data, "SEQUENCE")); 2500 2523 if (seq >= first + messages->len) { … … 2502 2525 continue; 2503 2526 } 2504 2527 2505 2528 mi = messages->pdata[seq - first]; 2506 2529 if (mi == NULL) { 2507 2530 CamelMessageInfo *pmi = NULL; 2508 2531 int j; 2509 2532 2510 2533 /* This is a kludge around a bug in Exchange 2511 2534 * 5.5 that sometimes claims multiple messages … … 2524 2547 break; 2525 2548 } 2526 2549 2527 2550 if (pmi == NULL) { 2528 2551 /* Server response is *really* fucked up, … … 2533 2556 mi = (CamelImapMessageInfo *)camel_message_info_clone(pmi); 2534 2557 } 2535 2558 2536 2559 uid = g_datalist_get_data (&data, "UID"); 2537 2538 /* This strdup() might not get freed since the mmap() patch! */ 2539 if (uid) 2560 if (uid) { 2540 2561 mi->info.uid = g_strdup (uid); 2562 mi->info.uid_needs_free = TRUE; 2563 } 2541 2564 2542 2565 flags = GPOINTER_TO_INT (g_datalist_get_data (&data, "FLAGS")); … … 2549 2572 flags_to_label(folder, mi); 2550 2573 } 2551 2574 2552 2575 #ifdef NON_TINYMAIL_FEATURES 2553 2576 size = GPOINTER_TO_INT (g_datalist_get_data (&data, "RFC822.SIZE")); … … 2555 2578 mi->info.size = size; 2556 2579 #endif 2580 2557 2581 g_datalist_clear (&data); 2558 2582 } 2559 2583 g_ptr_array_free (fetch_data, TRUE); 2560 2584 2561 2585 /* And add the entries to the summary, etc. */ 2562 for (i = 0; i < messages->len; i++) { 2586 for (i = 0; i < messages->len; i++) 2587 { 2588 2563 2589 mi = messages->pdata[i]; 2564 2590 if (!mi) { 2565 g_warning ("No information for message %d", i + first);2591 /* g_warning ("No information for message %d", i + first); 2566 2592 camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, 2567 2593 _("Incomplete server response: no information provided for message %d"), 2568 i + first); 2569 break; 2570 } 2594 i + first); */ 2595 continue; 2596 } 2597 2571 2598 uid = (char *)camel_message_info_uid(mi); 2572 2599 if (uid[0] == 0) { … … 2577 2604 break; 2578 2605 } 2606 2579 2607 info = (CamelImapMessageInfo *)camel_folder_summary_uid(folder->summary, uid); 2580 2608 if (info) { … … 2592 2620 break; 2593 2621 } 2594 2622 2595 2623 camel_folder_summary_add (folder->summary, (CamelMessageInfo *)mi); 2596 2624 camel_folder_change_info_add_uid (changes, camel_message_info_uid (mi)); 2597 2625 2598 2626 if ((mi->info.flags & CAMEL_IMAP_MESSAGE_RECENT)) 2599 2627 camel_folder_change_info_recent_uid(changes, camel_message_info_uid (mi)); 2600 2628 } 2629 2630 /* Dumping each nextn'th header (this is needed for the nextn calc to 2631 be correct), it *must* write the summary cache to disk! */ 2632 2633 camel_folder_summary_dump_mmap (folder->summary); 2601 2634 2602 2635 for ( ; i < messages->len; i++) { … … 2604 2637 camel_message_info_free(&mi->info); 2605 2638 } 2606 2607 2639 g_ptr_array_free (messages, TRUE); 2608 2609 return;2610 2640 2641 goto endbmore; 2642 2611 2643 lose: 2612 2644 if (fetch_data) { … … 2624 2656 g_ptr_array_free (messages, TRUE); 2625 2657 } 2658 2659 endbmore: 2660 count = 0; 2661 } /* more */ 2626 2662 } 2627 2663 trunk/libtinymail-camel/camel-lite/camel/providers/nntp/camel-nntp-summary.c
r1042 r1048 220 220 char *line, *tab; 221 221 int len, ret; 222 unsigned int n, count, total, size ;222 unsigned int n, count, total, size, acnt=0; 223 223 struct _xover_header *xover; 224 224 … … 282 282 mi = (CamelMessageInfoBase *)camel_folder_summary_uid(s, cns->priv->uid); 283 283 if (mi == NULL) { 284 285 if (acnt > 1000) { 286 camel_folder_summary_dump_mmap (s); 287 acnt = 0; 288 } 289 acnt++; 284 290 mi = (CamelMessageInfoBase *)camel_folder_summary_add_from_header(s, headers); 285 291 if (mi) { … … 315 321 int ret = -1; 316 322 char *line, *msgid; 317 unsigned int i, n, count, total ;323 unsigned int i, n, count, total, acnt=0; 318 324 CamelMessageInfo *mi; 319 325 CamelMimeParser *mp; … … 349 355 line[1] = 0; 350 356 cns->priv->uid = g_strdup_printf("%u,%s\n", n, msgid); 357 351 358 mi = camel_folder_summary_uid(s, cns->priv->uid); 352 359 if (mi == NULL) { 353 360 if (camel_mime_parser_init_with_stream(mp, (CamelStream *)store->stream) == -1) 354 361 goto error; 362 if (acnt > 1000) { 363 camel_folder_summary_dump_mmap (s); 364 acnt = 0; 365 } 366 acnt++; 355 367 mi = camel_folder_summary_add_from_parser(s, mp); 356 368 while (camel_mime_parser_step(mp, NULL, NULL) != CAMEL_MIME_PARSER_STATE_EOF) trunk/libtinymail-gnome-desktop/tny-gnome-device-priv.h
r879 r1048 28 28 29 29 #ifdef GNOME 30 gboolean invnm; 30 31 guint callback_id; 31 32 libnm_glib_ctx *nm_ctx; trunk/libtinymail-gnome-desktop/tny-gnome-device.c
r900 r1048 58 58 priv->fset = FALSE; 59 59 priv->forced = FALSE; 60 60 61 61 #ifdef GNOME 62 62 nm_callback (priv->nm_ctx, self); … … 75 75 nm_callback (priv->nm_ctx, self); 76 76 #endif 77 77 78 78 return; 79 79 } … … 89 89 90 90 #ifdef GNOME 91 nm_callback (priv->nm_ctx, self);92 #endif 93 91 nm_callback (priv->nm_ctx, self); 92 #endif 93 94 94 return; 95 95 } … … 118 118 119 119 #ifdef GNOME 120 if (!priv->fset )120 if (!priv->fset && !priv->invnm) 121 121 { 122 122 libnm_glib_state state = libnm_glib_get_network_state (priv->nm_ctx); … … 124 124 switch (state) 125 125 { 126 case LIBNM_ NO_NETWORK_CONNECTION:127 retval = FALSE;126 case LIBNM_ACTIVE_NETWORK_CONNECTION: 127 retval = TRUE; 128 128 break; 129 129 … … 131 131 case LIBNM_NO_NETWORKMANAGER: 132 132 case LIBNM_INVALID_CONTEXT: 133 g_print (_("Invalid network manager installation. Going to assume Online status\n")); 134 case LIBNM_ACTIVE_NETWORK_CONNECTION: 133 g_print (_("Invalid network manager installation. Going to assume Offline status\n")); 134 priv->invnm = TRUE; 135 case LIBNM_NO_NETWORK_CONNECTION: 135 136 default: 136 retval = TRUE;137 retval = FALSE; 137 138 break; 138 139 } 139 140 } 140 141 #endif 141 142 142 143 return retval; 143 144 } … … 150 151 TnyGnomeDevicePriv *priv = TNY_GNOME_DEVICE_GET_PRIVATE (self); 151 152 153 priv->invnm = FALSE; 152 154 priv->fset = FALSE; 153 155 priv->forced = FALSE; … … 157 159 priv->callback_id = libnm_glib_register_callback 158 160 (priv->nm_ctx, nm_callback, self, NULL); 159 160 #endif 161 161 #endif 162 162 163 return; 163 164 }
