1
0
mirror of https://github.com/moparisthebest/k-9 synced 2025-01-30 23:00:09 -05:00

Optimization: extracted populate() outside MessageInfoHolder in order to properly cache DateFormat (avoid useless DateFormat costly lookup at each population)

This commit is contained in:
Fiouz 2010-10-03 10:56:16 +00:00
parent 9347409e14
commit f1d413ce77
4 changed files with 188 additions and 135 deletions

View File

@ -1,22 +1,7 @@
package com.fsck.k9.activity; package com.fsck.k9.activity;
import java.util.Date; import java.util.Date;
import android.content.Context;
import android.text.SpannableStringBuilder;
import android.util.Config;
import android.util.Log;
import com.fsck.k9.Account;
import com.fsck.k9.K9;
import com.fsck.k9.R;
import com.fsck.k9.helper.Contacts;
import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.Address;
import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Message; import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Message.RecipientType;
import com.fsck.k9.mail.store.LocalStore.LocalMessage;
public class MessageInfoHolder public class MessageInfoHolder
{ {
@ -49,97 +34,6 @@ public class MessageInfoHolder
this.selected = false; this.selected = false;
} }
public MessageInfoHolder(Context context, Message m)
{
this();
Account account = m.getFolder().getAccount();
populate(context, m, new FolderInfoHolder(context, m.getFolder(), m.getFolder().getAccount()), account);
}
public MessageInfoHolder(Context context, Message m, FolderInfoHolder folder, Account account)
{
this();
populate(context, m, folder, account);
}
public void populate(Context context, Message m, FolderInfoHolder folder, Account account)
{
final Contacts contactHelper = Contacts.getInstance(context);
try
{
LocalMessage message = (LocalMessage) m;
Date date = message.getSentDate();
this.compareDate = message.getSentDate();
if (this.compareDate == null)
{
this.compareDate = message.getInternalDate();
}
this.folder = folder;
if (Utility.isDateToday(date))
{
this.date = android.text.format.DateFormat.getTimeFormat(context).format(date);
}
else
{
this.date = DateFormatter.getDateFormat(context).format(date);
}
this.hasAttachments = message.getAttachmentCount() > 0;
this.read = message.isSet(Flag.SEEN);
this.answered = message.isSet(Flag.ANSWERED);
this.flagged = message.isSet(Flag.FLAGGED);
this.downloaded = message.isSet(Flag.X_DOWNLOADED_FULL);
this.partially_downloaded = message.isSet(Flag.X_DOWNLOADED_PARTIAL);
Address[] addrs = message.getFrom();
if (addrs.length > 0 && account.isAnIdentity(addrs[0]))
{
CharSequence to = Address.toFriendly(message .getRecipients(RecipientType.TO), contactHelper);
this.compareCounterparty = to.toString();
this.sender = new SpannableStringBuilder(context.getString(R.string.message_list_to_fmt)).append(to);
}
else
{
this.sender = Address.toFriendly(addrs, contactHelper);
this.compareCounterparty = this.sender.toString();
}
if (addrs.length > 0)
{
this.senderAddress = addrs[0].getAddress();
}
else
{
// a reasonable fallback "whomever we were corresponding with
this.senderAddress = this.compareCounterparty;
}
this.subject = message.getSubject();
this.uid = message.getUid();
this.message = m;
this.preview = message.getPreview();
this.fullDate = DateFormatter.getDateFormat(context).format(date)+" "+android.text.format.DateFormat.getTimeFormat(context).format(date);
this.account = account.getDescription();
this.uri = "email://messages/"+account.getAccountNumber()+"/"+m.getFolder().getName()+"/"+m.getUid();
}
catch (MessagingException me)
{
if (Config.LOGV)
{
Log.v(K9.LOG_TAG, "Unable to load message info", me);
}
}
}
@Override @Override
public boolean equals(Object o) public boolean equals(Object o)
{ {

View File

@ -60,6 +60,7 @@ import com.fsck.k9.activity.setup.Prefs;
import com.fsck.k9.controller.MessagingController; import com.fsck.k9.controller.MessagingController;
import com.fsck.k9.controller.MessagingListener; import com.fsck.k9.controller.MessagingListener;
import com.fsck.k9.controller.MessagingController.SORT_TYPE; import com.fsck.k9.controller.MessagingController.SORT_TYPE;
import com.fsck.k9.helper.MessageHelper;
import com.fsck.k9.helper.Utility; import com.fsck.k9.helper.Utility;
import com.fsck.k9.mail.Flag; import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Folder; import com.fsck.k9.mail.Folder;
@ -317,6 +318,8 @@ public class MessageList
private Context context = null; private Context context = null;
/* package visibility for faster inner class access */ MessageHelper mMessageHelper = MessageHelper.getInstance(this);
class MessageListHandler class MessageListHandler
{ {
public void removeMessage(final List<MessageInfoHolder> messages) public void removeMessage(final List<MessageInfoHolder> messages)
@ -2262,14 +2265,14 @@ public class MessageList
removeMessages(messages); removeMessages(messages);
} }
private void addOrUpdateMessage(Account account, String folder, Message message, boolean verifyAgainstSearch) private void addOrUpdateMessage(Account account, String folderName, Message message, boolean verifyAgainstSearch)
{ {
List<Message> messages = new ArrayList<Message>(); List<Message> messages = new ArrayList<Message>();
messages.add(message); messages.add(message);
addOrUpdateMessages(account, folder, messages, verifyAgainstSearch); addOrUpdateMessages(account, folderName, messages, verifyAgainstSearch);
} }
private void addOrUpdateMessages(final Account account, final String folder, final List<Message> providedMessages, final boolean verifyAgainstSearch) private void addOrUpdateMessages(final Account account, final String folderName, final List<Message> providedMessages, final boolean verifyAgainstSearch)
{ {
// we copy the message list because the callback doesn't expect // we copy the message list because the callback doesn't expect
// the callbacks to mutate it. // the callbacks to mutate it.
@ -2284,6 +2287,9 @@ public class MessageList
List<MessageInfoHolder> messagesToRemove = new ArrayList<MessageInfoHolder>(); List<MessageInfoHolder> messagesToRemove = new ArrayList<MessageInfoHolder>();
List<Message> messagesToSearch = new ArrayList<Message>(); List<Message> messagesToSearch = new ArrayList<Message>();
// cache field into local variable for faster access for JVM without JIT
final MessageHelper messageHelper = mMessageHelper;
for (Message message : messages) for (Message message : messages)
{ {
MessageInfoHolder m = getMessage(message); MessageInfoHolder m = getMessage(message);
@ -2294,33 +2300,40 @@ public class MessageList
messagesToRemove.add(m); messagesToRemove.add(m);
} }
} }
else if (m == null) else
{ {
if (updateForMe(account, folder)) final Folder messageFolder = message.getFolder();
final Account messageAccount = messageFolder.getAccount();
if (m == null)
{ {
m = new MessageInfoHolder(context, message); if (updateForMe(account, folderName))
messagesToAdd.add(m);
}
else
{
if (mQueryString != null)
{ {
if (verifyAgainstSearch) m = new MessageInfoHolder();
messageHelper.populate(m, message, new FolderInfoHolder(MessageList.this, messageFolder, messageAccount), messageAccount);
messagesToAdd.add(m);
}
else
{
if (mQueryString != null)
{ {
messagesToSearch.add(message); if (verifyAgainstSearch)
} {
else messagesToSearch.add(message);
{ }
m = new MessageInfoHolder(context, message); else
messagesToAdd.add(m); {
m = new MessageInfoHolder();
messageHelper.populate(m, message, new FolderInfoHolder(MessageList.this, messageFolder, messageAccount), messageAccount);
messagesToAdd.add(m);
}
} }
} }
} }
} else
else {
{ messageHelper.populate(m, message, new FolderInfoHolder(MessageList.this, messageFolder, account), account);
m.populate(context, message, new FolderInfoHolder(context, message.getFolder(), account), account); needsSort = true;
needsSort = true; }
} }
} }

