You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2012/03/06 17:29:42 UTC

svn commit: r1297564 - in /myfaces/core/trunk: impl/src/main/java/org/apache/myfaces/view/facelets/ impl/src/main/java/org/apache/myfaces/view/facelets/compiler/ impl/src/main/java/org/apache/myfaces/view/facelets/impl/ impl/src/test/java/org/apache/my...

Author: lu4242
Date: Tue Mar  6 16:29:41 2012
New Revision: 1297564

URL: http://svn.apache.org/viewvc?rev=1297564&view=rev
Log:
MYFACES-3487 [perf] cache unique ids generated by facelets

Modified:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletCompositionContext.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/EncodingHandler.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFacelet.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletContext.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/FaceletCompositionContextImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/SectionUniqueIdCounter.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/impl/SectionUniqueIdCounterTest.java
    myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletCompositionContext.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletCompositionContext.java?rev=1297564&r1=1297563&r2=1297564&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletCompositionContext.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletCompositionContext.java Tue Mar  6 16:29:41 2012
@@ -456,4 +456,67 @@ abstract public class FaceletComposition
     {
     }
     
+    /**
+     * Set the iterator used to retrieve unique ids.
+     * 
+     * since 2.1.7, 2.0.13
+     * @param uniqueIdsIterator 
+     */
+    public void setUniqueIdsIterator(Iterator<String> uniqueIdsIterator)
+    {
+    }
+    
+    /**
+     * Activater record unique id mode, so an structure will be
+     * used to hold those values.
+     * 
+     * since 2.1.7, 2.0.13
+     */
+    public void initUniqueIdRecording()
+    {
+    }
+    
+    /**
+     * Add an unique id to the list if recording is enabled,
+     * if recording is not enabled it has no effect.
+     * 
+     * since 2.1.7, 2.0.13
+     * @param uniqueId 
+     */
+    public void addUniqueId(String uniqueId)
+    {
+    }
+    
+    /**
+     * Return the unique id from the iterator if applies
+     * 
+     * since 2.1.7, 2.0.13
+     * @return 
+     */
+    public String getUniqueIdFromIterator()
+    {
+        return null;
+    }
+    
+    /**
+     * Return the list of unique ids
+     * 
+     * since 2.1.7, 2.0.13
+     * @return 
+     */
+    public List<String> getUniqueIdList()
+    {
+        return null;
+    }
+
+    /**
+     * Increment the unique id without construct it.
+     * 
+     * since 2.1.7, 2.0.13
+     * @return 
+     */
+    public void incrementUniqueId()
+    {
+    }
+
 }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java?rev=1297564&r1=1297563&r2=1297564&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java Tue Mar  6 16:29:41 2012
@@ -127,6 +127,7 @@ import org.apache.myfaces.view.facelets.
 import org.apache.myfaces.view.facelets.util.ReflectionUtil;
 
 import static org.apache.myfaces.view.facelets.DefaultFaceletsStateManagementStrategy.*;
+import org.apache.myfaces.view.facelets.impl.SectionUniqueIdCounter;
 
 /**
  * This class represents the abstraction of Facelets as a ViewDeclarationLanguage.
@@ -304,6 +305,11 @@ public class FaceletViewDeclarationLangu
     private final static String STATE_KEY = "<!-...@-->";
 
     private final static int STATE_KEY_LEN = STATE_KEY.length();
+    
+    /**
+     * Key used to cache component ids for the counter
+     */
+    public final static String CACHED_COMPONENT_IDS = "oam.CACHED_COMPONENT_IDS"; 
 
     private int _bufferSize;
 
@@ -2392,6 +2398,17 @@ public class FaceletViewDeclarationLangu
         ExternalContext eContext = context.getExternalContext();
         _initializeBuffer(eContext);
         _initializeMode(eContext);
