More classes for galois
authorjzhou <jzhou>
Sat, 8 Oct 2011 00:08:03 +0000 (00:08 +0000)
committerjzhou <jzhou>
Sat, 8 Oct 2011 00:08:03 +0000 (00:08 +0000)
Robust/src/ClassLibrary/MGC/HashMap.java
Robust/src/ClassLibrary/MGC/Map.java
Robust/src/ClassLibrary/MGC/Thread.java
Robust/src/ClassLibrary/MGC/gnu/AbstractQueue.java [new file with mode: 0644]
Robust/src/ClassLibrary/MGC/gnu/Collections.java
Robust/src/ClassLibrary/MGC/gnu/Lock.java [new file with mode: 0644]
Robust/src/ClassLibrary/MGC/gnu/PriorityQueue.java [new file with mode: 0644]

index 9ec53db3a82af8dba146480ef3b39a4a31f8866d..562ef51d2b2d6de7119483fdd5c207253dd963d5 100644 (file)
@@ -3,6 +3,7 @@ public class HashMap implements Map {
   float loadFactor;
   int numItems;
   int threshold;
+  Collection values;
 
   public HashMap() {
     init(16, 0.75f);
@@ -143,4 +144,36 @@ public class HashMap implements Map {
     table[bin]=he;
     return null;
   }
+  
+  public Collection values()
+  {
+    if (values == null)
+      // We don't bother overriding many of the optional methods, as doing so
+      // wouldn't provide any significant performance advantage.
+      values = new AbstractCollection()
+      {
+        HashMap map;
+        
+        public AbstractCollection(HashMap m) {
+          this.map = map;
+        }
+        
+        public int size()
+        {
+          return size;
+        }
+
+        public Iterator iterator()
+        {
+          // Cannot create the iterator directly, because of LinkedHashMap.
+          return HashMapIterator(map, 1);
+        }
+
+        public void clear()
+        {
+          map.clear();
+        }
+      };
+    return values;
+  }
 }
index 1156a95610e264803cd3ec6f8d2312c2644910f3..3c50aace3d3abe1ea13ce23ea04b4b53979ab4c1 100644 (file)
@@ -246,4 +246,6 @@ public interface Map//<K, V>
    * @return the number of mappings
    */
   int size();
+  
+  Collection values();
 }
index dd7bd5e587e813d8bd8e83da2d7c14602dc60c80..917d3475bc3cc13f57fbfa22fab00071d46b42cb 100644 (file)
@@ -53,5 +53,11 @@ public class Thread implements Runnable {
     checkAccess();*/
     this.daemon = daemon;
   }
+  
+  public static Thread currentThread()
+  {
+    System.out.println("Unimplemented Thread.currentThread()!");
+    return null;
+  }
 
 }
