Author: jcompagner
Date: Mon Mar 3 08:19:17 2008
New Revision: 633155
URL: http://svn.apache.org/viewvc?rev=633155&view=rev
Log:
added optimization for remove/add of childs. Now a quick custom list is being
used that grows *2.
But the slow part for large things is still the add that does a linear search
to get to the right component(id)
Modified:
wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/MarkupContainer.java
wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/list/ListView.java
Modified:
wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/MarkupContainer.java
URL:
http://svn.apache.org/viewvc/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/MarkupContainer.java?rev=633155&r1=633154&r2=633155&view=diff
==============================================================================
---
wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/MarkupContainer.java
(original)
+++
wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/MarkupContainer.java
Mon Mar 3 08:19:17 2008
@@ -16,6 +16,7 @@
*/
package org.apache.wicket;
+import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -469,6 +470,10 @@
sorted = new ArrayList(1);
sorted.add(children);
}
+ else if (children instanceof ChildList)
+ {
+ sorted = new ArrayList((ChildList)children);
+ }
else
{
sorted = Arrays.asList((Component[])children);
@@ -574,13 +579,17 @@
int size = children_size();
for (int i = 0; i < size; i++)
{
- // Get next child
- final Component child = children_get(i);
+ Object childObject = children_get(i, false);
+ if (childObject instanceof Component)
+ {
+ // Get next child
+ final Component child =
(Component)childObject;
- // Do not call remove() because the state
change would than be
- // recorded twice.
- child.detachModel();
- child.setParent(null);
+ // Do not call remove() because the
state change would than be
+ // recorded twice.
+ child.detachModel();
+ child.setParent(null);
+ }
}
children = null;
@@ -917,23 +926,12 @@
}
else
{
- // Get current list size
- final int size = children_size();
-
- // Create array that holds size + 1 elements
- final Object[] children = new Object[size + 1];
-
- // Loop through existing children copying them
- for (int i = 0; i < size; i++)
+ if (!(children instanceof ChildList))
{
- children[i] = children_get(i, false);
+ // Save new children
+ children = new ChildList(children);
}
-
- // Add new child to the end
- children[size] = child;
-
- // Save new children
- this.children = children;
+ ((ChildList)children).add(child);
}
}
@@ -966,25 +964,39 @@
private final Object children_get(int index, boolean reconstruct)
{
Object component = null;
- if (index == 0 && children != null && children instanceof
Object[] == false)
+ if (children != null)
{
- component = postprocess(children, reconstruct, this, 0);
- if (children != component)
+ if (children instanceof Object[] == false && children
instanceof ChildList == false)
{
- children = component;
+ if (index != 0)
+ throw new
ArrayIndexOutOfBoundsException("index " + index +
+ " is greater then 0");
+ component = postprocess(children, reconstruct,
this, 0);
+ if (children != component)
+ {
+ children = component;
+ }
}
- }
- else
- {
- // we have a list
- Object[] children = (Object[])this.children;
- component = postprocess(children[index], reconstruct,
this, index);
- if (children[index] != component)
+ else
{
- children[index] = component;
+ Object[] children = null;
+ if (this.children instanceof ChildList)
+ {
+ // we have a list
+ children =
((ChildList)this.children).childs;
+ }
+ else
+ {
+ // we have a object array
+ children = (Object[])this.children;
+ }
+ component = postprocess(children[index],
reconstruct, this, index);
+ if (children[index] != component)
+ {
+ children[index] = component;
+ }
}
}
-
return component;
}
@@ -1013,30 +1025,46 @@
private final Component children_get(final String id)
{
+ if (children == null)
+ {
+ return null;
+ }
Component component = null;
- if (children != null && children instanceof Object[] == false
&& getId(children).equals(id))
+ if (children instanceof Object[] == false && children
instanceof List == false)
{
- component = (Component)postprocess(children, true,
this, 0);
- if (children != component)
+ if (getId(children).equals(id))
{
- children = component;
+ component = (Component)postprocess(children,
true, this, 0);
+ if (children != component)
+ {
+ children = component;
+ }
}
}
- else if (children instanceof Object[])
+ else
{
- final Object[] children = (Object[])this.children;
+ Object[] children = null;
+ int size = 0;
+ if (this.children instanceof ChildList)
+ {
+ children = ((ChildList)this.children).childs;
+ size = ((ChildList)this.children).size;
+ }
+ else
{
- for (int i = 0; i < children.length; i++)
+ children = (Object[])this.children;
+ size = children.length;
+ }
+ for (int i = 0; i < size; i++)
+ {
+ if (getId(children[i]).equals(id))
{
- if (getId(children[i]).equals(id))
+ component =
(Component)postprocess(children[i], true, this, i);
+ if (children[i] != component)
{
- component =
(Component)postprocess(children[i], true, this, i);
- if (children[i] != component)
- {
- children[i] = component;
- }
- break;
+ children[i] = component;
}
+ break;
}
}
}
@@ -1045,15 +1073,33 @@
private final int children_indexOf(Component child)
{
- if (children != null && children instanceof Object[] == false &&
- getId(children).equals(child.getId()))
+ if (children == null)
{
- return 0;
+ return -1;
}
- else if (children instanceof Object[])
+ if (children instanceof Object[] == false && children
instanceof ChildList == false)
{
- final Object[] children = (Object[])this.children;
- for (int i = 0; i < children.length; i++)
+ if (getId(children).equals(child.getId()))
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ int size = 0;
+ Object[] children;
+ if (this.children instanceof Object[])
+ {
+ children = (Object[])this.children;
+ size = children.length;
+ }
+ else
+ {
+ children = ((ChildList)this.children).childs;
+ size = ((ChildList)this.children).size;
+ }
+
+ for (int i = 0; i < size; i++)
{
if (getId(children[i]).equals(child.getId()))
{
@@ -1076,6 +1122,9 @@
private final Component children_remove(int index)
{
+ if (children == null)
+ return null;
+
if (children instanceof Component || children instanceof
ComponentSourceEntry)
{
if (index == 0)
@@ -1091,35 +1140,34 @@
}
else
{
- Object[] c = ((Object[])children);
- final Object removed = c[index];
- if (c.length == 2)
- {
- if (index == 0)
- {
- children = c[1];
- }
- else if (index == 1)
- {
- children = c[0];
- }
- else
- {
- throw new IndexOutOfBoundsException();
- }
- }
- else
+ if (children instanceof Object[])
{
- Object[] newChildren = new Object[c.length - 1];
- int j = 0;
- for (int i = 0; i < c.length; i++)
+ Object[] c = ((Object[])children);
+ final Object removed = c[index];
+ if (c.length == 2)
{
- if (i != index)
+ if (index == 0)
+ {
+ children = c[1];
+ }
+ else if (index == 1)
{
- newChildren[j++] = c[i];
+ children = c[0];
}
+ else
+ {
+ throw new
IndexOutOfBoundsException();
+ }
+ return (Component)postprocess(removed,
true, null, -1);
}
- children = newChildren;
+ children = new ChildList(children);
+ }
+
+ ChildList lst = (ChildList)children;
+ Object removed = lst.remove(index);
+ if (lst.size == 1)
+ {
+ children = lst.get(0);
}
return (Component)postprocess(removed, true, null, -1);
}
@@ -1128,19 +1176,25 @@
private final Object children_set(int index, Object child, boolean
reconstruct)
{
Object replaced;
- if (index < children_size())
+ if (index >= 0 && index < children_size())
{
- if (children == null || children instanceof Component ||
- children instanceof ComponentSourceEntry)
+ if (children instanceof Component || children
instanceof ComponentSourceEntry)
{
replaced = children;
children = child;
}
else
{
- final Object[] children =
(Object[])this.children;
- replaced = children[index];
- children[index] = child;
+ if (children instanceof ChildList)
+ {
+ replaced =
((ChildList)children).set(index, child);
+ }
+ else
+ {
+ final Object[] children =
(Object[])this.children;
+ replaced = children[index];
+ children[index] = child;
+ }
}
}
else
@@ -1167,6 +1221,10 @@
{
return 1;
}
+ else if (children instanceof ChildList)
+ {
+ return ((ChildList)children).size;
+ }
return ((Object[])children).length;
}
}
@@ -1465,6 +1523,13 @@
}
}
}
+ if (children instanceof ChildList)
+ {
+ ChildList lst = (ChildList)children;
+ Object[] tmp = new Object[lst.size];
+ System.arraycopy(lst.childs, 0, tmp, 0, lst.size);
+ children = tmp;
+ }
}
void internalMarkRendering()
@@ -1569,5 +1634,100 @@
return IVisitor.CONTINUE_TRAVERSAL;
}
});
+ }
+
+ private static class ChildList extends AbstractList
+ {
+ private int size;
+ private Object[] childs;
+
+ /**
+ * Construct.
+ *
+ * @param children
+ */
+ public ChildList(Object children)
+ {
+ if (children instanceof Object[])
+ {
+ childs = (Object[])children;
+ size = childs.length;
+ }
+ else
+ {
+ childs = new Object[3];
+ add(children);
+ }
+ }
+
+ public Object get(int index)
+ {
+ return childs[index];
+ }
+
+ public int size()
+ {
+ return size;
+ }
+
+ public boolean add(Object o)
+ {
+ ensureCapacity(size + 1);
+ childs[size++] = o;
+ return true;
+ }
+
+ public void add(int index, Object element)
+ {
+ if (index > size || index < 0)
+ throw new IndexOutOfBoundsException("Index: " +
index + ", Size: " + size);
+
+ ensureCapacity(size + 1);
+ System.arraycopy(childs, index, childs, index + 1, size
- index);
+ childs[index] = element;
+ size++;
+ }
+
+ public Object set(int index, Object element)
+ {
+ if (index >= size)
+ throw new IndexOutOfBoundsException("Index: " +
index + ", Size: " + size);
+
+ Object oldValue = childs[index];
+ childs[index] = element;
+ return oldValue;
+ }
+
+ public Object remove(int index)
+ {
+ if (index >= size)
+ throw new IndexOutOfBoundsException("Index: " +
index + ", Size: " + size);
+
+ Object oldValue = childs[index];
+
+ int numMoved = size - index - 1;
+ if (numMoved > 0)
+ System.arraycopy(childs, index + 1, childs,
index, numMoved);
+ childs[--size] = null; // Let gc do its work
+
+ return oldValue;
+ }
+
+ /**
+ * @param minCapacity
+ */
+ public void ensureCapacity(int minCapacity)
+ {
+ int oldCapacity = childs.length;
+ if (minCapacity > oldCapacity)
+ {
+ Object oldData[] = childs;
+ int newCapacity = oldCapacity * 2;
+ if (newCapacity < minCapacity)
+ newCapacity = minCapacity;
+ childs = new Object[newCapacity];
+ System.arraycopy(oldData, 0, childs, 0, size);
+ }
+ }
}
}
Modified:
wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/list/ListView.java
URL:
http://svn.apache.org/viewvc/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/list/ListView.java?rev=633155&r1=633154&r2=633155&view=diff
==============================================================================
---
wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/list/ListView.java
(original)
+++
wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/html/list/ListView.java
Mon Mar 3 08:19:17 2008
@@ -141,7 +141,7 @@
if (model == null)
{
throw new IllegalArgumentException(
- "Null models are not allowed. If you
have no model, you may prefer a Loop instead");
+ "Null models are not allowed. If you have no
model, you may prefer a Loop instead");
}
// A reasonable default for viewSize can not be determined
right now,
@@ -236,7 +236,7 @@
if ((Integer.MAX_VALUE - size) < firstIndex)
{
throw new IllegalStateException(
- "firstIndex + size must be smaller than
Integer.MAX_VALUE");
+ "firstIndex + size must be smaller than
Integer.MAX_VALUE");
}
return size;
@@ -549,14 +549,17 @@
removeAll();
}
+ boolean hasChildren = size() != 0;
// Loop through the markup in this container for each
item
for (int i = 0; i < size; i++)
{
// Get index
final int index = firstIndex + i;
- // If this component does not already exist,
populate it
- ListItem item =
(ListItem)get(Integer.toString(index));
+ ListItem item = null;
+ if (hasChildren)
+ // If this component does not already
exist, populate it
+ item =
(ListItem)get(Integer.toString(index));
if (item == null)
{
// Create item for index