+        
+        // Create a component ids cache and store it on application map to
+        // reduce the overhead associated with create such ids over and over.
+        MyfacesConfig mfConfig = MyfacesConfig.getCurrentInstance(eContext);
+        if (mfConfig.getComponentUniqueIdsCacheSize() > 0)
+        {
+            String[] componentIdsCached = SectionUniqueIdCounter.generateUniqueIdCache("_", 
+                    mfConfig.getComponentUniqueIdsCacheSize());
+            eContext.getApplicationMap().put(
+                    CACHED_COMPONENT_IDS, componentIdsCached);
+        }
 
         log.finest("Initialization Successful");
     }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/EncodingHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/EncodingHandler.java?rev=1297564&r1=1297563&r2=1297564&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/EncodingHandler.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/compiler/EncodingHandler.java Tue Mar  6 16:29:41 2012
@@ -19,6 +19,7 @@
 package org.apache.myfaces.view.facelets.compiler;
 
 import java.io.IOException;
+import java.util.List;
 
 import javax.el.ELException;
 import javax.faces.FacesException;
@@ -32,6 +33,8 @@ public class EncodingHandler implements 
 
     private final FaceletHandler next;
     private final String encoding;
+    
+    private volatile List<String> _uniqueIdList;
 
     public EncodingHandler(FaceletHandler next, String encoding)
     {
@@ -57,4 +60,20 @@ public class EncodingHandler implements 
         }
     }
 
+    /**
+     * @return the _uniqueIdList
+     */
+    public List<String> getUniqueIdList()
+    {
+        return _uniqueIdList;
+    }
+
+    /**
+     * @param uniqueIdList the _uniqueIdList to set
+     */
+    public void setUniqueIdList(List<String> uniqueIdList)
+    {
+        this._uniqueIdList = uniqueIdList;
+    }
+
 }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFacelet.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFacelet.java?rev=1297564&r1=1297563&r2=1297564&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFacelet.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFacelet.java Tue Mar  6 16:29:41 2012
@@ -25,6 +25,7 @@ import java.io.ObjectOutput;
 import java.net.URL;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
+import java.util.Collections;
 import java.util.Collection;
 import java.util.Date;
 import java.util.Iterator;
@@ -44,10 +45,12 @@ import javax.faces.context.FacesContext;
 import javax.faces.view.facelets.FaceletContext;
 import javax.faces.view.facelets.FaceletException;
 import javax.faces.view.facelets.FaceletHandler;
+import org.apache.myfaces.shared.config.MyfacesConfig;
 
 import org.apache.myfaces.view.facelets.AbstractFacelet;
 import org.apache.myfaces.view.facelets.AbstractFaceletContext;
 import org.apache.myfaces.view.facelets.FaceletCompositionContext;