View File

@ -0,0 +1,126 @@
package com.fsck.k9.helper;
import java.text.DateFormat;
import java.util.Date;
import android.content.Context;
import android.text.SpannableStringBuilder;
import android.util.Log;
import com.fsck.k9.Account;
import com.fsck.k9.K9;
import com.fsck.k9.R;
import com.fsck.k9.activity.DateFormatter;
import com.fsck.k9.activity.FolderInfoHolder;
import com.fsck.k9.activity.MessageInfoHolder;
import com.fsck.k9.mail.Address;
import com.fsck.k9.mail.Flag;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.Message.RecipientType;
import com.fsck.k9.mail.store.LocalStore.LocalMessage;
public class MessageHelper
{
private static MessageHelper sInstance;
public synchronized static MessageHelper getInstance(final Context context)
{
if (sInstance == null)
{
sInstance = new MessageHelper(context);
}
return sInstance;
}
private Context mContext;
private DateFormat mTodayDateFormat;
private DateFormat mDateFormat;
private DateFormat mTimeFormat;
private MessageHelper(final Context context)
{
mContext = context;
mDateFormat = DateFormatter.getDateFormat(mContext);
mTimeFormat = android.text.format.DateFormat.getTimeFormat(mContext);
mTodayDateFormat = android.text.format.DateFormat.getTimeFormat(mContext);
}
public void populate(final MessageInfoHolder target, final Message m,
final FolderInfoHolder folder, final Account account)
{
final Contacts contactHelper = Contacts.getInstance(mContext);
try
{
LocalMessage message = (LocalMessage) m;
Date date = message.getSentDate();
target.compareDate = message.getSentDate();
if (target.compareDate == null)
{
target.compareDate = message.getInternalDate();
}
target.folder = folder;
if (Utility.isDateToday(date))
{
target.date = mTodayDateFormat.format(date);
}
else
{
target.date = mDateFormat.format(date);
}
target.hasAttachments = message.getAttachmentCount() > 0;
target.read = message.isSet(Flag.SEEN);
target.answered = message.isSet(Flag.ANSWERED);
target.flagged = message.isSet(Flag.FLAGGED);
target.downloaded = message.isSet(Flag.X_DOWNLOADED_FULL);
target.partially_downloaded = message.isSet(Flag.X_DOWNLOADED_PARTIAL);
Address[] addrs = message.getFrom();
if (addrs.length > 0 && account.isAnIdentity(addrs[0]))
{
CharSequence to = Address.toFriendly(message .getRecipients(RecipientType.TO), contactHelper);
target.compareCounterparty = to.toString();
target.sender = new SpannableStringBuilder(mContext.getString(R.string.message_list_to_fmt)).append(to);
}
else
{
target.sender = Address.toFriendly(addrs, contactHelper);
target.compareCounterparty = target.sender.toString();
}
if (addrs.length > 0)
{
target.senderAddress = addrs[0].getAddress();
}
else
{
// a reasonable fallback "whomever we were corresponding with
target.senderAddress = target.compareCounterparty;
}
target.subject = message.getSubject();
target.uid = message.getUid();
target.message = m;
target.preview = message.getPreview();
target.fullDate = mDateFormat.format(date) + " " + mTimeFormat.format(date);
target.account = account.getDescription();
target.uri = "email://messages/" + account.getAccountNumber() + "/" + m.getFolder().getName() + "/" + m.getUid();
}
catch (MessagingException me)
{
Log.w(K9.LOG_TAG, "Unable to load message info", me);
}
}
}

View File

@ -8,6 +8,7 @@ import java.util.concurrent.SynchronousQueue;
import android.content.ContentProvider; import android.content.ContentProvider;
import android.content.ContentValues; import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher; import android.content.UriMatcher;
import android.database.Cursor; import android.database.Cursor;
import android.database.MatrixCursor; import android.database.MatrixCursor;
@ -19,10 +20,12 @@ import com.fsck.k9.AccountStats;
import com.fsck.k9.K9; import com.fsck.k9.K9;
import com.fsck.k9.Preferences; import com.fsck.k9.Preferences;
import com.fsck.k9.SearchAccount; import com.fsck.k9.SearchAccount;
import com.fsck.k9.activity.FolderInfoHolder;
import com.fsck.k9.activity.MessageInfoHolder; import com.fsck.k9.activity.MessageInfoHolder;
import com.fsck.k9.activity.MessageList; import com.fsck.k9.activity.MessageList;
import com.fsck.k9.controller.MessagingController; import com.fsck.k9.controller.MessagingController;
import com.fsck.k9.controller.MessagingListener; import com.fsck.k9.controller.MessagingListener;
import com.fsck.k9.helper.MessageHelper;
import com.fsck.k9.mail.Folder; import com.fsck.k9.mail.Folder;
import com.fsck.k9.mail.Message; import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException; import com.fsck.k9.mail.MessagingException;
@ -229,25 +232,38 @@ public class MessageProvider extends ContentProvider
{ {
private final BlockingQueue<List<MessageInfoHolder>> queue; private final BlockingQueue<List<MessageInfoHolder>> queue;
private List<MessageInfoHolder> holders = new ArrayList<MessageInfoHolder>(); private List<MessageInfoHolder> mHolders = new ArrayList<MessageInfoHolder>();
/** /**
* @param queue * @param queue
* Never <code>null</code>. The synchronized channel to use * Never <code>null</code>. The synchronized channel to use
* to retrieve {@link MessageInfoHolder}s. * to retrieve {@link MessageInfoHolder}s.
*/ */
public MesssageInfoHolderRetrieverListener(BlockingQueue<List<MessageInfoHolder>> queue) public MesssageInfoHolderRetrieverListener(final BlockingQueue<List<MessageInfoHolder>> queue)
{ {
this.queue = queue; this.queue = queue;
} }
@Override @Override
public void listLocalMessagesAddMessages(Account account, public void listLocalMessagesAddMessages(final Account account,
String folder, List<Message> messages) final String folderName, final List<Message> messages)
{ {
// cache fields into local variables for faster access on JVM without JIT
final MessageHelper helper = mMessageHelper;
final List<MessageInfoHolder> holders = mHolders;
final Context context = getContext();
for (final Message message : messages) for (final Message message : messages)
{ {
holders.add(new MessageInfoHolder(getContext(), message)); final MessageInfoHolder messageInfoHolder = new MessageInfoHolder();
final Folder messageFolder = message.getFolder();
final Account messageAccount = messageFolder.getAccount();
helper.populate(messageInfoHolder, message, new FolderInfoHolder(context,
messageFolder, messageAccount), messageAccount);
holders.add(messageInfoHolder);
} }
} }
@ -256,7 +272,7 @@ public class MessageProvider extends ContentProvider
{ {
try try
{ {
queue.put(holders); queue.put(mHolders);
} }
catch (InterruptedException e) catch (InterruptedException e)
{ {
@ -293,9 +309,13 @@ public class MessageProvider extends ContentProvider
*/ */
private List<QueryHandler> mQueryHandlers = new ArrayList<QueryHandler>(); private List<QueryHandler> mQueryHandlers = new ArrayList<QueryHandler>();
private MessageHelper mMessageHelper;
@Override @Override
public boolean onCreate() public boolean onCreate()
{ {
mMessageHelper = MessageHelper.getInstance(getContext());
registerQueryHandler(new AccountsQueryHandler()); registerQueryHandler(new AccountsQueryHandler());
registerQueryHandler(new MessagesQueryHandler()); registerQueryHandler(new MessagesQueryHandler());
registerQueryHandler(new UnreadQueryHandler()); registerQueryHandler(new UnreadQueryHandler());