From e67a3d89165b92bda3d7fa01363c3b0c30aae635 Mon Sep 17 00:00:00 2001 From: Lyubomir Marinov Date: Tue, 6 Oct 2009 16:14:56 +0000 Subject: [PATCH] Speeds up the processing of smileys and thus the display of messages for both chat and history. Local testing of normal chat use for a couple of days with the profiler attached, show it's very-roughly 5 times faster than before. Profiler aside, the speed-up is more likely to be seen/felt when receiving multiple messages in a row such as when connecting to an IRC server and when viewing history. --- .../gui/main/chat/ChatConversationPanel.java | 127 ++++++++++++----- .../gui/main/chat/SmileysSelectorBox.java | 6 +- .../main/contactlist/ContactListModel.java | 2 +- .../impl/gui/utils/ImageLoader.java | 130 ++++++++++-------- .../communicator/impl/gui/utils/Smiley.java | 40 ++---- 5 files changed, 181 insertions(+), 124 deletions(-) diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java index 8c47b7ef5..264d40305 100755 --- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java @@ -43,8 +43,8 @@ public class ChatConversationPanel MouseListener, ClipboardOwner { - private static final Logger logger = - Logger.getLogger(ChatConversationPanel.class); + private static final Logger logger + = Logger.getLogger(ChatConversationPanel.class); /** * The closing tag of the PLAINTEXT HTML element. @@ -69,6 +69,18 @@ public class ChatConversationPanel + "(\\b\\w+://[^\\s<>\"]+/*[?#]*(\\w+[&=;?]\\w+)*\\b)" // protocolURL + ")"); + /** + * The compiled Pattern which matches {@link #smileyStrings}. + */ + private static Pattern smileyPattern; + + /** + * The List of smiley strings which are matched by + * {@link #smileyPattern}. + */ + private static final java.util.List smileyStrings + = new ArrayList(); + private final JTextPane chatTextPane = new MyTextPane(); private final HTMLEditorKit editorKit; @@ -705,9 +717,7 @@ private String processSmileys(String message, String contentType) { String startPlainTextTag; String endPlainTextTag; - if (contentType == null - || contentType.equals(TEXT_CONTENT_TYPE) - || "".equals(contentType)) + if (!HTML_CONTENT_TYPE.equals(contentType)) { startPlainTextTag = START_PLAINTEXT_TAG; endPlainTextTag = END_PLAINTEXT_TAG; @@ -718,44 +728,99 @@ private String processSmileys(String message, String contentType) endPlainTextTag = ""; } - Collection smileys = ImageLoader.getDefaultSmileysPack(); + Collection smileys = ImageLoader.getDefaultSmileyPack(); + Matcher m = getSmileyPattern(smileys).matcher(message); + StringBuffer msgBuffer = new StringBuffer(); + int prevEnd = 0; - StringBuffer regexp = new StringBuffer(); + while (m.find()) + { + msgBuffer.append(message.substring(prevEnd, m.start())); + prevEnd = m.end(); - regexp.append("(?"); + msgBuffer.append(startPlainTextTag); } - regexp = regexp.deleteCharAt(regexp.length() - 1); + msgBuffer.append(message.substring(prevEnd)); - regexp.append(')'); + return msgBuffer.toString(); + } - Pattern p = Pattern.compile(regexp.toString()); + /** + * Gets a compiled Pattern which matches the smiley strings of the + * specified Collection of Smileys. + * + * @param smileys the Collection of Smileys for which to + * get a compiled Pattern which matches its smiley strings + * @return a compiled Pattern which matches the smiley strings of + * the specified Collection of Smileys + */ + private static Pattern getSmileyPattern(Collection smileys) + { + synchronized (smileyStrings) + { + boolean smileyStringsIsEqual; - Matcher m = p.matcher(message); + if (smileyPattern == null) + smileyStringsIsEqual = false; + else + { + smileyStringsIsEqual = true; + + int smileyStringIndex = 0; + int smileyStringCount = smileyStrings.size(); + + smileyLoop: for (Smiley smiley : smileys) + for (String smileyString : smiley.getSmileyStrings()) + if ((smileyStringIndex < smileyStringCount) + && smileyString + .equals( + smileyStrings.get(smileyStringIndex))) + smileyStringIndex++; + else + { + smileyStringsIsEqual = false; + break smileyLoop; + } + if (smileyStringsIsEqual + && (smileyStringIndex != smileyStringCount)) + smileyStringsIsEqual = false; + } - StringBuffer msgBuffer = new StringBuffer(); + if (!smileyStringsIsEqual) + { + smileyStrings.clear(); - while (m.find()) - { - String matchGroup = m.group().trim(); + StringBuffer regex = new StringBuffer(); - String replacement = endPlainTextTag + "\""" + startPlainTextTag; + regex.append("(? imageList = ImageLoader.getDefaultSmileysPack(); + Collection imageList = ImageLoader.getDefaultSmileyPack(); Dimension gridDimensions = this.calculateGridDimensions(imageList.size()); diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListModel.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListModel.java index d92afe073..1b15b6498 100644 --- a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListModel.java +++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListModel.java @@ -112,7 +112,7 @@ public Object getElementAt(int index) /** * Goes through all subgroups and contacts and determines the final size of * the contact list. - *0 + * * @param group The group which to be measured. * @return The size of the contactlist */ diff --git a/src/net/java/sip/communicator/impl/gui/utils/ImageLoader.java b/src/net/java/sip/communicator/impl/gui/utils/ImageLoader.java index b60425289..22c82d551 100644 --- a/src/net/java/sip/communicator/impl/gui/utils/ImageLoader.java +++ b/src/net/java/sip/communicator/impl/gui/utils/ImageLoader.java @@ -30,7 +30,7 @@ */ public class ImageLoader { - private static final Logger log = Logger.getLogger(ImageLoader.class); + private static final Logger logger = Logger.getLogger(ImageLoader.class); /** * Stores all already loaded images. @@ -1138,77 +1138,97 @@ public class ImageLoader public static final ImageID SMILEY20 = new ImageID("service.gui.smileys.SMILEY20"); + /** + * The default pack of Smileys. + */ + private static Collection defaultSmileyPack; + /** * Load default smileys pack. * * @return the ArrayList of all smileys. */ - public static Collection getDefaultSmileysPack() + public static Collection getDefaultSmileyPack() { - List defaultPackList = new ArrayList(); - defaultPackList.add(new Smiley(ImageLoader.SMILEY1, - new String[] {":((", ":-((", ":((", ":(", ":-(", "(sad)"}, "Sad")); + /* + * In order to not use a separate sync root for defaultSmileyPack, use + * one of the constants it contains. + */ + synchronized (SMILEY1) + { + if (defaultSmileyPack != null) + return defaultSmileyPack; - defaultPackList.add(new Smiley(ImageLoader.SMILEY2, - new String[] {"(angel)" }, "Angel")); + List defaultSmileyList = new ArrayList(); - defaultPackList.add(new Smiley(ImageLoader.SMILEY3, - new String[] {":-*", ":*", "(kiss)"}, "Kiss")); + defaultSmileyList.add(new Smiley(SMILEY1, + new String[] {":((", ":-((", ":((", ":(", ":-(", "(sad)"}, + "Sad")); - defaultPackList.add(new Smiley(ImageLoader.SMILEY4, - new String[] {":-0", "(shocked)"}, "Shocked")); + defaultSmileyList.add(new Smiley(SMILEY2, + new String[] {"(angel)" }, "Angel")); - defaultPackList.add(new Smiley(ImageLoader.SMILEY5, - new String[] { ";-((", ";((", ";-(", ";(", ":'(", ":'-(", - ":~-(", ":~(", "(upset)" }, "Upset")); + defaultSmileyList.add(new Smiley(SMILEY3, + new String[] {":-*", ":*", "(kiss)"}, "Kiss")); - defaultPackList.add(new Smiley(ImageLoader.SMILEY6, - new String[] {"(L)" , "(l)", "(H)", "(h)"}, "In love")); + defaultSmileyList.add(new Smiley(SMILEY4, + new String[] {":-0", "(shocked)"}, "Shocked")); - defaultPackList.add(new Smiley(ImageLoader.SMILEY7, - new String[] {"(blush)"}, "Blushing")); + defaultSmileyList.add(new Smiley(SMILEY5, + new String[] { ";-((", ";((", ";-(", ";(", ":'(", ":'-(", + ":~-(", ":~(", "(upset)" }, "Upset")); - defaultPackList.add(new Smiley(ImageLoader.SMILEY8, - new String[] {":-P", ":P", ":-p", ":p" }, "Tongue out")); + defaultSmileyList.add(new Smiley(SMILEY6, + new String[] {"(L)" , "(l)", "(H)", "(h)"}, "In love")); - defaultPackList.add(new Smiley(ImageLoader.SMILEY9, - new String[] {":-))", ":))", ";-))", ";))", "(lol)"}, "Laughing")); + defaultSmileyList.add(new Smiley(SMILEY7, + new String[] {"(blush)"}, "Blushing")); - defaultPackList.add(new Smiley(ImageLoader.SMILEY10, - new String[] {"(y)", "(Y)", "(ok)"}, "Ok")); + defaultSmileyList.add(new Smiley(SMILEY8, + new String[] {":-P", ":P", ":-p", ":p" }, "Tongue out")); - defaultPackList.add(new Smiley(ImageLoader.SMILEY11, - new String[] {";-)", ";)", ":-)", ":)"}, "Smile")); + defaultSmileyList.add(new Smiley(SMILEY9, + new String[] {":-))", ":))", ";-))", ";))", "(lol)"}, + "Laughing")); - defaultPackList.add(new Smiley(ImageLoader.SMILEY12, - new String[] {"(sick)"}, "Sick")); + defaultSmileyList.add(new Smiley(SMILEY10, + new String[] {"(y)", "(Y)", "(ok)"}, "Ok")); - defaultPackList.add(new Smiley(ImageLoader.SMILEY13, - new String[] {"(n)", "(N)" }, "No")); + defaultSmileyList.add(new Smiley(SMILEY11, + new String[] {";-)", ";)", ":-)", ":)"}, "Smile")); - defaultPackList.add(new Smiley(ImageLoader.SMILEY14, - new String[] {"(chuckle)" }, "Chuckle")); + defaultSmileyList.add(new Smiley(SMILEY12, + new String[] {"(sick)"}, "Sick")); - defaultPackList.add(new Smiley(ImageLoader.SMILEY15, - new String[] {"(wave)" }, "Waving")); + defaultSmileyList.add(new Smiley(SMILEY13, + new String[] {"(n)", "(N)" }, "No")); - defaultPackList.add(new Smiley(ImageLoader.SMILEY16, - new String[] {"(clap)"}, "Clapping")); + defaultSmileyList.add(new Smiley(SMILEY14, + new String[] {"(chuckle)" }, "Chuckle")); - defaultPackList.add(new Smiley(ImageLoader.SMILEY17, - new String[] {"(angry)"}, "Angry")); + defaultSmileyList.add(new Smiley(SMILEY15, + new String[] {"(wave)" }, "Waving")); - defaultPackList.add(new Smiley(ImageLoader.SMILEY18, - new String[] {"(bomb)"}, "Explosing")); + defaultSmileyList.add(new Smiley(SMILEY16, + new String[] {"(clap)"}, "Clapping")); - defaultPackList.add(new Smiley(ImageLoader.SMILEY19, - new String[] {"(search)"}, "Searching")); + defaultSmileyList.add(new Smiley(SMILEY17, + new String[] {"(angry)"}, "Angry")); - defaultPackList.add(new Smiley(ImageLoader.SMILEY20, - new String[] {"(oops)"}, "Oops")); + defaultSmileyList.add(new Smiley(SMILEY18, + new String[] {"(bomb)"}, "Explosing")); - return defaultPackList; + defaultSmileyList.add(new Smiley(SMILEY19, + new String[] {"(search)"}, "Searching")); + + defaultSmileyList.add(new Smiley(SMILEY20, + new String[] {"(oops)"}, "Oops")); + + defaultSmileyPack + = Collections.unmodifiableCollection(defaultSmileyList); + return defaultSmileyPack; + } } /** @@ -1218,20 +1238,10 @@ public static Collection getDefaultSmileysPack() */ public static Smiley getSmiley(String smileyString) { - Collection smileys = getDefaultSmileysPack(); - - for (Smiley smiley : smileys) - { - String[] smileyStrings = smiley.getSmileyStrings(); - - for (int j = 0; j < smileyStrings.length; j++) - { - String srcString = smileyStrings[j]; - + for (Smiley smiley : getDefaultSmileyPack()) + for (String srcString : smiley.getSmileyStrings()) if (srcString.equals(smileyString)) return smiley; - } - } return null; } @@ -1266,7 +1276,7 @@ public static BufferedImage getImage(ImageID imageID) } catch (Exception exc) { - log.error("Failed to load image:" + path, exc); + logger.error("Failed to load image:" + path, exc); } } @@ -1289,7 +1299,7 @@ public static Image getBytesInImage(byte[] imageBytes) } catch (Exception e) { - log.error("Failed to convert bytes to image.", e); + logger.error("Failed to convert bytes to image.", e); } return image; } @@ -1313,7 +1323,7 @@ public static String getImageUri(ImageID imageID) } catch (URISyntaxException e) { - log.debug("Unable to parse image URL to URI.", e); + logger.debug("Unable to parse image URL to URI.", e); } return null; diff --git a/src/net/java/sip/communicator/impl/gui/utils/Smiley.java b/src/net/java/sip/communicator/impl/gui/utils/Smiley.java index 66d6c719f..a59ed1754 100644 --- a/src/net/java/sip/communicator/impl/gui/utils/Smiley.java +++ b/src/net/java/sip/communicator/impl/gui/utils/Smiley.java @@ -7,6 +7,7 @@ package net.java.sip.communicator.impl.gui.utils; import java.net.*; +import java.util.*; import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.service.resources.*; @@ -15,14 +16,15 @@ * The Smiley is used to store a smiley. * * @author Yana Stamcheva + * @author Lubomir Marinov */ public class Smiley { - private ImageID imageID; + private final String description; - private String[] smileyStrings; + private final ImageID imageID; - private String description; + private final List smileyStrings; /** * Creates an instance of Smiley, by specifying the smiley @@ -34,31 +36,21 @@ public class Smiley public Smiley(ImageID imageID, String[] smileyStrings, String description) { this.imageID = imageID; - - this.setSmileyStrings(smileyStrings); - - this.setDescription(description); + this.smileyStrings + = Collections + .unmodifiableList(Arrays.asList(smileyStrings.clone())); + this.description = description; } /** * Returns the set of Strings corresponding to this smiley. * @return the set of Strings corresponding to this smiley. */ - public String[] getSmileyStrings() + public List getSmileyStrings() { return smileyStrings; } - /** - * Sets the set of Strings corresponding to this smiley. They could be - * ":-)", ":)", ":))" for example. - * @param smileyStrings the set of Strings corresponding to this smiley. - */ - public void setSmileyStrings(String[] smileyStrings) - { - this.smileyStrings = smileyStrings; - } - /** * Returns the description of this smiley. * @@ -69,16 +61,6 @@ public String getDescription() return description; } - /** - * Sets the description of this smiley. - * - * @param description the description of the smiley. - */ - public void setDescription(String description) - { - this.description = description; - } - /** * Returns the default String corresponding for this smiley. For example * ":-)". @@ -86,7 +68,7 @@ public void setDescription(String description) */ public String getDefaultString() { - return this.smileyStrings[0]; + return smileyStrings.get(0); } /**