dev@javaserverfaces.java.net

[REVIEW] Improvement to UIData.keepSaved()

From: Ryan Lubke <Ryan.Lubke_at_Sun.COM>
Date: Mon, 10 Sep 2007 10:41:22 -0700


UIData.keepSaved() is inefficient - especially for large tables.
Given a table with say 2500 rows, keepSaved is invoked twice and accounts
for over 300ms of time spent in processing.

With the change below, keepSaved() doesn't show up in profiling.

SECTION: Modified Files
----------------------------
M src/javax/faces/component/UIData.java
  - If we're nested, return immediately - no need to scan for messages.
  - If not nested, instead of looping through all of the UIData's known
    client IDs and checking for messages one by one, get all clientIds with
    messages. For each ID that starts with baseClientId, check to see if there
    are any FATAL or ERROR messages queued for the component, and if so, return.


  


SECTION: Diffs
----------------------------
Index: src/javax/faces/component/UIData.java
===================================================================
RCS file: /cvs/javaserverfaces-sources/jsf-api/src/javax/faces/component/UIData.java,v
retrieving revision 1.75.4.2
diff -u -r1.75.4.2 UIData.java
--- src/javax/faces/component/UIData.java 28 Aug 2007 17:36:44 -0000 1.75.4.2
+++ src/javax/faces/component/UIData.java 10 Sep 2007 17:35:50 -0000
@@ -1294,18 +1294,29 @@
      */
     private boolean keepSaved(FacesContext context) {
 
- for (String clientId : saved.keySet()) {
- Iterator messages = context.getMessages(clientId);
- while (messages.hasNext()) {
- FacesMessage message = (FacesMessage) messages.next();
- if (message.getSeverity().compareTo(FacesMessage.SEVERITY_ERROR)
- >= 0) {
- return (true);
+ if (!isNestedWithinUIData()) {
+ // we're not nested, so we can rely on the fact that
+ // baseClientId is not null. Get all client IDs that have messages
+ // and if any of them start with the baseClientId, then get the
+ // messages and see if any are ERROR or FATAL.
+ for (Iterator<String> ids = context.getClientIdsWithMessages();
+ ids.hasNext();) {
+ String id = ids.next();
+ if (id.startsWith(baseClientId)) {
+ for (Iterator<FacesMessage> msgs = context.getMessages(id);
+ msgs.hasNext();) {
+ FacesMessage msg = msgs.next();
+ if (FacesMessage.SEVERITY_ERROR.compareTo(msg.getSeverity()) >= 0) {
+ return true;
+ }
+ }
                 }
             }
+ return false;
+ } else {
+ return true;
         }
- return (isNestedWithinUIData());
-
+
     }
 
     private Boolean isNestedWithinUIData() {