diff --git a/Robust/src/ClassLibrary/MGC/gnu/AbstractQueue.java b/Robust/src/ClassLibrary/MGC/gnu/AbstractQueue.java
new file mode 100644 (file)
index 0000000..dd2a092
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util;
+
+/**
+ * This class provides skeletal implementations of some {@link Queue}
+ * operations. The implementations in this class are appropriate when
+ * the base implementation does <em>not</em> allow <tt>null</tt>
+ * elements.  Methods {@link #add add}, {@link #remove remove}, and
+ * {@link #element element} are based on {@link #offer offer}, {@link
+ * #poll poll}, and {@link #peek peek}, respectively but throw
+ * exceptions instead of indicating failure via <tt>false</tt> or
+ * <tt>null</tt> returns.
+ *
+ * <p> A <tt>Queue</tt> implementation that extends this class must
+ * minimally define a method {@link Queue#offer} which does not permit
+ * insertion of <tt>null</tt> elements, along with methods {@link
+ * Queue#peek}, {@link Queue#poll}, {@link Collection#size}, and a
+ * {@link Collection#iterator} supporting {@link
+ * Iterator#remove}. Typically, additional methods will be overridden
+ * as well. If these requirements cannot be met, consider instead
+ * subclassing {@link AbstractCollection}.
+ *
+ * <p>This class is a member of the
+ * <a href="{@docRoot}/../technotes/guides/collections/index.html">
+ * Java Collections Framework</a>.
+ *
+ * @since 1.5
+ * @author Doug Lea
+ * @param <E> the type of elements held in this collection
+ */
+public abstract class AbstractQueue/*<E>*/
+    extends AbstractCollection/*<E>*/
+    implements Queue/*<E>*/ {
+
+    /**
+     * Constructor for use by subclasses.
+     */
+    protected AbstractQueue() {
+    }
+
+    /**
+     * Inserts the specified element into this queue if it is possible to do so
+     * immediately without violating capacity restrictions, returning
+     * <tt>true</tt> upon success and throwing an <tt>IllegalStateException</tt>
+     * if no space is currently available.
+     *
+     * <p>This implementation returns <tt>true</tt> if <tt>offer</tt> succeeds,
+     * else throws an <tt>IllegalStateException</tt>.
+     *
+     * @param e the element to add
+     * @return <tt>true</tt> (as specified by {@link Collection#add})
+     * @throws IllegalStateException if the element cannot be added at this
+     *         time due to capacity restrictions
+     * @throws ClassCastException if the class of the specified element
+     *         prevents it from being added to this queue
+     * @throws NullPointerException if the specified element is null and
+     *         this queue does not permit null elements
+     * @throws IllegalArgumentException if some property of this element
+     *         prevents it from being added to this queue
+     */
+    public boolean add(Object/*E*/ e) {
+        if (offer(e))
+            return true;
+        else
+            throw new IllegalStateException("Queue full");
+    }
+
+    /**
+     * Retrieves and removes the head of this queue.  This method differs
+     * from {@link #poll poll} only in that it throws an exception if this
+     * queue is empty.
+     *
+     * <p>This implementation returns the result of <tt>poll</tt>
+     * unless the queue is empty.
+     *
+     * @return the head of this queue
+     * @throws NoSuchElementException if this queue is empty
+     */
+    public Object/*E*/ remove() {
+        Object/*E*/ x = poll();
+        if (x != null)
+            return x;
+        else
+            throw new NoSuchElementException();
+    }
+
+    /**
+     * Retrieves, but does not remove, the head of this queue.  This method
+     * differs from {@link #peek peek} only in that it throws an exception if
+     * this queue is empty.
+     *
+     * <p>This implementation returns the result of <tt>peek</tt>
+     * unless the queue is empty.
+     *
+     * @return the head of this queue
+     * @throws NoSuchElementException if this queue is empty
+     */
+    public Object/*E*/ element() {
+        Object/*E*/ x = peek();
+        if (x != null)
+            return x;
+        else
+            throw new NoSuchElementException();
+    }
+
+    /**
+     * Removes all of the elements from this queue.
+     * The queue will be empty after this call returns.
+     *
+     * <p>This implementation repeatedly invokes {@link #poll poll} until it
+     * returns <tt>null</tt>.
+     */
+    public void clear() {
+        while (poll() != null)
+            ;
+    }
+
+    /**
+     * Adds all of the elements in the specified collection to this
+     * queue.  Attempts to addAll of a queue to itself result in
+     * <tt>IllegalArgumentException</tt>. Further, the behavior of
+     * this operation is undefined if the specified collection is
+     * modified while the operation is in progress.
+     *
+     * <p>This implementation iterates over the specified collection,
+     * and adds each element returned by the iterator to this
+     * queue, in turn.  A runtime exception encountered while
+     * trying to add an element (including, in particular, a
+     * <tt>null</tt> element) may result in only some of the elements
+     * having been successfully added when the associated exception is
+     * thrown.
+     *
+     * @param c collection containing elements to be added to this queue
+     * @return <tt>true</tt> if this queue changed as a result of the call
+     * @throws ClassCastException if the class of an element of the specified
+     *         collection prevents it from being added to this queue
+     * @throws NullPointerException if the specified collection contains a
+     *         null element and this queue does not permit null elements,
+     *         or if the specified collection is null
+     * @throws IllegalArgumentException if some property of an element of the
+     *         specified collection prevents it from being added to this
+     *         queue, or if the specified collection is this queue
+     * @throws IllegalStateException if not all the elements can be added at
+     *         this time due to insertion restrictions
+     * @see #add(Object)
+     */
+    public boolean addAll(Collection/*<? extends E>*/ c) {
+        if (c == null)
+            throw new NullPointerException();
+        if (c == this)
+            throw new IllegalArgumentException();
+        boolean modified = false;
+        Iterator/*<? extends E>*/ e = c.iterator();
+        while (e.hasNext()) {
+            if (add(e.next()))
+                modified = true;
+        }
+        return modified;
+    }
+
+}
index 416d9b184455dfdf18128f3c38b235317588ebd2..748ade0fd6c0586736ab75ca9b94e1eecd2477de 100644 (file)
@@ -96,4 +96,79 @@ public class Collections
       }*/
     //TODO System.println("Collections.sort() invoked");
   }