+import org.apache.myfaces.view.facelets.compiler.EncodingHandler;
 
 
 /**
@@ -81,6 +84,8 @@ final class DefaultFacelet extends Abstr
     private final URL _src;
 
     private final boolean _isBuildingCompositeComponentMetadata; 
+    
+    private final boolean _encodingHandler;
 
     public DefaultFacelet(DefaultFaceletFactory factory, ExpressionFactory el, URL src, String alias,
                           FaceletHandler root)
@@ -94,6 +99,7 @@ final class DefaultFacelet extends Abstr
         _refreshPeriod = _factory.getRefreshPeriod();
         _relativePaths = new WeakHashMap<String, URL>();
         _isBuildingCompositeComponentMetadata = false;
+        _encodingHandler = (root instanceof EncodingHandler);
     }
     
     public DefaultFacelet(DefaultFaceletFactory factory, ExpressionFactory el, URL src, String alias,
@@ -108,6 +114,7 @@ final class DefaultFacelet extends Abstr
         _refreshPeriod = _factory.getRefreshPeriod();
         _relativePaths = new WeakHashMap<String, URL>();
         _isBuildingCompositeComponentMetadata = isBuildingCompositeComponentMetadata;
+        _encodingHandler = (root instanceof EncodingHandler);
     }    
 
     /**
@@ -119,12 +126,28 @@ final class DefaultFacelet extends Abstr
     {
         FaceletCompositionContext myFaceletContext = null;
         boolean faceletCompositionContextInitialized = false;
+        boolean recordUniqueIds = false;
         myFaceletContext = FaceletCompositionContext.getCurrentInstance(facesContext);
         if (myFaceletContext == null)
         {
             myFaceletContext = new FaceletCompositionContextImpl(_factory, facesContext);
             myFaceletContext.init(facesContext);
             faceletCompositionContextInitialized = true;
+            if (_encodingHandler && MyfacesConfig.getCurrentInstance(
+                    facesContext.getExternalContext()).isViewUniqueIdsCacheEnabled() && 
+                    _refreshPeriod <= 0)
+            {
+                List<String> uniqueIdList = ((EncodingHandler)_root).getUniqueIdList();
+                if (uniqueIdList == null)
+                {
+                    myFaceletContext.initUniqueIdRecording();
+                    recordUniqueIds = true;
+                }
+                else
+                {
+                    myFaceletContext.setUniqueIdsIterator(uniqueIdList.iterator());
+                }
+            }
         }
         DefaultFaceletContext ctx = new DefaultFaceletContext(facesContext, this, myFaceletContext);
         
@@ -165,6 +188,13 @@ final class DefaultFacelet extends Abstr
             if (faceletCompositionContextInitialized)
             {
                 myFaceletContext.release(facesContext);
+                List<String> uniqueIdList = ((EncodingHandler)_root).getUniqueIdList();
+                if (recordUniqueIds &&  uniqueIdList == null)
+                {
+                    uniqueIdList = Collections.unmodifiableList(
+                            myFaceletContext.getUniqueIdList());
+                    ((EncodingHandler)_root).setUniqueIdList(uniqueIdList);
+                }
             }
         }
     }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletContext.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletContext.java?rev=1297564&r1=1297563&r2=1297564&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletContext.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/DefaultFaceletContext.java Tue Mar  6 16:29:41 2012
@@ -314,12 +314,24 @@ final class DefaultFaceletContext extend
         // per facelet because prefix is calculated from faceletHierarchy and base is
         // related to the tagId, which depends on the location.
         //_uniqueIdBuilder.append(getFaceletCompositionContext().generateUniqueId());
-        getFaceletCompositionContext().generateUniqueId(_uniqueIdBuilder);
-        _uniqueIdBuilder.append("_");
-        _uniqueIdBuilder.append(_prefix);
-        _uniqueIdBuilder.append("_");
-        _uniqueIdBuilder.append(base);
-        return _uniqueIdBuilder.toString();
+        
+        String uniqueIdFromIterator = getFaceletCompositionContext().getUniqueIdFromIterator();
+        if (uniqueIdFromIterator == null)
+        {
+            getFaceletCompositionContext().generateUniqueId(_uniqueIdBuilder);
+            _uniqueIdBuilder.append("_");
+            _uniqueIdBuilder.append(_prefix);
+            _uniqueIdBuilder.append("_");
+            _uniqueIdBuilder.append(base);
+            uniqueIdFromIterator = _uniqueIdBuilder.toString();
+            getFaceletCompositionContext().addUniqueId(uniqueIdFromIterator);
+            return uniqueIdFromIterator;
+        }
+        else
+        {
+            getFaceletCompositionContext().incrementUniqueId();
+            return uniqueIdFromIterator;
+        }
     }
 
     /**

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/FaceletCompositionContextImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/FaceletCompositionContextImpl.java?rev=1297564&r1=1297563&r2=1297564&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/FaceletCompositionContextImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/FaceletCompositionContextImpl.java Tue Mar  6 16:29:41 2012
@@ -125,6 +125,10 @@ public class FaceletCompositionContextIm
     
     private SectionUniqueIdCounter _sectionUniqueComponentIdCounter;
     
+    private List<String> _uniqueIdsList;
+    private Iterator<String> _uniqueIdsIterator;
+    private int _level;
+    
     public FaceletCompositionContextImpl(FaceletFactory factory, FacesContext facesContext)
     {
         super();
@@ -136,7 +140,69 @@ public class FaceletCompositionContextIm
         _compositeComponentAttributesMarked = new HashMap<UIComponent, Map<String, Boolean>>();
         _deletionLevel = -1;
         _sectionUniqueIdCounter = new SectionUniqueIdCounter();
-        _sectionUniqueComponentIdCounter = new SectionUniqueIdCounter("_");
+        //Cached at facelet view
+        MyfacesConfig myfacesConfig = MyfacesConfig.getCurrentInstance(
+                facesContext.getExternalContext());
+        if (myfacesConfig.getComponentUniqueIdsCacheSize() > 0)
+        {
+            String[] componentIdsCache = (String [])facesContext.getExternalContext().
+                    getApplicationMap().get(FaceletViewDeclarationLanguage.CACHED_COMPONENT_IDS);
+            if (componentIdsCache != null)
+            {
+                _sectionUniqueComponentIdCounter = new SectionUniqueIdCounter("_", 
+                        componentIdsCache);
+            }
+            else
+            {
+                _sectionUniqueComponentIdCounter = new SectionUniqueIdCounter("_");
+            }
+        }
+        else
+        {
+            _sectionUniqueComponentIdCounter = new SectionUniqueIdCounter("_");
+        }
+        _uniqueIdsList = null;
+        _uniqueIdsIterator = null;
+        _level = 0;
+    }
+    
+    @Override
+    public void setUniqueIdsIterator(Iterator<String> uniqueIdsIterator)
+    {
+        _uniqueIdsList = null;
+        _uniqueIdsIterator = uniqueIdsIterator;
+    }
+    
+    @Override
+    public void initUniqueIdRecording()
+    {
+        _uniqueIdsList = new LinkedList<String>();
+        _uniqueIdsIterator = null;
+    }
+    
+    @Override
+    public void addUniqueId(String uniqueId)
+    {
+        if (_uniqueIdsList != null && _level == 0)
+        {
+            _uniqueIdsList.add(uniqueId);
+        }
+    }
+    
+    @Override
+    public String getUniqueIdFromIterator()
+    {
+        if (_uniqueIdsIterator != null && _uniqueIdsIterator.hasNext() && _level == 0)
+        {
+            return _uniqueIdsIterator.next();
+        }
+        return null;
+    }
+    
+    @Override
+    public List<String> getUniqueIdList()
+    {
+        return _uniqueIdsList;
     }
 
     public FaceletFactory getFaceletFactory()
@@ -737,9 +803,16 @@ public class FaceletCompositionContextIm
     
     public String startComponentUniqueIdSection()
     {
+        _level++;
         _sectionUniqueComponentIdCounter.startUniqueIdSection();
         return _sectionUniqueIdCounter.startUniqueIdSection();
     }
+
+    @Override
+    public void incrementUniqueId()
+    {
+        _sectionUniqueIdCounter.incrementUniqueId();
+    }
     
     public String generateUniqueId()
     {
@@ -758,6 +831,7 @@ public class FaceletCompositionContextIm
     
     public void endComponentUniqueIdSection()
     {
+        _level--;
         _sectionUniqueIdCounter.endUniqueIdSection();
         _sectionUniqueComponentIdCounter.endUniqueIdSection();
     }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/SectionUniqueIdCounter.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/SectionUniqueIdCounter.java?rev=1297564&r1=1297563&r2=1297564&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/SectionUniqueIdCounter.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/SectionUniqueIdCounter.java Tue Mar  6 16:29:41 2012
@@ -40,7 +40,9 @@ public class SectionUniqueIdCounter
     private char[] _bufferConversion;
     
     private final int _radix;
-   
+    
+    private String[] _uniqueIdsCache;
+    
     public SectionUniqueIdCounter()
     {
         _activeSection = 0;
@@ -63,6 +65,18 @@ public class SectionUniqueIdCounter
         _bufferConversion = new char[15];
     }
     
+    public SectionUniqueIdCounter(String prefix, String[] cache)
+    {
+        _activeSection = 0;
+        _radix = Character.MAX_RADIX;
+        _counterStack = new ArrayList<Section>();
+        _counterStack.add(new Section(null,1,_radix));
+        _prefix = prefix;
+        _builder = new StringBuilder(30);
+        _bufferConversion = new char[15];
+        _uniqueIdsCache = cache;
+    }
+    
     public SectionUniqueIdCounter(String prefix, int radix)
     {
         _activeSection = 0;
@@ -74,6 +88,25 @@ public class SectionUniqueIdCounter
         _bufferConversion = new char[15];
     }
 
+    /**
+     * Creates an array of the generated unique ids for an specified prefix,
+     * than can be used later to prevent calculate the same String over and over.
+     * 
+     * @param prefix
+     * @param count
+     * @return 
+     */
+    public static String[] generateUniqueIdCache(String prefix, int count)
+    {
+        String[] cache = new String[count];
+        SectionUniqueIdCounter counter = new SectionUniqueIdCounter(prefix);
+        for (int i = 0; i < count ; i++)
+        {
+            cache[i] = counter.generateUniqueId();
+        }
+        return cache;
+    }
+
     public String startUniqueIdSection()
     {
         //1. Calculate prefix
@@ -122,7 +155,23 @@ public class SectionUniqueIdCounter
 
     public String generateUniqueId()
     {
-        return _counterStack.get(_activeSection).generateUniqueId(_prefix);
+        if (_activeSection == 0 && _uniqueIdsCache != null)
+        {
+            long i = _counterStack.get(_activeSection).getCounter();
+            if (((int)i) < (long)_uniqueIdsCache.length)
+            {
+                _counterStack.get(_activeSection).incrementUniqueId();
+                return _uniqueIdsCache[((int)i)-1];
+            }
+            else
+            {
+                return _counterStack.get(_activeSection).generateUniqueId(_prefix);
+            }
+        }
+        else
+        {
+            return _counterStack.get(_activeSection).generateUniqueId(_prefix);
+        }
     }
     
     public void generateUniqueId(StringBuilder builderToAdd)
@@ -130,6 +179,11 @@ public class SectionUniqueIdCounter
         _counterStack.get(_activeSection).generateUniqueId(_prefix, builderToAdd);
     }
     
