From c1a8cd521f77cc542c206e7ab3f4aeb6aae53e87 Mon Sep 17 00:00:00 2001 From: Matthew Jason Benson Date: Fri, 5 Aug 2005 22:04:40 +0000 Subject: [PATCH] Inherit from BaseResourceCollectionWrapper (not -Container); improved sorting by hopefully reducing number of comparisons made. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@278500 13f79535-47bb-0310-9956-ffa450edef68 --- .../tools/ant/types/resources/Sort.java | 124 ++++++++++++++---- 1 file changed, 97 insertions(+), 27 deletions(-) diff --git a/src/main/org/apache/tools/ant/types/resources/Sort.java b/src/main/org/apache/tools/ant/types/resources/Sort.java index 79dbe31b5..d306109e7 100755 --- a/src/main/org/apache/tools/ant/types/resources/Sort.java +++ b/src/main/org/apache/tools/ant/types/resources/Sort.java @@ -18,10 +18,15 @@ package org.apache.tools.ant.types.resources; 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 @@ import org.apache.tools.ant.types.resources.comparators.ResourceComparator; * 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 @@ public class Sort extends BaseResourceCollectionContainer { * @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 @@ public class Sort extends BaseResourceCollectionContainer { 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);