+  
+  static final /*<T>*/ int compare(Object/*T*/ o1, Object/*T*/ o2, Comparator/*<? super T>*/ c)
+  {
+    return c == null ? ((Comparable) o1).compareTo(o2) : c.compare(o1, o2);
+  }
+  
+  public static /*<T extends Object & Comparable<? super T>>*/
+  Object/*T*/ min(Collection/*<? extends T>*/ c)
+  {
+    return min(c, null);
+  }
+
+  /**
+   * Find the minimum element in a Collection, according to a specified
+   * Comparator. This implementation iterates over the Collection, so it
+   * works in linear time.
+   *
+   * @param c the Collection to find the minimum element of
+   * @param order the Comparator to order the elements by, or null for natural
+   *        ordering
+   * @return the minimum element of c
+   * @throws NoSuchElementException if c is empty
+   * @throws ClassCastException if elements in c are not mutually comparable
+   * @throws NullPointerException if null is compared by natural ordering
+   *        (only possible when order is null)
+   */
+  public static /*<T> T*/Object min(Collection/*<? extends T>*/ c,
+        Comparator/*<? super T>*/ order)
+  {
+    Iterator/*<? extends T>*/ itr = c.iterator();
+    Object/*T*/ min = itr.next(); // throws NoSuchElementExcception
+    int csize = c.size();
+    for (int i = 1; i < csize; i++)
+      {
+  Object/*T*/ o = itr.next();
+  if (compare(min, o, order) > 0)
+    min = o;
+      }
+    return min;
+  }
+  
+  public static /*<T extends Object & Comparable<? super T>>
+  T*/Object max(Collection/*<? extends T>*/ c)
+  {
+    return max(c, null);
+  }
+
+  /**
+   * Find the maximum element in a Collection, according to a specified
+   * Comparator. This implementation iterates over the Collection, so it
+   * works in linear time.
+   *
+   * @param c the Collection to find the maximum element of
+   * @param order the Comparator to order the elements by, or null for natural
+   *        ordering
+   * @return the maximum element of c
+   * @throws NoSuchElementException if c is empty
+   * @throws ClassCastException if elements in c are not mutually comparable
+   * @throws NullPointerException if null is compared by natural ordering
+   *        (only possible when order is null)
+   */
+  public static /*<T> T*/Object max(Collection/*<? extends T>*/ c,
+        Comparator/*<? super T>*/ order)
+  {
+    Iterator/*<? extends T>*/ itr = c.iterator();
+    Object/*T*/ max = itr.next(); // throws NoSuchElementException
+    int csize = c.size();
+    for (int i = 1; i < csize; i++)
+      {
+  Object/*T*/ o = itr.next();
+  if (compare(max, o, order) < 0)
+    max = o;
+      }
+    return max;
+  }
 } // class Collections
