mbenson 2005/08/05 15:04:40
Modified: src/main/org/apache/tools/ant/types/resources Sort.java
Log:
Inherit from BaseResourceCollectionWrapper (not -Container);
improved sorting by hopefully reducing number of comparisons made.
Revision Changes Path
1.2 +97 -27
ant/src/main/org/apache/tools/ant/types/resources/Sort.java
Index: Sort.java
===================================================================
RCS file:
/home/cvs/ant/src/main/org/apache/tools/ant/types/resources/Sort.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Sort.java 23 May 2005 19:51:57 -0000 1.1
+++ Sort.java 5 Aug 2005 22:04:40 -0000 1.2
@@ -18,10 +18,15 @@
import java.util.List;
import java.util.Stack;
+import java.util.Vector;
+import java.util.TreeMap;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Comparator;
import java.util.Collections;
+import java.util.AbstractCollection;
+import java.util.NoSuchElementException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.BuildException;
@@ -33,49 +38,114 @@
* ResourceCollection that sorts another ResourceCollection.
* @since Ant 1.7
*/
-public class Sort extends BaseResourceCollectionContainer {
- private static final String ONE_NESTED_MESSAGE
- = "Sorting is to be applied to exactly one nested resource
collection.";
+public class Sort extends BaseResourceCollectionWrapper {
- private Stack compStack = new Stack();
+ private class MultiComparator implements Comparator {
+ private Vector v = null;
+ synchronized void add(ResourceComparator c) {
+ if (c == null) {
+ return;
+ }
+ v = (v == null) ? new Vector() : v;
+ v.add(c);
+ }
+ public synchronized int compare(Object o1, Object o2) {
+ int result = 0;
+ //if no nested, natural order:
+ if (v == null || v.size() == 0) {
+ result = ((Comparable) o1).compareTo((Comparable) o2);
+ } else {
+ for (Iterator i = v.iterator(); result == 0 && i.hasNext();)
{
+ result = ((Comparator) i.next()).compare(o1, o2);
+ }
+ }
+ return result;
+ }
+ }
+
+ //sorted bag impl. borrowed from commons-collections TreeBag:
+ private class SortedBag extends AbstractCollection {
+ private class MutableInt {
+ int value = 0;
+ }
+ private class MyIterator implements Iterator {
+ private Iterator keyIter = t.keySet().iterator();
+ private Object current;
+ private int occurrence;
+ public synchronized boolean hasNext() {
+ return occurrence > 0 || keyIter.hasNext();
+ }
+ public synchronized Object next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ if (occurrence == 0) {
+ current = keyIter.next();
+ occurrence = ((MutableInt) t.get(current)).value;
+ }
+ --occurrence;
+ return current;
+ }
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+ private TreeMap t;
+ private int size;
+
+ SortedBag(Comparator c) {
+ t = new TreeMap(c);
+ }
+ public synchronized Iterator iterator() {
+ return new MyIterator();
+ }
+ public synchronized boolean add(Object o) {
+ if (size < Integer.MAX_VALUE) {
+ ++size;
+ }
+ MutableInt m = (MutableInt) (t.get(o));
+ if (m == null) {
+ m = new MutableInt();
+ t.put(o, m);
+ }
+ m.value++;
+ return true;
+ }
+ public synchronized int size() {
+ return size;
+ }
+ }
+
+ private MultiComparator comp = new MultiComparator();
/**
* Sort the contained elements.
* @return a Collection of Resources.
*/
- protected Collection getCollection() {
- List rcs = getResourceCollections();
- if (rcs.size() != 1) {
- throw new BuildException(ONE_NESTED_MESSAGE);
- }
- Iterator nested = ((ResourceCollection) (rcs.get(0))).iterator();
- if (!(nested.hasNext())) {
+ protected synchronized Collection getCollection() {
+ ResourceCollection rc = getResourceCollection();
+ Iterator iter = rc.iterator();
+ if (!(iter.hasNext())) {
return Collections.EMPTY_SET;
}
- ArrayList al = new ArrayList();
- while (nested.hasNext()) {
- al.add(nested.next());
- }
- if (compStack.empty()) {
- Collections.sort(al);
- } else {
- for (Stack s = (Stack) compStack.clone(); !s.empty();) {
- Collections.sort(al, (ResourceComparator) s.pop());
- }
+ SortedBag b = new SortedBag(comp);
+ while (iter.hasNext()) {
+ b.add(iter.next());
}
- return al;
+ return b;
}
/**
* Add a ResourceComparator to this Sort ResourceCollection.
- * If multiple ResourceComparator are added, they will be processed in
LIFO order.
+ * If multiple ResourceComparators are added, they will be processed in
LIFO order.
* @param c the ResourceComparator to add.
*/
- public void add(ResourceComparator c) {
+ public synchronized void add(ResourceComparator c) {
if (isReference()) {
throw noChildrenAllowed();
}
- compStack.push(c);
+ comp.add(c);
+ FailFast.invalidate(this);
}
/**
@@ -85,7 +155,7 @@
* @param p the project to use to dereference the references.
* @throws BuildException on error.
*/
- protected void dieOnCircularReference(Stack stk, Project p)
+ protected synchronized void dieOnCircularReference(Stack stk, Project p)
throws BuildException {
if (isChecked()) {
return;
@@ -93,7 +163,7 @@
if (isReference()) {
super.dieOnCircularReference(stk, p);
} else {
- for (Iterator i = compStack.iterator(); i.hasNext();) {
+ for (Iterator i = comp.v.iterator(); i.hasNext();) {
Object o = i.next();
if (o instanceof DataType) {
stk.push(o);
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]