+    public void incrementUniqueId()
+    {
+        _counterStack.get(_activeSection).incrementUniqueId();
+    }
+    
     public void endUniqueIdSection()
     {
         if (_activeSection <= 0)
@@ -168,6 +222,11 @@ public class SectionUniqueIdCounter
         {
             return counter;
         }
+        
+        public void incrementUniqueId()
+        {
+            this.counter++;
+        }
 
         public void generateUniqueId(String base, StringBuilder builder)
         {

Modified: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/impl/SectionUniqueIdCounterTest.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/impl/SectionUniqueIdCounterTest.java?rev=1297564&r1=1297563&r2=1297564&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/impl/SectionUniqueIdCounterTest.java (original)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/impl/SectionUniqueIdCounterTest.java Tue Mar  6 16:29:41 2012
@@ -126,4 +126,35 @@ public class SectionUniqueIdCounterTest 
         System.out.println(UIViewRoot.UNIQUE_ID_PREFIX+counter.generateUniqueId());
         */
     }
+    
+    @Test
+    public void testCachedCounter()
+    {
+        String[] cache = SectionUniqueIdCounter.generateUniqueIdCache("_", 10);
+        
+        SectionUniqueIdCounter counter = new SectionUniqueIdCounter("_", cache);
+        SectionUniqueIdCounter counterOrig = new SectionUniqueIdCounter("_");
+        
+        Assert.assertEquals(counterOrig.generateUniqueId(), counter.generateUniqueId());
+        Assert.assertEquals(counterOrig.generateUniqueId(), counter.generateUniqueId());
+        Assert.assertEquals(counterOrig.generateUniqueId(), counter.generateUniqueId());
+        Assert.assertEquals(counterOrig.generateUniqueId(), counter.generateUniqueId());
+        
+        counterOrig.startUniqueIdSection();
+        counter.startUniqueIdSection();
+        
+        Assert.assertEquals(counterOrig.generateUniqueId(), counter.generateUniqueId());
+        Assert.assertEquals(counterOrig.generateUniqueId(), counter.generateUniqueId());
+        Assert.assertEquals(counterOrig.generateUniqueId(), counter.generateUniqueId());
+        Assert.assertEquals(counterOrig.generateUniqueId(), counter.generateUniqueId());
+
+        counterOrig.endUniqueIdSection();
+        counter.endUniqueIdSection();
+        
+        Assert.assertEquals(counterOrig.generateUniqueId(), counter.generateUniqueId());
+        Assert.assertEquals(counterOrig.generateUniqueId(), counter.generateUniqueId());
+        Assert.assertEquals(counterOrig.generateUniqueId(), counter.generateUniqueId());
+        Assert.assertEquals(counterOrig.generateUniqueId(), counter.generateUniqueId());
+    }
+    
 }