diff --git a/Robust/src/ClassLibrary/MGC/gnu/Lock.java b/Robust/src/ClassLibrary/MGC/gnu/Lock.java
new file mode 100644 (file)
index 0000000..5e117a6
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package java.util.concurrent.locks;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * {@code Lock} implementations provide more extensive locking
+ * operations than can be obtained using {@code synchronized} methods
+ * and statements.  They allow more flexible structuring, may have
+ * quite different properties, and may support multiple associated
+ * {@link Condition} objects.
+ *
+ * <p>A lock is a tool for controlling access to a shared resource by
+ * multiple threads. Commonly, a lock provides exclusive access to a
+ * shared resource: only one thread at a time can acquire the lock and
+ * all access to the shared resource requires that the lock be
+ * acquired first. However, some locks may allow concurrent access to
+ * a shared resource, such as the read lock of a {@link ReadWriteLock}.
+ *
+ * <p>The use of {@code synchronized} methods or statements provides
+ * access to the implicit monitor lock associated with every object, but
+ * forces all lock acquisition and release to occur in a block-structured way:
+ * when multiple locks are acquired they must be released in the opposite
+ * order, and all locks must be released in the same lexical scope in which
+ * they were acquired.
+ *
+ * <p>While the scoping mechanism for {@code synchronized} methods
+ * and statements makes it much easier to program with monitor locks,
+ * and helps avoid many common programming errors involving locks,
+ * there are occasions where you need to work with locks in a more
+ * flexible way. For example, some algorithms for traversing
+ * concurrently accessed data structures require the use of
+ * &quot;hand-over-hand&quot; or &quot;chain locking&quot;: you
+ * acquire the lock of node A, then node B, then release A and acquire
+ * C, then release B and acquire D and so on.  Implementations of the
+ * {@code Lock} interface enable the use of such techniques by
+ * allowing a lock to be acquired and released in different scopes,
+ * and allowing multiple locks to be acquired and released in any
+ * order.
+ *
+ * <p>With this increased flexibility comes additional
+ * responsibility. The absence of block-structured locking removes the
+ * automatic release of locks that occurs with {@code synchronized}
+ * methods and statements. In most cases, the following idiom
+ * should be used:
+ *
+ * <pre><tt>     Lock l = ...;
+ *     l.lock();
+ *     try {
+ *         // access the resource protected by this lock
+ *     } finally {
+ *         l.unlock();
+ *     }
+ * </tt></pre>
+ *
+ * When locking and unlocking occur in different scopes, care must be
+ * taken to ensure that all code that is executed while the lock is
+ * held is protected by try-finally or try-catch to ensure that the
+ * lock is released when necessary.
+ *
+ * <p>{@code Lock} implementations provide additional functionality
+ * over the use of {@code synchronized} methods and statements by
+ * providing a non-blocking attempt to acquire a lock ({@link
+ * #tryLock()}), an attempt to acquire the lock that can be
+ * interrupted ({@link #lockInterruptibly}, and an attempt to acquire
+ * the lock that can timeout ({@link #tryLock(long, TimeUnit)}).
+ *
+ * <p>A {@code Lock} class can also provide behavior and semantics
+ * that is quite different from that of the implicit monitor lock,
+ * such as guaranteed ordering, non-reentrant usage, or deadlock
+ * detection. If an implementation provides such specialized semantics
+ * then the implementation must document those semantics.
+ *
+ * <p>Note that {@code Lock} instances are just normal objects and can
+ * themselves be used as the target in a {@code synchronized} statement.
+ * Acquiring the
+ * monitor lock of a {@code Lock} instance has no specified relationship
+ * with invoking any of the {@link #lock} methods of that instance.
+ * It is recommended that to avoid confusion you never use {@code Lock}
+ * instances in this way, except within their own implementation.
+ *
+ * <p>Except where noted, passing a {@code null} value for any
+ * parameter will result in a {@link NullPointerException} being
+ * thrown.
+ *
+ * <h3>Memory Synchronization</h3>
+ *
+ * <p>All {@code Lock} implementations <em>must</em> enforce the same
+ * memory synchronization semantics as provided by the built-in monitor
+ * lock, as described in <a href="http://java.sun.com/docs/books/jls/">
+ * The Java Language Specification, Third Edition (17.4 Memory Model)</a>:
+ * <ul>
+ * <li>A successful {@code lock} operation has the same memory
+ * synchronization effects as a successful <em>Lock</em> action.
+ * <li>A successful {@code unlock} operation has the same
+ * memory synchronization effects as a successful <em>Unlock</em> action.
+ * </ul>
+ *
+ * Unsuccessful locking and unlocking operations, and reentrant
+ * locking/unlocking operations, do not require any memory
+ * synchronization effects.
+ *
+ * <h3>Implementation Considerations</h3>
+ *
+ * <p> The three forms of lock acquisition (interruptible,
+ * non-interruptible, and timed) may differ in their performance
+ * characteristics, ordering guarantees, or other implementation
+ * qualities.  Further, the ability to interrupt the <em>ongoing</em>
+ * acquisition of a lock may not be available in a given {@code Lock}
+ * class.  Consequently, an implementation is not required to define
+ * exactly the same guarantees or semantics for all three forms of
+ * lock acquisition, nor is it required to support interruption of an
+ * ongoing lock acquisition.  An implementation is required to clearly
+ * document the semantics and guarantees provided by each of the
+ * locking methods. It must also obey the interruption semantics as
+ * defined in this interface, to the extent that interruption of lock
+ * acquisition is supported: which is either totally, or only on
+ * method entry.
+ *
+ * <p>As interruption generally implies cancellation, and checks for
+ * interruption are often infrequent, an implementation can favor responding
+ * to an interrupt over normal method return. This is true even if it can be
+ * shown that the interrupt occurred after another action may have unblocked
+ * the thread. An implementation should document this behavior.
+ *
+ * @see ReentrantLock
+ * @see Condition
+ * @see ReadWriteLock
+ *
+ * @since 1.5
+ * @author Doug Lea
+ */
+public interface Lock {
+
+    /**
+     * Acquires the lock.
+     *
+     * <p>If the lock is not available then the current thread becomes
+     * disabled for thread scheduling purposes and lies dormant until the
+     * lock has been acquired.
+     *
+     * <p><b>Implementation Considerations</b>
+     *
+     * <p>A {@code Lock} implementation may be able to detect erroneous use
+     * of the lock, such as an invocation that would cause deadlock, and
+     * may throw an (unchecked) exception in such circumstances.  The
+     * circumstances and the exception type must be documented by that
+     * {@code Lock} implementation.
+     */
+    void lock();
+
+    /**
+     * Acquires the lock unless the current thread is
+     * {@linkplain Thread#interrupt interrupted}.
+     *
+     * <p>Acquires the lock if it is available and returns immediately.
+     *
+     * <p>If the lock is not available then the current thread becomes
+     * disabled for thread scheduling purposes and lies dormant until
+     * one of two things happens:
+     *
+     * <ul>
+     * <li>The lock is acquired by the current thread; or
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
+     * current thread, and interruption of lock acquisition is supported.
+     * </ul>
+     *
+     * <p>If the current thread:
+     * <ul>
+     * <li>has its interrupted status set on entry to this method; or
+     * <li>is {@linkplain Thread#interrupt interrupted} while acquiring the
+     * lock, and interruption of lock acquisition is supported,
+     * </ul>
+     * then {@link InterruptedException} is thrown and the current thread's
+     * interrupted status is cleared.
+     *
+     * <p><b>Implementation Considerations</b>
+     *
+     * <p>The ability to interrupt a lock acquisition in some
+     * implementations may not be possible, and if possible may be an
+     * expensive operation.  The programmer should be aware that this
+     * may be the case. An implementation should document when this is
+     * the case.
+     *
+     * <p>An implementation can favor responding to an interrupt over
+     * normal method return.
+     *
+     * <p>A {@code Lock} implementation may be able to detect
+     * erroneous use of the lock, such as an invocation that would
+     * cause deadlock, and may throw an (unchecked) exception in such
+     * circumstances.  The circumstances and the exception type must
+     * be documented by that {@code Lock} implementation.
+     *
+     * @throws InterruptedException if the current thread is
+     *         interrupted while acquiring the lock (and interruption
+     *         of lock acquisition is supported).
+     */
+    //void lockInterruptibly() throws InterruptedException;
+
+    /**
+     * Acquires the lock only if it is free at the time of invocation.
+     *
+     * <p>Acquires the lock if it is available and returns immediately
+     * with the value {@code true}.
+     * If the lock is not available then this method will return
+     * immediately with the value {@code false}.
+     *
+     * <p>A typical usage idiom for this method would be:
+     * <pre>
+     *      Lock lock = ...;
+     *      if (lock.tryLock()) {
+     *          try {
+     *              // manipulate protected state
+     *          } finally {
+     *              lock.unlock();
+     *          }
+     *      } else {
+     *          // perform alternative actions
+     *      }
+     * </pre>
+     * This usage ensures that the lock is unlocked if it was acquired, and
+     * doesn't try to unlock if the lock was not acquired.
+     *
+     * @return {@code true} if the lock was acquired and
+     *         {@code false} otherwise
+     */
+    boolean tryLock();
+
+    /**
+     * Acquires the lock if it is free within the given waiting time and the
+     * current thread has not been {@linkplain Thread#interrupt interrupted}.
+     *
+     * <p>If the lock is available this method returns immediately
+     * with the value {@code true}.
+     * If the lock is not available then
+     * the current thread becomes disabled for thread scheduling
+     * purposes and lies dormant until one of three things happens:
+     * <ul>
+     * <li>The lock is acquired by the current thread; or
+     * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
+     * current thread, and interruption of lock acquisition is supported; or
+     * <li>The specified waiting time elapses
+     * </ul>
+     *
+     * <p>If the lock is acquired then the value {@code true} is returned.
+     *
+     * <p>If the current thread:
+     * <ul>
+     * <li>has its interrupted status set on entry to this method; or
+     * <li>is {@linkplain Thread#interrupt interrupted} while acquiring
+     * the lock, and interruption of lock acquisition is supported,
+     * </ul>
+     * then {@link InterruptedException} is thrown and the current thread's
+     * interrupted status is cleared.
+     *
+     * <p>If the specified waiting time elapses then the value {@code false}
+     * is returned.
+     * If the time is
+     * less than or equal to zero, the method will not wait at all.
+     *
+     * <p><b>Implementation Considerations</b>
+     *
+     * <p>The ability to interrupt a lock acquisition in some implementations
+     * may not be possible, and if possible may
+     * be an expensive operation.
+     * The programmer should be aware that this may be the case. An
+     * implementation should document when this is the case.
+     *
+     * <p>An implementation can favor responding to an interrupt over normal
+     * method return, or reporting a timeout.
+     *
+     * <p>A {@code Lock} implementation may be able to detect
+     * erroneous use of the lock, such as an invocation that would cause
+     * deadlock, and may throw an (unchecked) exception in such circumstances.
+     * The circumstances and the exception type must be documented by that
+     * {@code Lock} implementation.
+     *
+     * @param time the maximum time to wait for the lock
+     * @param unit the time unit of the {@code time} argument
+     * @return {@code true} if the lock was acquired and {@code false}
+     *         if the waiting time elapsed before the lock was acquired
+     *
+     * @throws InterruptedException if the current thread is interrupted
+     *         while acquiring the lock (and interruption of lock
+     *         acquisition is supported)
+     */
+    //boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
+
+    /**
+     * Releases the lock.
+     *
+     * <p><b>Implementation Considerations</b>
+     *
+     * <p>A {@code Lock} implementation will usually impose
+     * restrictions on which thread can release a lock (typically only the
+     * holder of the lock can release it) and may throw
+     * an (unchecked) exception if the restriction is violated.
+     * Any restrictions and the exception
+     * type must be documented by that {@code Lock} implementation.
+     */
+    void unlock();
+
+    /**
+     * Returns a new {@link Condition} instance that is bound to this
+     * {@code Lock} instance.
+     *
+     * <p>Before waiting on the condition the lock must be held by the
+     * current thread.
+     * A call to {@link Condition#await()} will atomically release the lock
+     * before waiting and re-acquire the lock before the wait returns.
+     *
+     * <p><b>Implementation Considerations</b>
+     *
+     * <p>The exact operation of the {@link Condition} instance depends on
+     * the {@code Lock} implementation and must be documented by that
+     * implementation.
+     *
+     * @return A new {@link Condition} instance for this {@code Lock} instance
+     * @throws UnsupportedOperationException if this {@code Lock}
+     *         implementation does not support conditions
+     */
+    Condition newCondition();
+}
diff --git a/Robust/src/ClassLibrary/MGC/gnu/PriorityQueue.java b/Robust/src/ClassLibrary/MGC/gnu/PriorityQueue.java
new file mode 100644 (file)
index 0000000..5b23890
--- /dev/null
@@ -0,0 +1,345 @@
+/* PriorityQueue.java -- Unbounded priority queue
+   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package java.util;
+
+import java.io.Serializable;
+
+/**
+ * @author Tom Tromey (tromey@redhat.com)
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+public class PriorityQueue/*<E>*/ extends AbstractQueue/*<E>*/ implements Serializable
+{
+  private static final int DEFAULT_CAPACITY = 11;
+
+  private static final long serialVersionUID = -7720805057305804111L;
+
+  /** Number of elements actually used in the storage array.  */
+  int used;
+
+  /**
+   * This is the storage for the underlying binomial heap.
+   * The idea is, each node is less than or equal to its children.
+   * A node at index N (0-based) has two direct children, at
+   * nodes 2N+1 and 2N+2.
+   */
+  Object/*E*/[] storage;
+
+  /**
+   * The comparator we're using, or null for natural ordering.
+   */
+  Comparator/*<? super E>*/ comparator;
+
+  public PriorityQueue()
+  {
+    this(DEFAULT_CAPACITY, null);
+  }
+
+  public PriorityQueue(Collection/*<? extends E>*/ c)
+  {
+    this(Math.max(1, (int) (1.1 * c.size())), null);
+
+    // Special case where we can find the comparator to use.
+    /*if (c instanceof SortedSet)
+      {
+       SortedSet<? extends E> ss = (SortedSet<? extends E>) c;
+       this.comparator = (Comparator<? super E>) ss.comparator();
+       // We can insert the elements directly, since they are sorted.
+       int i = 0;
+       for (E val : ss)
+         {
+           if (val == null)
+             throw new NullPointerException();
+           storage[i++] = val;
+         }
+      }
+    else */if (c instanceof PriorityQueue)
+    {
+      PriorityQueue/*<? extends E>*/ pq = (PriorityQueue/*<? extends E>*/) c;
+      this.comparator = (Comparator/*<? super E>*/)pq.comparator();
+      // We can just copy the contents.
+      System.arraycopy(pq.storage, 0, storage, 0, pq.storage.length);
+    }
+
+    addAll(c);
+  }
+
+  public PriorityQueue(int cap)
+  {
+    this(cap, null);
+  }
+
+  public PriorityQueue(int cap, Comparator/*<? super E>*/ comp)
+  {
+    this.used = 0;
+    this.storage = /*(E[])*/ new Object[cap];
+    this.comparator = comp;
+  }
+
+  public PriorityQueue(PriorityQueue/*<? extends E>*/ c)
+  {
+    this(Math.max(1, (int) (1.1 * c.size())),
+        (Comparator/*<? super E>*/)c.comparator());
+    // We can just copy the contents.
+    System.arraycopy(c.storage, 0, storage, 0, c.storage.length);
+  }
+
+  /*public PriorityQueue(SortedSet<? extends E> c)
+  {
+    this(Math.max(1, (int) (1.1 * c.size())),
+        (Comparator<? super E>)c.comparator());
+    // We can insert the elements directly, since they are sorted.
+    int i = 0;
+    for (E val : c)
+      {
+       if (val == null)
+         throw new NullPointerException();
+       storage[i++] = val;
+      }
+  }*/
+
+  public void clear()
+  {
+    //Arrays.fill(storage, null);
+    for(int i = 0; i<storage.length; i++) {
+      storage[i] = null;
+    }
+    used = 0;
+  }
+
+  public Comparator/*<? super E>*/ comparator()
+  {
+    return comparator;
+  }
+
+  public Iterator/*<E>*/ iterator()
+  {
+    return (Iterator)(new PriorityQueueIterator/*<E>*/(this));
+  }
+
+  public boolean offer(Object/*E*/ o)
+  {
+    if (o == null)
+      throw new NullPointerException();
+
+    int slot = findSlot(-1);
+
+    storage[slot] = o;
+    ++used;
+    bubbleUp(slot);
+
+    return true;
+  }
+
+  public Object/*E*/ peek()
+  {
+    return used == 0 ? null : storage[0];
+  }
+
+  public Object/*E*/ poll()
+  {
+    if (used == 0)
+      return null;
+    Object/*E*/ result = storage[0];
+    remove(0);
+    return result;
+  }
+
+  public boolean remove(Object o)
+  {
+    if (o != null)
+    {
+      for (int i = 0; i < storage.length; ++i)
+      {
+        if (o.equals(storage[i]))
+        {
+          remove(i);
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  public int size()
+  {
+    return used;
+  }
+
+  // It is more efficient to implement this locally -- less searching
+  // for free slots.
+  public boolean addAll(Collection/*<? extends E>*/ c)
+  {
+    if (c == this)
+      throw new IllegalArgumentException();
+
+    int newSlot = -1;
+    int save = used;
+    //for (Object/*E*/ val : c)
+    Iterator it = c.iterator();
+    while(it.hasNext())
+    {
+      Object val = it.next();
+      if (val == null)
+        throw new NullPointerException();
+      newSlot = findSlot(newSlot);
+      storage[newSlot] = val;
+      ++used;
+      bubbleUp(newSlot);
+    }
+
+    return save != used;
+  }
+
+  int findSlot(int start)
+  {
+    int slot;
+    if (used == storage.length)
+    {
+      resize();
+      slot = used;
+    }
+    else
+    {
+      for (slot = start + 1; slot < storage.length; ++slot)
+      {
+        if (storage[slot] == null)
+          break;
+      }
+      // We'll always find a slot.
+    }
+    return slot;
+  }
+
+  void remove(int index)
+  {
+    // Remove the element at INDEX.  We do this by finding the least
+    // child and moving it into place, then iterating until we reach
+    // the bottom of the tree.
+    while (storage[index] != null)
+    {
+      int child = 2 * index + 1;
+
+      // See if we went off the end.
+      if (child >= storage.length)
+      {
+        storage[index] = null;
+        break;
+      }
+
+      // Find which child we want to promote.  If one is not null,
+      // we pick it.  If both are null, it doesn't matter, we're
+      // about to leave.  If neither is null, pick the lesser.
+      if (child + 1 >= storage.length || storage[child + 1] == null)
+      {
+        // Nothing.
+      }
+      else if (storage[child] == null 
+          || (Collections.compare(storage[child], storage[child + 1],
+              comparator) > 0))
+        ++child;
+      storage[index] = storage[child];
+      index = child;
+    }
+    --used;
+  }
+
+  void bubbleUp(int index)
+  {
+    // The element at INDEX was inserted into a blank spot.  Now move
+    // it up the tree to its natural resting place.
+    while (index > 0)
+    {
+      // This works regardless of whether we're at 2N+1 or 2N+2.
+      int parent = (index - 1) / 2;
+      if (Collections.compare(storage[parent], storage[index], comparator)
+          <= 0)
+      {
+        // Parent is the same or smaller than this element, so the
+        // invariant is preserved.  Note that if the new element
+        // is smaller than the parent, then it is necessarily
+        // smaller than the parent's other child.
+        break;
+      }
+
+      Object/*E*/ temp = storage[index];
+      storage[index] = storage[parent];
+      storage[parent] = temp;
+
+      index = parent;
+    }
+  }
+
+  void resize()
+  {
+    Object/*E*/[] new_data = /*(E[])*/ new Object[2 * storage.length];
+    System.arraycopy(storage, 0, new_data, 0, storage.length);
+    storage = new_data;
+  }
+}
+
+public class PriorityQueueIterator implements Iterator {
+  int index = -1;
+  int count = 0;
+  PriorityQueue queue;
+
+  public PriorityQueueIterator(PriorityQueue queue) {
+    this.queue = queue;
+  }
+
+  public boolean hasNext()
+  {
+    return count < used;
+  }
+
+  public Object/*E*/ next()
+  {
+    while (this.queue.storage[++index] == null)
+      ;
+
+    ++count;
+    return this.queue.storage[index];
+  }
+
+  public void remove()
+  {
+    this.queue.remove(index);
+  }
+}