You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by gc...@apache.org on 2008/01/19 01:45:45 UTC
svn commit: r613331 - in /myfaces/trinidad/trunk/trinidad-api/src/main:
java-templates/org/apache/myfaces/trinidad/component/
java/org/apache/myfaces/trinidad/component/
Author: gcrawford
Date: Fri Jan 18 16:45:44 2008
New Revision: 613331
URL: http://svn.apache.org/viewvc?rev=613331&view=rev
Log:
Issue 906 optimize getClientId - use per thread shared StringBuilder
In getClientId/getContainerClientId we create a new stringBuilder.
However when creating a client id we only use one stringBuilder at a time, so have a single instance of a StringBuilder saved on thread local.
Have a utility to get this instance, and any time a user gets the instance, set the length of the stringBuilder to 0.
Modified:
myfaces/trinidad/trunk/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXDecorateCollectionTemplate.java
myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java
myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponentBase.java
Modified: myfaces/trinidad/trunk/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXDecorateCollectionTemplate.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXDecorateCollectionTemplate.java?rev=613331&r1=613330&r2=613331&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXDecorateCollectionTemplate.java (original)
+++ myfaces/trinidad/trunk/trinidad-api/src/main/java-templates/org/apache/myfaces/trinidad/component/UIXDecorateCollectionTemplate.java Fri Jan 18 16:45:44 2008
@@ -6,9 +6,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -26,7 +26,7 @@
* <p>
* @version $Name: $ ($Revision$) $Date$
*/
-public abstract class UIXDecorateCollectionTemplate extends UIXComponentBase
+public abstract class UIXDecorateCollectionTemplate extends UIXComponentBase
implements NamingContainer
{
/**
@@ -38,13 +38,13 @@
{
return _currencyString;
}
-
+
/**
* Sets the currency String for this decorate collection. The decorator renders
* aggregated components that are not in the component tree. If any of the aggregated
* component is a naming container (for e.g. menubar), this method allows the currency to
* be set to that naming container so that it can successfully decode its children.
- *
+ *
* @param currency the currency to be established
* @see #getCurrencyString
*/
@@ -52,7 +52,7 @@
{
_currencyString = currency;
}
-
+
/**
* Gets the client-id of this component, without any NamingContainers.
* This id changes depending on the currency Object.
@@ -69,7 +69,9 @@
String key = getCurrencyString();
if (key != null)
{
- id += NamingContainer.SEPARATOR_CHAR + key;
+ StringBuilder bld = __getSharedStringBuilder();
+ bld.append(id).append(NamingContainer.SEPARATOR_CHAR).append(key);
+ id = bld.toString();
}
return id;
Modified: myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java?rev=613331&r1=613330&r2=613331&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java (original)
+++ myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXCollection.java Fri Jan 18 16:45:44 2008
@@ -6,9 +6,9 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -555,9 +555,9 @@
@Deprecated
public String getCurrencyString()
{
- return getClientRowKey();
+ return getClientRowKey();
}
-
+
/**
* @deprecated use setClientRowKey
* @see #setClientRowKey
@@ -667,7 +667,9 @@
String key = getClientRowKey();
if (key != null)
{
- id += NamingContainer.SEPARATOR_CHAR + key;
+ StringBuilder bld = __getSharedStringBuilder();
+ bld.append(id).append(NamingContainer.SEPARATOR_CHAR).append(key);
+ id = bld.toString();
}
return id;
@@ -814,11 +816,11 @@
if ((singleFacetState == null) ||
(singleFacetState == Transient.TRUE))
continue;
-
+
// Don't bother allocating anything until we have some non-null
// and non-transient facet state
if (facetStateIsEmpty)
- {
+ {
facetStateIsEmpty = false;
facetState = new Object[facetCount * 2];
}
@@ -829,7 +831,7 @@
facetState[base + 1] = singleFacetState;
i++;
}
-
+
// OK, we had something: allocate the state array to three
// entries, and insert the facet state at position 2
if (!facetStateIsEmpty)
@@ -883,7 +885,7 @@
// Just a transient component - return
if ((stampState == Transient.TRUE) || (stampState == null))
return;
-
+
// If this isn't an Object array, then it's a component with state
// of its own, but no child/facet state - so restore and be done
if (!(stampState instanceof Object[]))
@@ -905,7 +907,7 @@
if (stateSize >= 3)
{
Object[] facetStateArray = (Object[]) state[2];
- // This had better be non-null, otherwise we never
+ // This had better be non-null, otherwise we never
// should have allocated a three-element array!
assert(facetStateArray != null);
@@ -917,7 +919,7 @@
restoreStampState(context, stamp.getFacet(facetName), facetState);
}
}
-
+
// If there's any child state, restore it
if (stateSize >= 2)
{
@@ -976,7 +978,7 @@
/**
* Gets the ClientRowKeyManager that is used to handle the
- * {@link #getClientRowKey} and
+ * {@link #getClientRowKey} and
* {@link #setClientRowKey} methods.
* If the manager does not already exist a new one is created.
* In order to create your own manager, your Renderer (for this component)
@@ -987,7 +989,7 @@
{
// this method must be public, because specific renderers
// need access to the ClientRowKeyManager so that they might prune it.
-
+
InternalState iState = _getInternalState(true);
if (iState._clientKeyMgr == null)
{
@@ -1171,7 +1173,7 @@
{
// Never read and created by _getStampState
//InternalState iState = _getInternalState(true);
-
+
StampState stampState = _getStampState();
FacesContext context = getFacesContext();
Object currencyObj = getRowKey();
@@ -1299,7 +1301,7 @@
{
if (_isOptimizedKey(clientRowKey))
return clientRowKey;
-
+
ValueMap<Object,String> currencyCache = _currencyCache;
Object rowkey = currencyCache.getKey(clientRowKey);
return rowkey;
@@ -1319,7 +1321,7 @@
if (key == null)
{
// we don't have a string-key, so create a new one.
-
+
// first check to see if the rowkey itself can be used as the string-key:
if (rowKey instanceof String)
{
Modified: myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponentBase.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponentBase.java?rev=613331&r1=613330&r2=613331&view=diff
==============================================================================
--- myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponentBase.java (original)
+++ myfaces/trinidad/trunk/trinidad-api/src/main/java/org/apache/myfaces/trinidad/component/UIXComponentBase.java Fri Jan 18 16:45:44 2008
@@ -270,7 +270,7 @@
if (containerComponent instanceof NamingContainer)
{
String contClientId = containerComponent.getClientId(context);
- StringBuilder bld = new StringBuilder(contClientId.length() + 1 + clientId.length());
+ StringBuilder bld = __getSharedStringBuilder();
bld.append(contClientId).append(NamingContainer.SEPARATOR_CHAR).append(clientId);
clientId = bld.toString();
break;
@@ -1198,6 +1198,59 @@
}
}
+
+
+ /**
+ * <p>
+ * This gets a single threadlocal shared stringbuilder instance, each time you call
+ * __getSharedStringBuilder it sets the length of the stringBuilder instance to 0.
+ * </p><p>
+ * This allows you to use the same StringBuilder instance over and over.
+ * You must call toString on the instance before calling __getSharedStringBuilder again.
+ * </p>
+ * Example that works
+ * <pre><code>
+ * StringBuilder sb1 = __getSharedStringBuilder();
+ * sb1.append(a).append(b);
+ * String c = sb1.toString();
+ *
+ * StringBuilder sb2 = __getSharedStringBuilder();
+ * sb2.append(b).append(a);
+ * String d = sb2.toString();
+ * </code></pre>
+ * <br><br>
+ * Example that doesn't work, you must call toString on sb1 before
+ * calling __getSharedStringBuilder again.
+ * <pre><code>
+ * StringBuilder sb1 = __getSharedStringBuilder();
+ * StringBuilder sb2 = __getSharedStringBuilder();
+ *
+ * sb1.append(a).append(b);
+ * String c = sb1.toString();
+ *
+ * sb2.append(b).append(a);
+ * String d = sb2.toString();
+ * </code></pre>
+ *
+ */
+ static StringBuilder __getSharedStringBuilder()
+ {
+ StringBuilder sb = _STRING_BUILDER.get();
+
+ if (sb == null)
+ {
+ sb = new StringBuilder();
+ _STRING_BUILDER.set(sb);
+ }
+
+ // clear out the stringBuilder by setting the length to 0
+ sb.setLength(0);
+
+ return sb;
+ }
+
+
+
/**
* render a component. this is called by renderers whose
* getRendersChildren() return true.
@@ -1328,6 +1381,11 @@
private static final Iterator<String> _EMPTY_STRING_ITERATOR =
new EmptyIterator<String>();
+
+
+ static private final ThreadLocal<StringBuilder> _STRING_BUILDER =
+ new ThreadLocal<StringBuilder>();
+
private static final Iterator<UIComponent> _EMPTY_UICOMPONENT_ITERATOR =
new EmptyIterator<UIComponent>();