Modified: myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java?rev=1297564&r1=1297563&r2=1297564&view=diff
==============================================================================
--- myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java (original)
+++ myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java Tue Mar  6 16:29:41 2012
@@ -353,8 +353,30 @@ public class MyfacesConfig
     public final static String INIT_PARAM_DEFAULT_RESPONSE_WRITER_CONTENT_TYPE_MODE = 
         "org.apache.myfaces.DEFAULT_RESPONSE_WRITER_CONTENT_TYPE_MODE";
     public final static String INIT_PARAM_DEFAULT_RESPONSE_WRITER_CONTENT_TYPE_MODE_DEFAULT = "text/html";
+
+    /**
+     * Enable or disable a cache used to "remember" the generated facelets unique ids and reduce 
+     * the impact on memory usage, only active if javax.faces.FACELETS_REFRESH_PERIOD is -1 (no refresh).
+     */
+    @JSFWebConfigParam(defaultValue = "false", since = "2.0.13, 2.1.7", expectedValues="true, false", 
+            group="viewhandler", tags="performance",
+            desc="Enable or disable a cache used to 'remember'  the generated facelets unique ids " + 
+                 "and reduce the impact over memory usage.")
+    public static final String INIT_PARAM_VIEW_UNIQUE_IDS_CACHE_ENABLED = 
+        "org.apache.myfaces.VIEW_UNIQUE_IDS_CACHE_ENABLED";
+    public static final boolean INIT_PARAM_VIEW_UNIQUE_IDS_CACHE_ENABLED_DEFAULT = false;
     
     /**
+     * Set the size of the cache used to store strings generated using SectionUniqueIdCounter
+     * for component ids. If this is set to 0, no cache is used. By default is set to 100.
+     */
+    @JSFWebConfigParam(defaultValue = "100", since = "2.0.13, 2.1.7",
+            group="viewhandler", tags="performance")
+    public static final String INIT_PARAM_COMPONENT_UNIQUE_IDS_CACHE_SIZE =
+        "org.apache.myfaces.COMPONENT_UNIQUE_IDS_CACHE_SIZE";
+    public static final int INIT_PARAM_COMPONENT_UNIQUE_IDS_CACHE_SIZE_DEFAULT = 100;
+
+    /**
     * If set false, myfaces won't support JSP and javax.faces.el. JSP are deprecated in JSF 2.X, javax.faces.el in 
     * in JSF 1.2. Default value is true. 
     * 
@@ -394,6 +416,8 @@ public class MyfacesConfig
     private boolean _strictJsf2RefreshTargetAjax;
     private boolean _strictJsf2CCELResolver;
     private String _defaultResponseWriterContentTypeMode;
+    private boolean _viewUniqueIdsCacheEnabled;
+    private int _componentUniqueIdsCacheSize;
     private boolean _supportJSPAndFacesEL;
 
     private static final boolean TOMAHAWK_AVAILABLE;
@@ -490,6 +514,8 @@ public class MyfacesConfig
         setStrictJsf2RefreshTargetAjax(INIT_PARAM_STRICT_JSF_2_REFRESH_TARGET_AJAX_DEFAULT);
         setStrictJsf2CCELResolver(INIT_PARAM_STRICT_JSF_2_CC_EL_RESOLVER_DEFAULT);
         setDefaultResponseWriterContentTypeMode(INIT_PARAM_DEFAULT_RESPONSE_WRITER_CONTENT_TYPE_MODE_DEFAULT);
+        setViewUniqueIdsCacheEnabled(INIT_PARAM_VIEW_UNIQUE_IDS_CACHE_ENABLED_DEFAULT);
+        setComponentUniqueIdsCacheSize(INIT_PARAM_COMPONENT_UNIQUE_IDS_CACHE_SIZE_DEFAULT);
         setSupportJSPAndFacesEL(INIT_PARAM_SUPPORT_JSP_AND_FACES_EL_DEFAULT);
     }
 
@@ -584,7 +610,12 @@ public class MyfacesConfig
                 extCtx, INIT_PARAM_DEFAULT_RESPONSE_WRITER_CONTENT_TYPE_MODE,
                 INIT_PARAM_DEFAULT_RESPONSE_WRITER_CONTENT_TYPE_MODE_DEFAULT));
 
-        
+        myfacesConfig.setViewUniqueIdsCacheEnabled(WebConfigParamUtils.getBooleanInitParameter(extCtx, 
+                INIT_PARAM_VIEW_UNIQUE_IDS_CACHE_ENABLED, INIT_PARAM_VIEW_UNIQUE_IDS_CACHE_ENABLED_DEFAULT));
+        myfacesConfig.setComponentUniqueIdsCacheSize(
+                WebConfigParamUtils.getIntegerInitParameter(extCtx,
+                INIT_PARAM_COMPONENT_UNIQUE_IDS_CACHE_SIZE, 
+                INIT_PARAM_COMPONENT_UNIQUE_IDS_CACHE_SIZE_DEFAULT));
         myfacesConfig.setSupportJSPAndFacesEL(WebConfigParamUtils.getBooleanInitParameter(extCtx, 
                 INIT_PARAM_SUPPORT_JSP_AND_FACES_EL, INIT_PARAM_SUPPORT_JSP_AND_FACES_EL_DEFAULT));
         
@@ -1054,7 +1085,17 @@ public class MyfacesConfig
     {
         this._defaultResponseWriterContentTypeMode = defaultResponseWriterContentTypeMode;
     }
-    
+
+    public boolean isViewUniqueIdsCacheEnabled()
+    {
+        return _viewUniqueIdsCacheEnabled;
+    }
+
+    public void setViewUniqueIdsCacheEnabled(boolean viewUniqueIdsCacheEnabled)
+    {
+        _viewUniqueIdsCacheEnabled = viewUniqueIdsCacheEnabled;
+    }
+
     public boolean isSupportJSPAndFacesEL()
     {
         return _supportJSPAndFacesEL;
@@ -1064,5 +1105,15 @@ public class MyfacesConfig
             boolean supportJSPANDFacesEL)
     {
         _supportJSPAndFacesEL = supportJSPANDFacesEL;
-    } 
+    }
+
+    public int getComponentUniqueIdsCacheSize()
+    {
+        return _componentUniqueIdsCacheSize;
+    }
+
+    public void setComponentUniqueIdsCacheSize(int componentUniqueIdsCacheSize)
+    {
+        this._componentUniqueIdsCacheSize = componentUniqueIdsCacheSize;
+    }
 }