All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.aspectj.util.PartialOrder Maven / Gradle / Ivy

/* *******************************************************************
 * Copyright (c) 1999-2001 Xerox Corporation,
 *               2002 Palo Alto Research Center, Incorporated (PARC).
 * All rights reserved.
 * This program and the accompanying materials are made available
 * under the terms of the Eclipse Public License v 2.0
 * which accompanies this distribution and is available at
 * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
 *
 * Contributors:
 *     Xerox/PARC     initial implementation
 * ******************************************************************/

package org.aspectj.util;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 * This class implements a partial order
 *
 * It includes routines for doing a topo-sort
 */

public class PartialOrder {

	/**
	 * All classes that want to be part of a partial order must implement PartialOrder.PartialComparable.
	 */
	public interface PartialComparable {
		/**
		 * @return 
    *
  • +1 if this is greater than other
  • *
  • -1 if this is less than other
  • *
  • 0 if this is not comparable to other
  • *
* * Note: returning 0 from this method doesn't mean the same thing as returning 0 from * java.util.Comparable.compareTo() */ int compareTo(Object other); /** * This method can provide a deterministic ordering for elements that are strictly not comparable. If you have no need for * this, this method can just return 0 whenever called. */ int fallbackCompareTo(Object other); } private static class SortObject { T object; List> smallerObjects = new LinkedList<>(); List> biggerObjects = new LinkedList<>(); public SortObject(T o) { object = o; } boolean hasNoSmallerObjects() { return smallerObjects.size() == 0; } boolean removeSmallerObject(SortObject o) { smallerObjects.remove(o); return hasNoSmallerObjects(); } void addDirectedLinks(SortObject other) { int cmp = object.compareTo(other.object); if (cmp == 0) { return; } if (cmp > 0) { this.smallerObjects.add(other); other.biggerObjects.add(this); } else { this.biggerObjects.add(other); other.smallerObjects.add(this); } } public String toString() { return object.toString(); // +smallerObjects+biggerObjects; } } private static void addNewPartialComparable(List> graph, T o) { SortObject so = new SortObject<>(o); for (SortObject other : graph) { so.addDirectedLinks(other); } graph.add(so); } private static void removeFromGraph(List> graph, SortObject o) { for (Iterator> i = graph.iterator(); i.hasNext();) { SortObject other = i.next(); if (o == other) { i.remove(); } // ??? could use this to build up a new queue of objects with no // ??? smaller ones other.removeSmallerObject(o); } } /** * @param objects must all implement PartialComparable * * @return the same members as objects, but sorted according to their partial order. returns null if the objects are cyclical * */ public static List sort(List objects) { // lists of size 0 or 1 don't need any sorting if (objects.size() < 2) { return objects; } // ??? we might want to optimize a few other cases of small size // ??? I don't like creating this data structure, but it does give good // ??? separation of concerns. List> sortList = new LinkedList<>(); for (T object : objects) { addNewPartialComparable(sortList, object); } // System.out.println(sortList); // now we have built our directed graph // use a simple sort algorithm from here // can increase efficiency later // List ret = new ArrayList(objects.size()); final int N = objects.size(); for (int index = 0; index < N; index++) { // System.out.println(sortList); // System.out.println("-->" + ret); SortObject leastWithNoSmallers = null; for (SortObject so: sortList) { if (so.hasNoSmallerObjects()) { if (leastWithNoSmallers == null || so.object.fallbackCompareTo(leastWithNoSmallers.object) < 0) { leastWithNoSmallers = so; } } } if (leastWithNoSmallers == null) { return null; } removeFromGraph(sortList, leastWithNoSmallers); objects.set(index, leastWithNoSmallers.object); } return objects; } /*********************************************************************************** * /* a minimal testing harness ***********************************************************************************/ static class Token implements PartialComparable { private String s; Token(String s) { this.s = s; } public int compareTo(Object other) { Token t = (Token) other; int cmp = s.charAt(0) - t.s.charAt(0); if (cmp == 1) { return 1; } if (cmp == -1) { return -1; } return 0; } public int fallbackCompareTo(Object other) { return -s.compareTo(((Token) other).s); } public String toString() { return s; } } public static void main(String[] args) { List l = new ArrayList<>(); l.add(new Token("a1")); l.add(new Token("c2")); l.add(new Token("b3")); l.add(new Token("f4")); l.add(new Token("e5")); l.add(new Token("d6")); l.add(new Token("c7")); l.add(new Token("b8")); l.add(new Token("z")); l.add(new Token("x")); l.add(new Token("f9")); l.add(new Token("e10")); l.add(new Token("a11")); l.add(new Token("d12")); l.add(new Token("b13")); l.add(new Token("c14")); System.out.println(l); sort(l); System.out.println(l); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy