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]

Reply via email to