forked from I2P_Developers/i2p.i2p
Merge branch 'susimail-loading' into 'master'
Susimail: Speed up initial loading by 35x See merge request i2p-hackers/i2p.i2p!162
This commit is contained in:
@@ -48,6 +48,7 @@ import java.util.Set;
|
|||||||
import net.i2p.I2PAppContext;
|
import net.i2p.I2PAppContext;
|
||||||
import net.i2p.app.ClientAppManager;
|
import net.i2p.app.ClientAppManager;
|
||||||
import net.i2p.app.NotificationService;
|
import net.i2p.app.NotificationService;
|
||||||
|
import net.i2p.data.Base64;
|
||||||
import net.i2p.util.FileUtil;
|
import net.i2p.util.FileUtil;
|
||||||
import net.i2p.util.I2PAppThread;
|
import net.i2p.util.I2PAppThread;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
@@ -61,7 +62,7 @@ import net.i2p.util.Log;
|
|||||||
class MailCache {
|
class MailCache {
|
||||||
|
|
||||||
public enum FetchMode {
|
public enum FetchMode {
|
||||||
HEADER, ALL, CACHE_ONLY
|
HEADER, ALL, CACHE_ONLY, HEADER_CACHE_ONLY
|
||||||
}
|
}
|
||||||
|
|
||||||
private final POP3MailBox mailbox;
|
private final POP3MailBox mailbox;
|
||||||
@@ -326,12 +327,12 @@ class MailCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch any needed data from pop3 server, unless mode is CACHE_ONLY,
|
* Fetch any needed data from pop3 server, unless mode is CACHE_ONLY or HEADER_CACHE_ONLY,
|
||||||
* or this isn't the Inbox.
|
* or this isn't the Inbox.
|
||||||
* Blocking unless mode is CACHE_ONLY.
|
* Blocking for a long time unless mode is CACHE_ONLY or HEADER_CACHE_ONLY.
|
||||||
*
|
*
|
||||||
* @param uidl message id to get
|
* @param uidl message id to get
|
||||||
* @param mode CACHE_ONLY to not pull from pop server
|
* @param mode CACHE_ONLY or HEADER_CACHE_ONLY to not pull from pop server
|
||||||
* @return An e-mail or null
|
* @return An e-mail or null
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
@@ -368,12 +369,35 @@ class MailCache {
|
|||||||
|
|
||||||
if (mode == FetchMode.HEADER) {
|
if (mode == FetchMode.HEADER) {
|
||||||
if (!mail.hasHeader()) {
|
if (!mail.hasHeader()) {
|
||||||
|
if (_log.shouldInfo()) _log.info("Fetching mail header from server for b64: " + Base64.encode(uidl));
|
||||||
Buffer buf = mailbox.getHeader(uidl);
|
Buffer buf = mailbox.getHeader(uidl);
|
||||||
if (buf != null)
|
if (buf != null)
|
||||||
mail.setHeader(buf);
|
mail.setHeader(buf);
|
||||||
}
|
}
|
||||||
} else if (mode == FetchMode.ALL) {
|
} else if (mode == FetchMode.HEADER_CACHE_ONLY) {
|
||||||
if(!mail.hasBody()) {
|
if (!mail.hasHeader()) {
|
||||||
|
// shouldn't happen
|
||||||
|
if (disk.getMail(mail, true)) {
|
||||||
|
if (_log.shouldWarn()) _log.warn("Loaded deferred header from disk cache for b64: " + Base64.encode(uidl));
|
||||||
|
return mail;
|
||||||
|
} else {
|
||||||
|
if (_log.shouldWarn()) _log.warn("Failed to load deferred header from disk cache for b64: " + Base64.encode(uidl));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!mail.hasBody()) {
|
||||||
|
// CACHE_ONLY or ALL
|
||||||
|
if (disk.getFullFile(uidl).exists()) {
|
||||||
|
// body was not loaded at startup but we have it, load it now
|
||||||
|
if (disk.getMail(mail, false)) {
|
||||||
|
if (_log.shouldDebug()) _log.debug("Loaded deferred body from disk cache for b64: " + Base64.encode(uidl));
|
||||||
|
return mail;
|
||||||
|
}
|
||||||
|
if (_log.shouldWarn()) _log.warn("Failed to load deferred body from disk cache for b64: " + Base64.encode(uidl));
|
||||||
|
} else {
|
||||||
|
if (_log.shouldWarn()) _log.warn("We do not have body in disk cache for b64: " + Base64.encode(uidl));
|
||||||
|
}
|
||||||
|
if (mode == FetchMode.ALL) {
|
||||||
|
if (_log.shouldInfo()) _log.info("Fetching mail body from server for b64: " + Base64.encode(uidl));
|
||||||
File file = new File(_context.getTempDir(), "susimail-new-" + _context.random().nextLong());
|
File file = new File(_context.getTempDir(), "susimail-new-" + _context.random().nextLong());
|
||||||
Buffer rb = mailbox.getBody(uidl, new FileBuffer(file));
|
Buffer rb = mailbox.getBody(uidl, new FileBuffer(file));
|
||||||
if (rb != null) {
|
if (rb != null) {
|
||||||
@@ -384,8 +408,6 @@ class MailCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// else if it wasn't in cache, too bad
|
|
||||||
}
|
}
|
||||||
return mail;
|
return mail;
|
||||||
}
|
}
|
||||||
@@ -405,7 +427,7 @@ class MailCache {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
public boolean getMail(FetchMode mode) {
|
public boolean getMail(FetchMode mode) {
|
||||||
if (mode == FetchMode.CACHE_ONLY)
|
if (mode == FetchMode.CACHE_ONLY || mode == FetchMode.HEADER_CACHE_ONLY)
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
if (mailbox == null) {
|
if (mailbox == null) {
|
||||||
if (_log.shouldDebug()) _log.debug("getMail() mode " + mode + " called on wrong folder " + getFolderName(), new Exception());
|
if (_log.shouldDebug()) _log.debug("getMail() mode " + mode + " called on wrong folder " + getFolderName(), new Exception());
|
||||||
|
|||||||
@@ -462,10 +462,26 @@ class PersistentMailCache {
|
|||||||
mail = new Draft(uidl);
|
mail = new Draft(uidl);
|
||||||
else
|
else
|
||||||
mail = new Mail(uidl);
|
mail = new Mail(uidl);
|
||||||
if (headerOnly)
|
if (headerOnly) {
|
||||||
mail.setHeader(rb);
|
mail.setHeader(rb);
|
||||||
else
|
} else if (isDrafts) {
|
||||||
|
// drafts always have FULL_SUFFIX but
|
||||||
|
// may not actually have a real body or part.
|
||||||
|
// If we don't call setBody(), it has
|
||||||
|
// a null part and we NPE on the compose page.
|
||||||
|
// Attachments are stored in separate files so
|
||||||
|
// these are all small.
|
||||||
mail.setBody(rb);
|
mail.setBody(rb);
|
||||||
|
} else {
|
||||||
|
// Deferred loading, body will be loaded
|
||||||
|
// on-demand in MailCache.getMail()
|
||||||
|
// We set the size of the gzipped file to be the
|
||||||
|
// size so the UI doesn't have ?? in it.
|
||||||
|
// The size will be corrected if and when the body is read.
|
||||||
|
//mail.setBody(rb);
|
||||||
|
mail.setHeader(rb);
|
||||||
|
mail.setSize(f.length());
|
||||||
|
}
|
||||||
return mail;
|
return mail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ class Sorters {
|
|||||||
* Gets mail from the cache, checks for null, then compares
|
* Gets mail from the cache, checks for null, then compares
|
||||||
*/
|
*/
|
||||||
public int compare(String arg0, String arg1) {
|
public int compare(String arg0, String arg1) {
|
||||||
Mail a = mailCache.getMail( arg0, MailCache.FetchMode.CACHE_ONLY );
|
Mail a = mailCache.getMail(arg0, MailCache.FetchMode.HEADER_CACHE_ONLY);
|
||||||
Mail b = mailCache.getMail( arg1, MailCache.FetchMode.CACHE_ONLY );
|
Mail b = mailCache.getMail(arg1, MailCache.FetchMode.HEADER_CACHE_ONLY);
|
||||||
if (a == null)
|
if (a == null)
|
||||||
return (b == null) ? 0 : 1;
|
return (b == null) ? 0 : 1;
|
||||||
if (b == null)
|
if (b == null)
|
||||||
|
|||||||
@@ -2328,7 +2328,7 @@ public class WebMail extends HttpServlet
|
|||||||
if (state == State.LIST) {
|
if (state == State.LIST) {
|
||||||
for (Iterator<String> it = folder.currentPageIterator(); it != null && it.hasNext(); ) {
|
for (Iterator<String> it = folder.currentPageIterator(); it != null && it.hasNext(); ) {
|
||||||
String uidl = it.next();
|
String uidl = it.next();
|
||||||
Mail mail = mc.getMail(uidl, MailCache.FetchMode.HEADER);
|
Mail mail = mc.getMail(uidl, MailCache.FetchMode.HEADER_CACHE_ONLY);
|
||||||
if( mail != null && mail.error.length() > 0 ) {
|
if( mail != null && mail.error.length() > 0 ) {
|
||||||
sessionObject.error += mail.error;
|
sessionObject.error += mail.error;
|
||||||
mail.error = "";
|
mail.error = "";
|
||||||
@@ -3300,7 +3300,7 @@ public class WebMail extends HttpServlet
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
for (Iterator<String> it = folder.currentPageIterator(); it != null && it.hasNext(); ) {
|
for (Iterator<String> it = folder.currentPageIterator(); it != null && it.hasNext(); ) {
|
||||||
String uidl = it.next();
|
String uidl = it.next();
|
||||||
Mail mail = mc.getMail(uidl, MailCache.FetchMode.CACHE_ONLY);
|
Mail mail = mc.getMail(uidl, MailCache.FetchMode.HEADER_CACHE_ONLY);
|
||||||
if (mail == null || !mail.hasHeader()) {
|
if (mail == null || !mail.hasHeader()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user