-/* Copyright (C) 1998, 1999, 2000 Free Software Foundation
+/* PushbackReader.java -- An character stream that can unread chars
+ Copyright (C) 1998, 2000 Free Software Foundation, Inc.
- This file is part of libgcj.
+This file is part of GNU Classpath.
-This software is copyrighted work licensed under the terms of the
-Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
-details. */
+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., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+As a special exception, if you link this library with other files to
+produce an executable, this library does not by itself cause the
+resulting executable to be covered by the GNU General Public License.
+This exception does not however invalidate any other reasons why the
+executable file might be covered by the GNU General Public License. */
+
+
package java.io;
/**
- * @author Warren Levy <warrenl@cygnus.com>
- * @date October 16, 1998.
+ * This subclass of <code>FilterReader</code> provides the ability to
+ * unread data from a stream. It maintains an internal buffer of unread
+ * data that is supplied to the next read operation. This is conceptually
+ * similar to mark/reset functionality, except that in this case the
+ * position to reset the stream to does not need to be known in advance.
+ * <p>
+ * The default pushback buffer size one char, but this can be overridden
+ * by the creator of the stream.
+ *
+ * @version 0.0
+ *
+ * @author Aaron M. Renn (arenn@urbanophile.com)
+ * @author Warren Levy <warrenl@cygnus.com>
+ */
+public class PushbackReader extends FilterReader
+{
+
+/*************************************************************************/
+
+/*
+ * Class Variables
+ */
+
+/**
+ * This is the default buffer size
+ */
+private static final int DEFAULT_BUFFER_SIZE = 1;
+
+/*************************************************************************/
+
+/*
+ * Instance Variables
*/
-/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
- * "The Java Language Specification", ISBN 0-201-63451-1
- * plus online API docs for JDK 1.2 beta from http://www.javasoft.com.
- * Status: Believed complete and correct.
+
+/**
+ * This is the buffer that is used to store the pushed back data
+ */
+private char[] buf;
+
+/**
+ * This is the position in the buffer from which the next char will be
+ * read. Bytes are stored in reverse order in the buffer, starting from
+ * <code>buf[buf.length - 1]</code> to <code>buf[0]</code>. Thus when
+ * <code>pos</code> is 0 the buffer is full and <code>buf.length</code> when
+ * it is empty
+ */
+private int pos;
+
+/*************************************************************************/
+
+/*
+ * Constructors
*/
-
-public class PushbackReader extends FilterReader
+
+/**
+ * This method initializes a <code>PushbackReader</code> to read from the
+ * specified subordinate <code>Reader</code> with a default pushback buffer
+ * size of 1.
+ *
+ * @code in The subordinate stream to read from
+ */
+public
+PushbackReader(Reader in)
+{
+ this(in, DEFAULT_BUFFER_SIZE);
+}
+
+/*************************************************************************/
+
+/**
+ * This method initializes a <code>PushbackReader</code> to read from the
+ * specified subordinate <code>Reader</code> with the specified buffer
+ * size
+ *
+ * @param in The subordinate <code>Reader</code> to read from
+ * @param bufsize The pushback buffer size to use
+ */
+public
+PushbackReader(Reader in, int bufsize)
+{
+ super(in);
+
+ if (bufsize < 0)
+ throw new IllegalArgumentException("buffer size must be positive");
+
+ buf = new char[bufsize];
+ pos = bufsize;
+}
+
+/*************************************************************************/
+
+/*
+ * Instance Methods
+ */
+
+/**
+ * This method closes the stream and frees any associated resources.
+ *
+ * @exception IOException If an error occurs.
+ */
+public void
+close() throws IOException
{
- /* Internal buffer array for data. */
- private char[] buf;
-
- /* The current position in the buffer. */
- private int pos;
-
- public PushbackReader(Reader in)
- {
- this(in, 1);
- }
-
- public PushbackReader(Reader in, int size)
- {
- super(in);
- if (size < 0)
- throw new IllegalArgumentException();
- buf = new char[size];
- pos = buf.length;
- }
-
- public void close() throws IOException
- {
- synchronized (lock)
+ synchronized (lock)
{
buf = null;
super.close();
}
- }
+}
+
+/*************************************************************************/
+
+/**
+ * This method throws an exception when called since this class does
+ * not support mark/reset.
+ *
+ * @param read_limit Not used.
+ *
+ * @exception IOException Always thrown to indicate mark/reset not supported.
+ */
+public void
+mark(int read_limit) throws IOException
+{
+ throw new IOException("mark not supported in this class");
+}
+
+/*************************************************************************/
+
+/**
+ * This method returns <code>false</code> to indicate that it does not support
+ * mark/reset functionality.
+ *
+ * @return This method returns <code>false</code> to indicate that this class does not support mark/reset functionality
+ *
+ */
+public boolean
+markSupported()
+{
+ return(false);
+}
+
+/*************************************************************************/
+
+/**
+ * This method always throws an IOException in this class because
+ * mark/reset functionality is not supported.
+ *
+ * @exception IOException Always thrown for this class
+ */
+public void
+reset() throws IOException
+{
+ throw new IOException("reset not supported in this class");
+}
+
+/*************************************************************************/
+
+/**
+ * This method determines whether or not this stream is ready to be read.
+ * If it returns <code>false</code> to indicate that the stream is not
+ * ready, any attempt to read from the stream could (but is not
+ * guaranteed to) block.
+ * <p>
+ * This stream is ready to read if there are either chars waiting to be
+ * read in the pushback buffer or if the underlying stream is ready to
+ * be read.
+ *
+ * @return <code>true</code> if this stream is ready to be read, <code>false</code> otherwise
+ *
+ * @exception IOException If an error occurs
+ */
+public boolean
+ready() throws IOException
+{
+ synchronized (lock)
+ {
+ if (buf == null)
+ throw new IOException ("stream closed");
+
+ if (((buf.length - pos) > 0) || super.ready())
+ return(true);
+ else
+ return(false);
+ }
+}
+
+/*************************************************************************/
+
+// Don't delete this method just because the spec says it shouldn't be there!
+// See the CVS log for details.
+/**
+ * This method skips the specified number of chars in the stream. It
+ * returns the actual number of chars skipped, which may be less than the
+ * requested amount.
+ * <p>
+ * This method first discards chars from the buffer, then calls the
+ * <code>skip</code> method on the underlying <code>Reader</code> to
+ * skip additional chars if necessary.
+ *
+ * @param num_chars The requested number of chars to skip
+ *
+ * @return The actual number of chars skipped.
+ *
+ * @exception IOException If an error occurs
+ */
+public long
+skip(long num_chars) throws IOException
+{
+ synchronized (lock)
+ {
+ if (num_chars <= 0)
+ return(0);
+
+ if ((buf.length - pos) >= num_chars)
+ {
+ pos += num_chars;
+ return(num_chars);
+ }
+
+ int chars_discarded = buf.length - pos;
+ pos = buf.length;
+
+ long chars_skipped = in.skip(num_chars - chars_discarded);
- public boolean markSupported()
- {
- return false;
- }
+ return(chars_discarded + chars_skipped);
+ } // synchronized
+}
+
+/*************************************************************************/
- public int read() throws IOException
- {
- synchronized (lock)
+/**
+ * This method reads an unsigned char from the input stream and returns it
+ * as an int in the range of 0-65535. This method also will return -1 if
+ * the end of the stream has been reached. The char returned will be read
+ * from the pushback buffer, unless the buffer is empty, in which case
+ * the char will be read from the underlying stream.
+ * <p>
+ * This method will block until the char can be read.
+ *
+ * @return The char read or -1 if end of stream
+ *
+ * @exception IOException If an error occurs
+ */
+public int
+read() throws IOException
+{
+ synchronized (lock)
{
if (buf == null)
- throw new IOException();
+ throw new IOException("stream closed");
- if (pos < buf.length)
- return ((int) buf[pos++]) & 0xFFFF;
+ if (pos == buf.length)
+ return(super.read());
- return super.read();
+ ++pos;
+ return((buf[pos - 1] & 0xFFFF));
}
- }
+}
+
+/*************************************************************************/
- public int read(char[] b, int off, int len) throws IOException
- {
- synchronized (lock)
+/**
+ * This method read chars from a stream and stores them into a caller
+ * supplied buffer. It starts storing the data at index <code>offset</code> into
+ * the buffer and attempts to read <code>len</code> chars. This method can
+ * return before reading the number of chars requested. The actual number
+ * of chars read is returned as an int. A -1 is returned to indicate the
+ * end of the stream.
+ * <p>
+ * This method will block until some data can be read.
+ * <p>
+ * This method first reads chars from the pushback buffer in order to
+ * satisfy the read request. If the pushback buffer cannot provide all
+ * of the chars requested, the remaining chars are read from the
+ * underlying stream.
+ *
+ * @param buf The array into which the chars read should be stored
+ * @param offset The offset into the array to start storing chars
+ * @param len The requested number of chars to read
+ *
+ * @return The actual number of chars read, or -1 if end of stream.
+ *
+ * @exception IOException If an error occurs.
+ */
+public synchronized int
+read(char[] b, int offset, int len) throws IOException
+{
+ synchronized (lock)
{
if (buf == null)
- throw new IOException();
+ throw new IOException("stream closed");
- if (off < 0 || len < 0 || off + len > b.length)
+ if (offset < 0 || len < 0 || offset + len > b.length)
throw new ArrayIndexOutOfBoundsException();
int numBytes = Math.min(buf.length - pos, len);
if (numBytes > 0)
{
- System.arraycopy (buf, pos, b, off, numBytes);
+ System.arraycopy (buf, pos, b, offset, numBytes);
pos += numBytes;
return numBytes;
}
- return super.read(b, off, len);
+ return super.read(b, offset, len);
}
- }
+}
- public boolean ready() throws IOException
- {
- synchronized (lock)
+/*************************************************************************/
+
+/**
+ * This method pushes a single char of data into the pushback buffer.
+ * The char pushed back is the one that will be returned as the first char
+ * of the next read.
+ * <p>
+ * If the pushback buffer is full, this method throws an exception.
+ * <p>
+ * The argument to this method is an <code>int</code>. Only the low eight bits
+ * of this value are pushed back.
+ *
+ * @param b The char to be pushed back, passed as an int
+ *
+ * @exception IOException If the pushback buffer is full.
+ */
+public void
+unread(int b) throws IOException
+{
+ synchronized (lock)
{
if (buf == null)
- throw new IOException();
+ throw new IOException("stream closed");
+ if (pos == 0)
+ throw new IOException("Pushback buffer is full");
- if (buf.length - pos > 0)
- return true;
-
- return super.ready();
- }
- }
+ --pos;
+ buf[pos] = (char)(b & 0xFFFF);
+ } // synchronized
+}
- public void unread(int b) throws IOException
- {
- synchronized (lock)
- {
- if (buf == null || pos <= 0)
- throw new IOException();
+/*************************************************************************/
- buf[--pos] = (char) b;
- }
- }
+/**
+ * This method pushes all of the chars in the passed char array into
+ * the pushback buffer. These chars are pushed in reverse order so that
+ * the next char read from the stream after this operation will be
+ * <code>buf[0]</code> followed by <code>buf[1]</code>, etc.
+ * <p>
+ * If the pushback buffer cannot hold all of the requested chars, an
+ * exception is thrown.
+ *
+ * @param buf The char array to be pushed back
+ *
+ * @exception IOException If the pushback buffer is full
+ */
+public synchronized void
+unread(char[] buf) throws IOException
+{
+ unread(buf, 0, buf.length);
+}
- public void unread(char[] b) throws IOException
- {
- unread(b, 0, b.length);
- }
+/*************************************************************************/
- public void unread(char[] b, int off, int len) throws IOException
- {
- synchronized (lock)
+/**
+ * This method pushed back chars from the passed in array into the pushback
+ * buffer. The chars from <code>buf[offset]</code> to <cdoe>buf[offset + len]</code>
+ * are pushed in reverse order so that the next char read from the stream
+ * after this operation will be <code>buf[offset]</code> followed by
+ * <code>buf[offset + 1]</code>, etc.
+ * <p>
+ * If the pushback buffer cannot hold all of the requested chars, an
+ * exception is thrown.
+ *
+ * @param buf The char array to be pushed back
+ * @param offset The index into the array where the chars to be push start
+ * @param len The number of chars to be pushed.
+ *
+ * @exception IOException If the pushback buffer is full
+ */
+public synchronized void
+unread(char[] b, int offset, int len) throws IOException
+{
+ synchronized (lock)
{
- if (buf == null || pos < len)
- throw new IOException();
+ if (buf == null)
+ throw new IOException("stream closed");
+ if (pos < len)
+ throw new IOException("Pushback buffer is full");
// Note the order that these chars are being added is the opposite
// of what would be done if they were added to the buffer one at a time.
// See the Java Class Libraries book p. 1397.
- System.arraycopy(b, off, buf, pos - len, len);
+ System.arraycopy(b, offset, buf, pos - len, len);
// Don't put this into the arraycopy above, an exception might be thrown
// and in that case we don't want to modify pos.
pos -= len;
}
- }
}
+
+} // class PushbackReader
/* Arrays.java -- Utility class with methods to operate on arrays
- Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
This file is part of GNU Classpath.
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
* arrays, and a method to provide a List "view" of an array to facilitate
* using arrays with Collection-based APIs.
*/
-public class Arrays {
-
+public class Arrays
+{
/**
* This class is non-instantiable.
*/
- private Arrays() {
+ private Arrays()
+ {
}
- private static Comparator defaultComparator = new Comparator() {
- public int compare(Object o1, Object o2) {
- return ((Comparable)o1).compareTo(o2);
+ private static Comparator defaultComparator = new Comparator()
+ {
+ public int compare(Object o1, Object o2)
+ {
+ return ((Comparable) o1).compareTo(o2);
}
};
* found, where n is the index of the first value higher than key or
* a.length if there is no such value.
*/
- public static int binarySearch(byte[] a, byte key) {
+ public static int binarySearch(byte[]a, byte key)
+ {
int low = 0;
int hi = a.length - 1;
int mid = 0;
- while (low <= hi) {
- mid = (low + hi) >> 1;
- final byte d = a[mid];
- if (d == key) {
- return mid;
- } else if (d > key) {
- hi = mid - 1;
- } else {
- low = ++mid; // This gets the insertion point right on the last loop
+ while (low <= hi)
+ {
+ mid = (low + hi) >> 1;
+ final byte d = a[mid];
+ if (d == key)
+ {
+ return mid;
+ }
+ else if (d > key)
+ {
+ hi = mid - 1;
+ }
+ else
+ {
+ // This gets the insertion point right on the last loop
+ low = ++mid;
+ }
}
- }
return -mid - 1;
}
* found, where n is the index of the first value higher than key or
* a.length if there is no such value.
*/
- public static int binarySearch(char[] a, char key) {
+ public static int binarySearch(char[]a, char key)
+ {
int low = 0;
int hi = a.length - 1;
int mid = 0;
- while (low <= hi) {
- mid = (low + hi) >> 1;
- final char d = a[mid];
- if (d == key) {
- return mid;
- } else if (d > key) {
- hi = mid - 1;
- } else {
- low = ++mid; // This gets the insertion point right on the last loop
+ while (low <= hi)
+ {
+ mid = (low + hi) >> 1;
+ final char d = a[mid];
+ if (d == key)
+ {
+ return mid;
+ }
+ else if (d > key)
+ {
+ hi = mid - 1;
+ }
+ else
+ {
+ // This gets the insertion point right on the last loop
+ low = ++mid;
+ }
}
- }
return -mid - 1;
}
* found, where n is the index of the first value higher than key or
* a.length if there is no such value.
*/
- public static int binarySearch(double[] a, double key) {
+ public static int binarySearch(double[]a, double key)
+ {
int low = 0;
int hi = a.length - 1;
int mid = 0;
- while (low <= hi) {
- mid = (low + hi) >> 1;
- final double d = a[mid];
- if (d == key) {
- return mid;
- } else if (d > key) {
- hi = mid - 1;
- } else {
- low = ++mid; // This gets the insertion point right on the last loop
+ while (low <= hi)
+ {
+ mid = (low + hi) >> 1;
+ final double d = a[mid];
+ if (d == key)
+ {
+ return mid;
+ }
+ else if (d > key)
+ {
+ hi = mid - 1;
+ }
+ else
+ {
+ // This gets the insertion point right on the last loop
+ low = ++mid;
+ }
}
- }
return -mid - 1;
}
* found, where n is the index of the first value higher than key or
* a.length if there is no such value.
*/
- public static int binarySearch(float[] a, float key) {
+ public static int binarySearch(float[]a, float key)
+ {
int low = 0;
int hi = a.length - 1;
int mid = 0;
- while (low <= hi) {
- mid = (low + hi) >> 1;
- final float d = a[mid];
- if (d == key) {
- return mid;
- } else if (d > key) {
- hi = mid - 1;
- } else {
- low = ++mid; // This gets the insertion point right on the last loop
+ while (low <= hi)
+ {
+ mid = (low + hi) >> 1;
+ final float d = a[mid];
+ if (d == key)
+ {
+ return mid;
+ }
+ else if (d > key)
+ {
+ hi = mid - 1;
+ }
+ else
+ {
+ // This gets the insertion point right on the last loop
+ low = ++mid;
+ }
}
- }
return -mid - 1;
}
* found, where n is the index of the first value higher than key or
* a.length if there is no such value.
*/
- public static int binarySearch(int[] a, int key) {
+ public static int binarySearch(int[]a, int key)
+ {
int low = 0;
int hi = a.length - 1;
int mid = 0;
- while (low <= hi) {
- mid = (low + hi) >> 1;
- final int d = a[mid];
- if (d == key) {
- return mid;
- } else if (d > key) {
- hi = mid - 1;
- } else {
- low = ++mid; // This gets the insertion point right on the last loop
+ while (low <= hi)
+ {
+ mid = (low + hi) >> 1;
+ final int d = a[mid];
+ if (d == key)
+ {
+ return mid;
+ }
+ else if (d > key)
+ {
+ hi = mid - 1;
+ }
+ else
+ {
+ // This gets the insertion point right on the last loop
+ low = ++mid;
+ }
}
- }
return -mid - 1;
}
* found, where n is the index of the first value higher than key or
* a.length if there is no such value.
*/
- public static int binarySearch(long[] a, long key) {
+ public static int binarySearch(long[]a, long key)
+ {
int low = 0;
int hi = a.length - 1;
int mid = 0;
- while (low <= hi) {
- mid = (low + hi) >> 1;
- final long d = a[mid];
- if (d == key) {
- return mid;
- } else if (d > key) {
- hi = mid - 1;
- } else {
- low = ++mid; // This gets the insertion point right on the last loop
+ while (low <= hi)
+ {
+ mid = (low + hi) >> 1;
+ final long d = a[mid];
+ if (d == key)
+ {
+ return mid;
+ }
+ else if (d > key)
+ {
+ hi = mid - 1;
+ }
+ else
+ {
+ // This gets the insertion point right on the last loop
+ low = ++mid;
+ }
}
- }
return -mid - 1;
}
* found, where n is the index of the first value higher than key or
* a.length if there is no such value.
*/
- public static int binarySearch(short[] a, short key) {
+ public static int binarySearch(short[]a, short key)
+ {
int low = 0;
int hi = a.length - 1;
int mid = 0;
- while (low <= hi) {
- mid = (low + hi) >> 1;
- final short d = a[mid];
- if (d == key) {
- return mid;
- } else if (d > key) {
- hi = mid - 1;
- } else {
- low = ++mid; // This gets the insertion point right on the last loop
+ while (low <= hi)
+ {
+ mid = (low + hi) >> 1;
+ final short d = a[mid];
+ if (d == key)
+ {
+ return mid;
+ }
+ else if (d > key)
+ {
+ hi = mid - 1;
+ }
+ else
+ {
+ // This gets the insertion point right on the last loop
+ low = ++mid;
+ }
}
- }
return -mid - 1;
}
* @exception NullPointerException if the specified comparator is null.
* @exception ClassCastException if the objects are not comparable by c.
*/
- private static int objectSearch(Object[] a, Object key, final Comparator c) {
+ private static int objectSearch(Object[]a, Object key, final Comparator c)
+ {
int low = 0;
int hi = a.length - 1;
int mid = 0;
- while (low <= hi) {
- mid = (low + hi) >> 1;
- final int d = c.compare(key, a[mid]);
- if (d == 0) {
- return mid;
- } else if (d < 0) {
- hi = mid - 1;
- } else {
- low = ++mid; // This gets the insertion point right on the last loop
+ while (low <= hi)
+ {
+ mid = (low + hi) >> 1;
+ final int d = c.compare(key, a[mid]);
+ if (d == 0)
+ {
+ return mid;
+ }
+ else if (d < 0)
+ {
+ hi = mid - 1;
+ }
+ else
+ {
+ // This gets the insertion point right on the last loop
+ low = ++mid;
+ }
}
- }
return -mid - 1;
}
* elements of a
* @exception NullPointerException if a null element has compareTo called
*/
- public static int binarySearch(Object[] a, Object key) {
+ public static int binarySearch(Object[]a, Object key)
+ {
return objectSearch(a, key, defaultComparator);
}
* @exception ClassCastException if key could not be compared with one of the
* elements of a
*/
- public static int binarySearch(Object[] a, Object key, Comparator c) {
+ public static int binarySearch(Object[]a, Object key, Comparator c)
+ {
return objectSearch(a, key, c);
}
* @returns true if a1 and a2 are both null, or if a2 is of the same length
* as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
*/
- public static boolean equals(byte[] a1, byte[] a2) {
-
+ public static boolean equals(byte[]a1, byte[]a2)
+ {
// Quick test which saves comparing elements of the same array, and also
// catches the case that both are null.
- if (a1 == a2) {
- return true;
- }
- try {
-
- // If they're the same length, test each element
- if (a1.length == a2.length) {
- for (int i = 0; i < a1.length; i++) {
- if (a1[i] != a2[i]) {
- return false;
- }
- }
- return true;
+ if (a1 == a2)
+ {
+ return true;
}
+
+ try
+ {
+ // If they're the same length, test each element
+ if (a1.length == a2.length)
+ {
+ for (int i = 0; i < a1.length; i++)
+ {
+ if (a1[i] != a2[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
- // If a1 == null or a2 == null but not both then we will get a NullPointer
- } catch (NullPointerException e) {
- }
+ // If a1 == null or a2 == null but not both then we will get a NullPointer
+ }
+ catch (NullPointerException e)
+ {
+ }
return false;
}
* @returns true if a1 and a2 are both null, or if a2 is of the same length
* as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
*/
- public static boolean equals(char[] a1, char[] a2) {
-
+ public static boolean equals(char[]a1, char[]a2)
+ {
// Quick test which saves comparing elements of the same array, and also
// catches the case that both are null.
- if (a1 == a2) {
- return true;
- }
- try {
-
- // If they're the same length, test each element
- if (a1.length == a2.length) {
- for (int i = 0; i < a1.length; i++) {
- if (a1[i] != a2[i]) {
- return false;
- }
- }
- return true;
+ if (a1 == a2)
+ {
+ return true;
}
+
+ try
+ {
+ // If they're the same length, test each element
+ if (a1.length == a2.length)
+ {
+ for (int i = 0; i < a1.length; i++)
+ {
+ if (a1[i] != a2[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
- // If a1 == null or a2 == null but not both then we will get a NullPointer
- } catch (NullPointerException e) {
- }
+ // If a1 == null or a2 == null but not both then we will get a NullPointer
+ }
+ catch (NullPointerException e)
+ {
+ }
return false;
}
* @returns true if a1 and a2 are both null, or if a2 is of the same length
* as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
*/
- public static boolean equals(double[] a1, double[] a2) {
-
+ public static boolean equals(double[]a1, double[]a2)
+ {
// Quick test which saves comparing elements of the same array, and also
// catches the case that both are null.
- if (a1 == a2) {
- return true;
- }
- try {
-
- // If they're the same length, test each element
- if (a1.length == a2.length) {
- for (int i = 0; i < a1.length; i++) {
- if (a1[i] != a2[i]) {
- return false;
- }
- }
- return true;
+ if (a1 == a2)
+ {
+ return true;
}
+
+ try
+ {
+ // If they're the same length, test each element
+ if (a1.length == a2.length)
+ {
+ for (int i = 0; i < a1.length; i++)
+ {
+ if (a1[i] != a2[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
- // If a1 == null or a2 == null but not both then we will get a NullPointer
- } catch (NullPointerException e) {
- }
+ // If a1 == null or a2 == null but not both then we will get a NullPointer
+ }
+ catch (NullPointerException e)
+ {
+ }
return false;
}
* @returns true if a1 and a2 are both null, or if a2 is of the same length
* as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
*/
- public static boolean equals(float[] a1, float[] a2) {
-
+ public static boolean equals(float[]a1, float[]a2)
+ {
// Quick test which saves comparing elements of the same array, and also
// catches the case that both are null.
- if (a1 == a2) {
- return true;
- }
- try {
-
- // If they're the same length, test each element
- if (a1.length == a2.length) {
- for (int i = 0; i < a1.length; i++) {
- if (a1[i] != a2[i]) {
- return false;
- }
- }
- return true;
+ if (a1 == a2)
+ {
+ return true;
}
+
+ try
+ {
+ // If they're the same length, test each element
+ if (a1.length == a2.length)
+ {
+ for (int i = 0; i < a1.length; i++)
+ {
+ if (a1[i] != a2[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
- // If a1 == null or a2 == null but not both then we will get a NullPointer
- } catch (NullPointerException e) {
- }
+ // If a1 == null or a2 == null but not both then we will get a NullPointer
+ }
+ catch (NullPointerException e)
+ {
+ }
return false;
}
* @returns true if a1 and a2 are both null, or if a2 is of the same length
* as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
*/
- public static boolean equals(long[] a1, long[] a2) {
-
+ public static boolean equals(long[]a1, long[]a2)
+ {
// Quick test which saves comparing elements of the same array, and also
// catches the case that both are null.
- if (a1 == a2) {
- return true;
- }
- try {
-
- // If they're the same length, test each element
- if (a1.length == a2.length) {
- for (int i = 0; i < a1.length; i++) {
- if (a1[i] != a2[i]) {
- return false;
- }
- }
- return true;
+ if (a1 == a2)
+ {
+ return true;
}
+
+ try
+ {
+ // If they're the same length, test each element
+ if (a1.length == a2.length)
+ {
+ for (int i = 0; i < a1.length; i++)
+ {
+ if (a1[i] != a2[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
- // If a1 == null or a2 == null but not both then we will get a NullPointer
- } catch (NullPointerException e) {
- }
+ // If a1 == null or a2 == null but not both then we will get a NullPointer
+ }
+ catch (NullPointerException e)
+ {
+ }
return false;
}
* @returns true if a1 and a2 are both null, or if a2 is of the same length
* as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
*/
- public static boolean equals(short[] a1, short[] a2) {
-
+ public static boolean equals(short[]a1, short[]a2)
+ {
// Quick test which saves comparing elements of the same array, and also
// catches the case that both are null.
- if (a1 == a2) {
- return true;
- }
- try {
-
- // If they're the same length, test each element
- if (a1.length == a2.length) {
- for (int i = 0; i < a1.length; i++) {
- if (a1[i] != a2[i]) {
- return false;
- }
- }
- return true;
+ if (a1 == a2)
+ {
+ return true;
}
+
+ try
+ {
+ // If they're the same length, test each element
+ if (a1.length == a2.length)
+ {
+ for (int i = 0; i < a1.length; i++)
+ {
+ if (a1[i] != a2[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
- // If a1 == null or a2 == null but not both then we will get a NullPointer
- } catch (NullPointerException e) {
- }
+ // If a1 == null or a2 == null but not both then we will get a NullPointer
+ }
+ catch (NullPointerException e)
+ {
+ }
return false;
}
* @returns true if a1 and a2 are both null, or if a2 is of the same length
* as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
*/
- public static boolean equals(boolean[] a1, boolean[] a2) {
-
+ public static boolean equals(boolean[]a1, boolean[]a2)
+ {
// Quick test which saves comparing elements of the same array, and also
// catches the case that both are null.
- if (a1 == a2) {
- return true;
- }
- try {
-
- // If they're the same length, test each element
- if (a1.length == a2.length) {
- for (int i = 0; i < a1.length; i++) {
- if (a1[i] != a2[i]) {
- return false;
- }
- }
- return true;
+ if (a1 == a2)
+ {
+ return true;
}
+
+ try
+ {
+ // If they're the same length, test each element
+ if (a1.length == a2.length)
+ {
+ for (int i = 0; i < a1.length; i++)
+ {
+ if (a1[i] != a2[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
- // If a1 == null or a2 == null but not both then we will get a NullPointer
- } catch (NullPointerException e) {
- }
+ // If a1 == null or a2 == null but not both then we will get a NullPointer
+ }
+ catch (NullPointerException e)
+ {
+ }
return false;
}
* @returns true if a1 and a2 are both null, or if a2 is of the same length
* as a1, and for each 0 <= i < a1.length, a1[i] == a2[i]
*/
- public static boolean equals(int[] a1, int[] a2) {
-
+ public static boolean equals(int[]a1, int[]a2)
+ {
// Quick test which saves comparing elements of the same array, and also
// catches the case that both are null.
- if (a1 == a2) {
- return true;
- }
- try {
-
- // If they're the same length, test each element
- if (a1.length == a2.length) {
- for (int i = 0; i < a1.length; i++) {
- if (a1[i] != a2[i]) {
- return false;
- }
- }
- return true;
+ if (a1 == a2)
+ {
+ return true;
}
+
+ try
+ {
+ // If they're the same length, test each element
+ if (a1.length == a2.length)
+ {
+ for (int i = 0; i < a1.length; i++)
+ {
+ if (a1[i] != a2[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
- // If a1 == null or a2 == null but not both then we will get a NullPointer
- } catch (NullPointerException e) {
- }
+ // If a1 == null or a2 == null but not both then we will get a NullPointer
+ }
+ catch (NullPointerException e)
+ {
+ }
return false;
}
* as a2, and for each 0 <= i < a.length, a1[i] == null ? a2[i] == null :
* a1[i].equals(a2[i]).
*/
- public static boolean equals(Object[] a1, Object[] a2) {
-
+ public static boolean equals(Object[]a1, Object[]a2)
+ {
// Quick test which saves comparing elements of the same array, and also
// catches the case that both are null.
- if (a1 == a2) {
- return true;
- }
- try {
-
- // If they're the same length, test each element
- if (a1.length == a2.length) {
- for (int i = 0; i < a1.length; i++) {
- if (!(a1[i] == null ? a2[i] == null : a1[i].equals(a2[i]))) {
- return false;
- }
- }
- return true;
+ if (a1 == a2)
+ {
+ return true;
}
+
+ try
+ {
+ // If they're the same length, test each element
+ if (a1.length == a2.length)
+ {
+ for (int i = 0; i < a1.length; i++)
+ {
+ if (!(a1[i] == null ? a2[i] == null : a1[i].equals(a2[i])))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
- // If a1 == null or a2 == null but not both then we will get a NullPointer
- } catch (NullPointerException e) {
- }
+ // If a1 == null or a2 == null but not both then we will get a NullPointer
+ }
+ catch (NullPointerException e)
+ {
+ }
return false;
}
* @param a the array to fill
* @param val the value to fill it with
*/
- public static void fill(boolean[] a, boolean val) {
+ public static void fill(boolean[]a, boolean val)
+ {
// This implementation is slightly inefficient timewise, but the extra
// effort over inlining it is O(1) and small, and I refuse to repeat code
// if it can be helped.
* @param toIndex the index to fill to, exclusive
* @param val the value to fill with
*/
- public static void fill(boolean[] a, int fromIndex, int toIndex,
- boolean val) {
- for (int i = fromIndex; i < toIndex; i++) {
- a[i] = val;
- }
+ public static void fill(boolean[]a, int fromIndex, int toIndex, boolean val)
+ {
+ for (int i = fromIndex; i < toIndex; i++)
+ {
+ a[i] = val;
+ }
}
/**
* @param a the array to fill
* @param val the value to fill it with
*/
- public static void fill(byte[] a, byte val) {
+ public static void fill(byte[]a, byte val)
+ {
// This implementation is slightly inefficient timewise, but the extra
// effort over inlining it is O(1) and small, and I refuse to repeat code
// if it can be helped.
* @param toIndex the index to fill to, exclusive
* @param val the value to fill with
*/
- public static void fill(byte[] a, int fromIndex, int toIndex, byte val) {
- for (int i = fromIndex; i < toIndex; i++) {
- a[i] = val;
- }
+ public static void fill(byte[]a, int fromIndex, int toIndex, byte val)
+ {
+ for (int i = fromIndex; i < toIndex; i++)
+ {
+ a[i] = val;
+ }
}
/**
* @param a the array to fill
* @param val the value to fill it with
*/
- public static void fill(char[] a, char val) {
+ public static void fill(char[]a, char val)
+ {
// This implementation is slightly inefficient timewise, but the extra
// effort over inlining it is O(1) and small, and I refuse to repeat code
// if it can be helped.
* @param toIndex the index to fill to, exclusive
* @param val the value to fill with
*/
- public static void fill(char[] a, int fromIndex, int toIndex, char val) {
- for (int i = fromIndex; i < toIndex; i++) {
- a[i] = val;
- }
+ public static void fill(char[]a, int fromIndex, int toIndex, char val)
+ {
+ for (int i = fromIndex; i < toIndex; i++)
+ {
+ a[i] = val;
+ }
}
/**
* @param a the array to fill
* @param val the value to fill it with
*/
- public static void fill(double[] a, double val) {
+ public static void fill(double[]a, double val)
+ {
// This implementation is slightly inefficient timewise, but the extra
// effort over inlining it is O(1) and small, and I refuse to repeat code
// if it can be helped.
* @param toIndex the index to fill to, exclusive
* @param val the value to fill with
*/
- public static void fill(double[] a, int fromIndex, int toIndex, double val) {
- for (int i = fromIndex; i < toIndex; i++) {
- a[i] = val;
- }
+ public static void fill(double[]a, int fromIndex, int toIndex, double val)
+ {
+ for (int i = fromIndex; i < toIndex; i++)
+ {
+ a[i] = val;
+ }
}
/**
* @param a the array to fill
* @param val the value to fill it with
*/
- public static void fill(float[] a, float val) {
+ public static void fill(float[]a, float val)
+ {
// This implementation is slightly inefficient timewise, but the extra
// effort over inlining it is O(1) and small, and I refuse to repeat code
// if it can be helped.
* @param toIndex the index to fill to, exclusive
* @param val the value to fill with
*/
- public static void fill(float[] a, int fromIndex, int toIndex, float val) {
- for (int i = fromIndex; i < toIndex; i++) {
- a[i] = val;
- }
+ public static void fill(float[]a, int fromIndex, int toIndex, float val)
+ {
+ for (int i = fromIndex; i < toIndex; i++)
+ {
+ a[i] = val;
+ }
}
/**
* @param a the array to fill
* @param val the value to fill it with
*/
- public static void fill(int[] a, int val) {
+ public static void fill(int[]a, int val)
+ {
// This implementation is slightly inefficient timewise, but the extra
// effort over inlining it is O(1) and small, and I refuse to repeat code
// if it can be helped.
* @param toIndex the index to fill to, exclusive
* @param val the value to fill with
*/
- public static void fill(int[] a, int fromIndex, int toIndex, int val) {
- for (int i = fromIndex; i < toIndex; i++) {
- a[i] = val;
- }
+ public static void fill(int[]a, int fromIndex, int toIndex, int val)
+ {
+ for (int i = fromIndex; i < toIndex; i++)
+ {
+ a[i] = val;
+ }
}
/**
* @param a the array to fill
* @param val the value to fill it with
*/
- public static void fill(long[] a, long val) {
+ public static void fill(long[]a, long val)
+ {
// This implementation is slightly inefficient timewise, but the extra
// effort over inlining it is O(1) and small, and I refuse to repeat code
// if it can be helped.
* @param toIndex the index to fill to, exclusive
* @param val the value to fill with
*/
- public static void fill(long[] a, int fromIndex, int toIndex, long val) {
- for (int i = fromIndex; i < toIndex; i++) {
- a[i] = val;
- }
+ public static void fill(long[]a, int fromIndex, int toIndex, long val)
+ {
+ for (int i = fromIndex; i < toIndex; i++)
+ {
+ a[i] = val;
+ }
}
/**
* @param a the array to fill
* @param val the value to fill it with
*/
- public static void fill(short[] a, short val) {
+ public static void fill(short[]a, short val)
+ {
// This implementation is slightly inefficient timewise, but the extra
// effort over inlining it is O(1) and small, and I refuse to repeat code
// if it can be helped.
* @param toIndex the index to fill to, exclusive
* @param val the value to fill with
*/
- public static void fill(short[] a, int fromIndex, int toIndex, short val) {
- for (int i = fromIndex; i < toIndex; i++) {
- a[i] = val;
- }
+ public static void fill(short[]a, int fromIndex, int toIndex, short val)
+ {
+ for (int i = fromIndex; i < toIndex; i++)
+ {
+ a[i] = val;
+ }
}
/**
* @exception ClassCastException if val is not an instance of the element
* type of a.
*/
- public static void fill(Object[] a, Object val) {
+ public static void fill(Object[]a, Object val)
+ {
// This implementation is slightly inefficient timewise, but the extra
// effort over inlining it is O(1) and small, and I refuse to repeat code
// if it can be helped.
* @exception ClassCastException if val is not an instance of the element
* type of a.
*/
- public static void fill(Object[] a, int fromIndex, int toIndex, Object val) {
- for (int i = fromIndex; i < toIndex; i++) {
- a[i] = val;
- }
+ public static void fill(Object[]a, int fromIndex, int toIndex, Object val)
+ {
+ for (int i = fromIndex; i < toIndex; i++)
+ {
+ a[i] = val;
+ }
}
// Thanks to Paul Fisher <rao@gnu.org> for finding this quicksort algorithm
*
* @param a the array to sort
*/
- public static void sort(byte[] a) {
+ public static void sort(byte[]a)
+ {
qsort(a, 0, a.length);
}
- private static short cmp(byte i, byte j) {
- return (short)(i-j);
+ public static void sort(byte[] a, int fromIndex, int toIndex)
+ {
+ qsort(a, fromIndex, toIndex);
}
- private static int med3(int a, int b, int c, byte[] d) {
- return cmp(d[a], d[b]) < 0 ?
+ private static short cmp(byte i, byte j)
+ {
+ return (short) (i - j);
+ }
+
+ private static int med3(int a, int b, int c, byte[]d)
+ {
+ return cmp(d[a], d[b]) < 0 ?
(cmp(d[b], d[c]) < 0 ? b : cmp(d[a], d[c]) < 0 ? c : a)
- : (cmp(d[b], d[c]) > 0 ? b : cmp(d[a], d[c]) > 0 ? c : a);
+ : (cmp(d[b], d[c]) > 0 ? b : cmp(d[a], d[c]) > 0 ? c : a);
}
-
- private static void swap(int i, int j, byte[] a) {
+
+ private static void swap(int i, int j, byte[]a)
+ {
byte c = a[i];
a[i] = a[j];
a[j] = c;
}
- private static void qsort(byte[] a, int start, int n) {
+ private static void qsort(byte[]a, int start, int n)
+ {
// use an insertion sort on small arrays
- if (n < 7) {
- for (int i = start + 1; i < start + n; i++)
- for (int j = i; j > 0 && cmp(a[j-1], a[j]) > 0; j--)
- swap(j, j-1, a);
- return;
- }
-
- int pm = n/2; // small arrays, middle element
- if (n > 7) {
- int pl = start;
- int pn = start + n-1;
+ if (n < 7)
+ {
+ for (int i = start + 1; i < start + n; i++)
+ for (int j = i; j > 0 && cmp(a[j - 1], a[j]) > 0; j--)
+ swap(j, j - 1, a);
+ return;
+ }
- if (n > 40) { // big arrays, pseudomedian of 9
- int s = n/8;
- pl = med3(pl, pl+s, pl+2*s, a);
- pm = med3(pm-s, pm, pm+s, a);
- pn = med3(pn-2*s, pn-s, pn, a);
+ int pm = n / 2; // small arrays, middle element
+ if (n > 7)
+ {
+ int pl = start;
+ int pn = start + n - 1;
+
+ if (n > 40)
+ { // big arrays, pseudomedian of 9
+ int s = n / 8;
+ pl = med3(pl, pl + s, pl + 2 * s, a);
+ pm = med3(pm - s, pm, pm + s, a);
+ pn = med3(pn - 2 * s, pn - s, pn, a);
+ }
+ pm = med3(pl, pm, pn, a); // mid-size, med of 3
}
- pm = med3(pl, pm, pn, a); // mid-size, med of 3
- }
int pa, pb, pc, pd, pv;
short r;
- pv = start; swap(pv, pm, a);
+ pv = start;
+ swap(pv, pm, a);
pa = pb = start;
- pc = pd = start + n-1;
-
- for (;;) {
- while (pb <= pc && (r = cmp(a[pb], a[pv])) <= 0) {
- if (r == 0) { swap(pa, pb, a); pa++; }
- pb++;
- }
- while (pc >= pb && (r = cmp(a[pc], a[pv])) >= 0) {
- if (r == 0) { swap(pc, pd, a); pd--; }
- pc--;
- }
- if (pb > pc) break;
- swap(pb, pc, a);
- pb++;
- pc--;
- }
+ pc = pd = start + n - 1;
+
+ for (;;)
+ {
+ while (pb <= pc && (r = cmp(a[pb], a[pv])) <= 0)
+ {
+ if (r == 0)
+ {
+ swap(pa, pb, a);
+ pa++;
+ }
+ pb++;
+ }
+ while (pc >= pb && (r = cmp(a[pc], a[pv])) >= 0)
+ {
+ if (r == 0)
+ {
+ swap(pc, pd, a);
+ pd--;
+ }
+ pc--;
+ }
+ if (pb > pc)
+ break;
+ swap(pb, pc, a);
+ pb++;
+ pc--;
+ }
int pn = start + n;
int s;
- s = Math.min(pa-start, pb-pa); vecswap(start, pb-s, s, a);
- s = Math.min(pd-pc, pn-pd-1); vecswap(pb, pn-s, s, a);
- if ((s = pb-pa) > 1) qsort(a, start, s);
- if ((s = pd-pc) > 1) qsort(a, pn-s, s);
+ s = Math.min(pa - start, pb - pa);
+ vecswap(start, pb - s, s, a);
+ s = Math.min(pd - pc, pn - pd - 1);
+ vecswap(pb, pn - s, s, a);
+ if ((s = pb - pa) > 1)
+ qsort(a, start, s);
+ if ((s = pd - pc) > 1)
+ qsort(a, pn - s, s);
}
- private static void vecswap(int i, int j, int n, byte[] a) {
+ private static void vecswap(int i, int j, int n, byte[]a)
+ {
for (; n > 0; i++, j++, n--)
swap(i, j, a);
}
*
* @param a the array to sort
*/
- public static void sort(char[] a) {
+ public static void sort(char[]a)
+ {
qsort(a, 0, a.length);
}
- private static int cmp(char i, char j) {
- return i-j;
+ public static void sort(char[] a, int fromIndex, int toIndex)
+ {
+ qsort(a, fromIndex, toIndex);
+ }
+
+ private static int cmp(char i, char j)
+ {
+ return i - j;
}
- private static int med3(int a, int b, int c, char[] d) {
- return cmp(d[a], d[b]) < 0 ?
+ private static int med3(int a, int b, int c, char[]d)
+ {
+ return cmp(d[a], d[b]) < 0 ?
(cmp(d[b], d[c]) < 0 ? b : cmp(d[a], d[c]) < 0 ? c : a)
- : (cmp(d[b], d[c]) > 0 ? b : cmp(d[a], d[c]) > 0 ? c : a);
+ : (cmp(d[b], d[c]) > 0 ? b : cmp(d[a], d[c]) > 0 ? c : a);
}
-
- private static void swap(int i, int j, char[] a) {
+
+ private static void swap(int i, int j, char[]a)
+ {
char c = a[i];
a[i] = a[j];
a[j] = c;
}
- private static void qsort(char[] a, int start, int n) {
+ private static void qsort(char[]a, int start, int n)
+ {
// use an insertion sort on small arrays
- if (n < 7) {
- for (int i = start + 1; i < start + n; i++)
- for (int j = i; j > 0 && cmp(a[j-1], a[j]) > 0; j--)
- swap(j, j-1, a);
- return;
- }
-
- int pm = n/2; // small arrays, middle element
- if (n > 7) {
- int pl = start;
- int pn = start + n-1;
+ if (n < 7)
+ {
+ for (int i = start + 1; i < start + n; i++)
+ for (int j = i; j > 0 && cmp(a[j - 1], a[j]) > 0; j--)
+ swap(j, j - 1, a);
+ return;
+ }
- if (n > 40) { // big arrays, pseudomedian of 9
- int s = n/8;
- pl = med3(pl, pl+s, pl+2*s, a);
- pm = med3(pm-s, pm, pm+s, a);
- pn = med3(pn-2*s, pn-s, pn, a);
+ int pm = n / 2; // small arrays, middle element
+ if (n > 7)
+ {
+ int pl = start;
+ int pn = start + n - 1;
+
+ if (n > 40)
+ { // big arrays, pseudomedian of 9
+ int s = n / 8;
+ pl = med3(pl, pl + s, pl + 2 * s, a);
+ pm = med3(pm - s, pm, pm + s, a);
+ pn = med3(pn - 2 * s, pn - s, pn, a);
+ }
+ pm = med3(pl, pm, pn, a); // mid-size, med of 3
}
- pm = med3(pl, pm, pn, a); // mid-size, med of 3
- }
int pa, pb, pc, pd, pv;
int r;
- pv = start; swap(pv, pm, a);
+ pv = start;
+ swap(pv, pm, a);
pa = pb = start;
- pc = pd = start + n-1;
-
- for (;;) {
- while (pb <= pc && (r = cmp(a[pb], a[pv])) <= 0) {
- if (r == 0) { swap(pa, pb, a); pa++; }
- pb++;
- }
- while (pc >= pb && (r = cmp(a[pc], a[pv])) >= 0) {
- if (r == 0) { swap(pc, pd, a); pd--; }
- pc--;
- }
- if (pb > pc) break;
- swap(pb, pc, a);
- pb++;
- pc--;
- }
+ pc = pd = start + n - 1;
+
+ for (;;)
+ {
+ while (pb <= pc && (r = cmp(a[pb], a[pv])) <= 0)
+ {
+ if (r == 0)
+ {
+ swap(pa, pb, a);
+ pa++;
+ }
+ pb++;
+ }
+ while (pc >= pb && (r = cmp(a[pc], a[pv])) >= 0)
+ {
+ if (r == 0)
+ {
+ swap(pc, pd, a);
+ pd--;
+ }
+ pc--;
+ }
+ if (pb > pc)
+ break;
+ swap(pb, pc, a);
+ pb++;
+ pc--;
+ }
int pn = start + n;
int s;
- s = Math.min(pa-start, pb-pa); vecswap(start, pb-s, s, a);
- s = Math.min(pd-pc, pn-pd-1); vecswap(pb, pn-s, s, a);
- if ((s = pb-pa) > 1) qsort(a, start, s);
- if ((s = pd-pc) > 1) qsort(a, pn-s, s);
+ s = Math.min(pa - start, pb - pa);
+ vecswap(start, pb - s, s, a);
+ s = Math.min(pd - pc, pn - pd - 1);
+ vecswap(pb, pn - s, s, a);
+ if ((s = pb - pa) > 1)
+ qsort(a, start, s);
+ if ((s = pd - pc) > 1)
+ qsort(a, pn - s, s);
}
- private static void vecswap(int i, int j, int n, char[] a) {
+ private static void vecswap(int i, int j, int n, char[]a)
+ {
for (; n > 0; i++, j++, n--)
swap(i, j, a);
}
*
* @param a the array to sort
*/
- public static void sort(double[] a) {
+ public static void sort(double[]a)
+ {
qsort(a, 0, a.length);
}
- private static double cmp(double i, double j) {
- return i-j;
+ public static void sort(double[] a, int fromIndex, int toIndex)
+ {
+ qsort(a, fromIndex, toIndex);
}
- private static int med3(int a, int b, int c, double[] d) {
- return cmp(d[a], d[b]) < 0 ?
+ private static double cmp(double i, double j)
+ {
+ return i - j;
+ }
+
+ private static int med3(int a, int b, int c, double[]d)
+ {
+ return cmp(d[a], d[b]) < 0 ?
(cmp(d[b], d[c]) < 0 ? b : cmp(d[a], d[c]) < 0 ? c : a)
- : (cmp(d[b], d[c]) > 0 ? b : cmp(d[a], d[c]) > 0 ? c : a);
+ : (cmp(d[b], d[c]) > 0 ? b : cmp(d[a], d[c]) > 0 ? c : a);
}
-
- private static void swap(int i, int j, double[] a) {
+
+ private static void swap(int i, int j, double[]a)
+ {
double c = a[i];
a[i] = a[j];
a[j] = c;
}
- private static void qsort(double[] a, int start, int n) {
+ private static void qsort(double[]a, int start, int n)
+ {
// use an insertion sort on small arrays
- if (n < 7) {
- for (int i = start + 1; i < start + n; i++)
- for (int j = i; j > 0 && cmp(a[j-1], a[j]) > 0; j--)
- swap(j, j-1, a);
- return;
- }
-
- int pm = n/2; // small arrays, middle element
- if (n > 7) {
- int pl = start;
- int pn = start + n-1;
+ if (n < 7)
+ {
+ for (int i = start + 1; i < start + n; i++)
+ for (int j = i; j > 0 && cmp(a[j - 1], a[j]) > 0; j--)
+ swap(j, j - 1, a);
+ return;
+ }
- if (n > 40) { // big arrays, pseudomedian of 9
- int s = n/8;
- pl = med3(pl, pl+s, pl+2*s, a);
- pm = med3(pm-s, pm, pm+s, a);
- pn = med3(pn-2*s, pn-s, pn, a);
+ int pm = n / 2; // small arrays, middle element
+ if (n > 7)
+ {
+ int pl = start;
+ int pn = start + n - 1;
+
+ if (n > 40)
+ { // big arrays, pseudomedian of 9
+ int s = n / 8;
+ pl = med3(pl, pl + s, pl + 2 * s, a);
+ pm = med3(pm - s, pm, pm + s, a);
+ pn = med3(pn - 2 * s, pn - s, pn, a);
+ }
+ pm = med3(pl, pm, pn, a); // mid-size, med of 3
}
- pm = med3(pl, pm, pn, a); // mid-size, med of 3
- }
int pa, pb, pc, pd, pv;
double r;
- pv = start; swap(pv, pm, a);
+ pv = start;
+ swap(pv, pm, a);
pa = pb = start;
- pc = pd = start + n-1;
-
- for (;;) {
- while (pb <= pc && (r = cmp(a[pb], a[pv])) <= 0) {
- if (r == 0) { swap(pa, pb, a); pa++; }
- pb++;
- }
- while (pc >= pb && (r = cmp(a[pc], a[pv])) >= 0) {
- if (r == 0) { swap(pc, pd, a); pd--; }
- pc--;
- }
- if (pb > pc) break;
- swap(pb, pc, a);
- pb++;
- pc--;
- }
+ pc = pd = start + n - 1;
+
+ for (;;)
+ {
+ while (pb <= pc && (r = cmp(a[pb], a[pv])) <= 0)
+ {
+ if (r == 0)
+ {
+ swap(pa, pb, a);
+ pa++;
+ }
+ pb++;
+ }
+ while (pc >= pb && (r = cmp(a[pc], a[pv])) >= 0)
+ {
+ if (r == 0)
+ {
+ swap(pc, pd, a);
+ pd--;
+ }
+ pc--;
+ }
+ if (pb > pc)
+ break;
+ swap(pb, pc, a);
+ pb++;
+ pc--;
+ }
int pn = start + n;
int s;
- s = Math.min(pa-start, pb-pa); vecswap(start, pb-s, s, a);
- s = Math.min(pd-pc, pn-pd-1); vecswap(pb, pn-s, s, a);
- if ((s = pb-pa) > 1) qsort(a, start, s);
- if ((s = pd-pc) > 1) qsort(a, pn-s, s);
+ s = Math.min(pa - start, pb - pa);
+ vecswap(start, pb - s, s, a);
+ s = Math.min(pd - pc, pn - pd - 1);
+ vecswap(pb, pn - s, s, a);
+ if ((s = pb - pa) > 1)
+ qsort(a, start, s);
+ if ((s = pd - pc) > 1)
+ qsort(a, pn - s, s);
}
- private static void vecswap(int i, int j, int n, double[] a) {
+ private static void vecswap(int i, int j, int n, double[]a)
+ {
for (; n > 0; i++, j++, n--)
swap(i, j, a);
}
*
* @param a the array to sort
*/
- public static void sort(float[] a) {
+ public static void sort(float[]a)
+ {
qsort(a, 0, a.length);
}
- private static float cmp(float i, float j) {
- return i-j;
+ public static void sort(float[] a, int fromIndex, int toIndex)
+ {
+ qsort(a, fromIndex, toIndex);
+ }
+
+ private static float cmp(float i, float j)
+ {
+ return i - j;
}
- private static int med3(int a, int b, int c, float[] d) {
- return cmp(d[a], d[b]) < 0 ?
+ private static int med3(int a, int b, int c, float[]d)
+ {
+ return cmp(d[a], d[b]) < 0 ?
(cmp(d[b], d[c]) < 0 ? b : cmp(d[a], d[c]) < 0 ? c : a)
- : (cmp(d[b], d[c]) > 0 ? b : cmp(d[a], d[c]) > 0 ? c : a);
+ : (cmp(d[b], d[c]) > 0 ? b : cmp(d[a], d[c]) > 0 ? c : a);
}
- private static void swap(int i, int j, float[] a) {
+ private static void swap(int i, int j, float[]a)
+ {
float c = a[i];
a[i] = a[j];
a[j] = c;
}
- private static void qsort(float[] a, int start, int n) {
+ private static void qsort(float[]a, int start, int n)
+ {
// use an insertion sort on small arrays
- if (n < 7) {
- for (int i = start + 1; i < start + n; i++)
- for (int j = i; j > 0 && cmp(a[j-1], a[j]) > 0; j--)
- swap(j, j-1, a);
- return;
- }
-
- int pm = n/2; // small arrays, middle element
- if (n > 7) {
- int pl = start;
- int pn = start + n-1;
+ if (n < 7)
+ {
+ for (int i = start + 1; i < start + n; i++)
+ for (int j = i; j > 0 && cmp(a[j - 1], a[j]) > 0; j--)
+ swap(j, j - 1, a);
+ return;
+ }
- if (n > 40) { // big arrays, pseudomedian of 9
- int s = n/8;
- pl = med3(pl, pl+s, pl+2*s, a);
- pm = med3(pm-s, pm, pm+s, a);
- pn = med3(pn-2*s, pn-s, pn, a);
+ int pm = n / 2; // small arrays, middle element
+ if (n > 7)
+ {
+ int pl = start;
+ int pn = start + n - 1;
+
+ if (n > 40)
+ { // big arrays, pseudomedian of 9
+ int s = n / 8;
+ pl = med3(pl, pl + s, pl + 2 * s, a);
+ pm = med3(pm - s, pm, pm + s, a);
+ pn = med3(pn - 2 * s, pn - s, pn, a);
+ }
+ pm = med3(pl, pm, pn, a); // mid-size, med of 3
}
- pm = med3(pl, pm, pn, a); // mid-size, med of 3
- }
int pa, pb, pc, pd, pv;
float r;
- pv = start; swap(pv, pm, a);
+ pv = start;
+ swap(pv, pm, a);
pa = pb = start;
- pc = pd = start + n-1;
-
- for (;;) {
- while (pb <= pc && (r = cmp(a[pb], a[pv])) <= 0) {
- if (r == 0) { swap(pa, pb, a); pa++; }
- pb++;
- }
- while (pc >= pb && (r = cmp(a[pc], a[pv])) >= 0) {
- if (r == 0) { swap(pc, pd, a); pd--; }
- pc--;
- }
- if (pb > pc) break;
- swap(pb, pc, a);
- pb++;
- pc--;
- }
+ pc = pd = start + n - 1;
+
+ for (;;)
+ {
+ while (pb <= pc && (r = cmp(a[pb], a[pv])) <= 0)
+ {
+ if (r == 0)
+ {
+ swap(pa, pb, a);
+ pa++;
+ }
+ pb++;
+ }
+ while (pc >= pb && (r = cmp(a[pc], a[pv])) >= 0)
+ {
+ if (r == 0)
+ {
+ swap(pc, pd, a);
+ pd--;
+ }
+ pc--;
+ }
+ if (pb > pc)
+ break;
+ swap(pb, pc, a);
+ pb++;
+ pc--;
+ }
int pn = start + n;
int s;
- s = Math.min(pa-start, pb-pa); vecswap(start, pb-s, s, a);
- s = Math.min(pd-pc, pn-pd-1); vecswap(pb, pn-s, s, a);
- if ((s = pb-pa) > 1) qsort(a, start, s);
- if ((s = pd-pc) > 1) qsort(a, pn-s, s);
+ s = Math.min(pa - start, pb - pa);
+ vecswap(start, pb - s, s, a);
+ s = Math.min(pd - pc, pn - pd - 1);
+ vecswap(pb, pn - s, s, a);
+ if ((s = pb - pa) > 1)
+ qsort(a, start, s);
+ if ((s = pd - pc) > 1)
+ qsort(a, pn - s, s);
}
- private static void vecswap(int i, int j, int n, float[] a) {
+ private static void vecswap(int i, int j, int n, float[]a)
+ {
for (; n > 0; i++, j++, n--)
swap(i, j, a);
}
*
* @param a the array to sort
*/
- public static void sort(int[] a) {
+ public static void sort(int[]a)
+ {
qsort(a, 0, a.length);
}
- private static long cmp(int i, int j) {
- return (long)i-(long)j;
+ public static void sort(int[] a, int fromIndex, int toIndex)
+ {
+ qsort(a, fromIndex, toIndex);
+ }
+
+ private static long cmp(int i, int j)
+ {
+ return (long) i - (long) j;
}
- private static int med3(int a, int b, int c, int[] d) {
- return cmp(d[a], d[b]) < 0 ?
+ private static int med3(int a, int b, int c, int[]d)
+ {
+ return cmp(d[a], d[b]) < 0 ?
(cmp(d[b], d[c]) < 0 ? b : cmp(d[a], d[c]) < 0 ? c : a)
- : (cmp(d[b], d[c]) > 0 ? b : cmp(d[a], d[c]) > 0 ? c : a);
+ : (cmp(d[b], d[c]) > 0 ? b : cmp(d[a], d[c]) > 0 ? c : a);
}
-
- private static void swap(int i, int j, int[] a) {
+
+ private static void swap(int i, int j, int[]a)
+ {
int c = a[i];
a[i] = a[j];
a[j] = c;
}
- private static void qsort(int[] a, int start, int n) {
+ private static void qsort(int[]a, int start, int n)
+ {
// use an insertion sort on small arrays
- if (n < 7) {
- for (int i = start + 1; i < start + n; i++)
- for (int j = i; j > 0 && cmp(a[j-1], a[j]) > 0; j--)
- swap(j, j-1, a);
- return;
- }
-
- int pm = n/2; // small arrays, middle element
- if (n > 7) {
- int pl = start;
- int pn = start + n-1;
+ if (n < 7)
+ {
+ for (int i = start + 1; i < start + n; i++)
+ for (int j = i; j > 0 && cmp(a[j - 1], a[j]) > 0; j--)
+ swap(j, j - 1, a);
+ return;
+ }
- if (n > 40) { // big arrays, pseudomedian of 9
- int s = n/8;
- pl = med3(pl, pl+s, pl+2*s, a);
- pm = med3(pm-s, pm, pm+s, a);
- pn = med3(pn-2*s, pn-s, pn, a);
+ int pm = n / 2; // small arrays, middle element
+ if (n > 7)
+ {
+ int pl = start;
+ int pn = start + n - 1;
+
+ if (n > 40)
+ { // big arrays, pseudomedian of 9
+ int s = n / 8;
+ pl = med3(pl, pl + s, pl + 2 * s, a);
+ pm = med3(pm - s, pm, pm + s, a);
+ pn = med3(pn - 2 * s, pn - s, pn, a);
+ }
+ pm = med3(pl, pm, pn, a); // mid-size, med of 3
}
- pm = med3(pl, pm, pn, a); // mid-size, med of 3
- }
int pa, pb, pc, pd, pv;
long r;
- pv = start; swap(pv, pm, a);
+ pv = start;
+ swap(pv, pm, a);
pa = pb = start;
- pc = pd = start + n-1;
-
- for (;;) {
- while (pb <= pc && (r = cmp(a[pb], a[pv])) <= 0) {
- if (r == 0) { swap(pa, pb, a); pa++; }
- pb++;
- }
- while (pc >= pb && (r = cmp(a[pc], a[pv])) >= 0) {
- if (r == 0) { swap(pc, pd, a); pd--; }
- pc--;
- }
- if (pb > pc) break;
- swap(pb, pc, a);
- pb++;
- pc--;
- }
+ pc = pd = start + n - 1;
+
+ for (;;)
+ {
+ while (pb <= pc && (r = cmp(a[pb], a[pv])) <= 0)
+ {
+ if (r == 0)
+ {
+ swap(pa, pb, a);
+ pa++;
+ }
+ pb++;
+ }
+ while (pc >= pb && (r = cmp(a[pc], a[pv])) >= 0)
+ {
+ if (r == 0)
+ {
+ swap(pc, pd, a);
+ pd--;
+ }
+ pc--;
+ }
+ if (pb > pc)
+ break;
+ swap(pb, pc, a);
+ pb++;
+ pc--;
+ }
int pn = start + n;
int s;
- s = Math.min(pa-start, pb-pa); vecswap(start, pb-s, s, a);
- s = Math.min(pd-pc, pn-pd-1); vecswap(pb, pn-s, s, a);
- if ((s = pb-pa) > 1) qsort(a, start, s);
- if ((s = pd-pc) > 1) qsort(a, pn-s, s);
+ s = Math.min(pa - start, pb - pa);
+ vecswap(start, pb - s, s, a);
+ s = Math.min(pd - pc, pn - pd - 1);
+ vecswap(pb, pn - s, s, a);
+ if ((s = pb - pa) > 1)
+ qsort(a, start, s);
+ if ((s = pd - pc) > 1)
+ qsort(a, pn - s, s);
}
- private static void vecswap(int i, int j, int n, int[] a) {
+ private static void vecswap(int i, int j, int n, int[]a)
+ {
for (; n > 0; i++, j++, n--)
swap(i, j, a);
}
*
* @param a the array to sort
*/
- public static void sort(long[] a) {
+ public static void sort(long[]a)
+ {
qsort(a, 0, a.length);
}
+ public static void sort(long[] a, int fromIndex, int toIndex)
+ {
+ qsort(a, fromIndex, toIndex);
+ }
+
// The "cmp" method has been removed from here and replaced with direct
// compares in situ, to avoid problems with overflow if the difference
// between two numbers is bigger than a long will hold.
// One particular change as a result is the use of r1 and r2 in qsort
- private static int med3(int a, int b, int c, long[] d) {
- return d[a] < d[b] ?
+ private static int med3(int a, int b, int c, long[]d)
+ {
+ return d[a] < d[b] ?
(d[b] < d[c] ? b : d[a] < d[c] ? c : a)
- : (d[b] > d[c] ? b : d[a] > d[c] ? c : a);
+ : (d[b] > d[c] ? b : d[a] > d[c] ? c : a);
}
-
- private static void swap(int i, int j, long[] a) {
+
+ private static void swap(int i, int j, long[]a)
+ {
long c = a[i];
a[i] = a[j];
a[j] = c;
}
- private static void qsort(long[] a, int start, int n) {
+ private static void qsort(long[]a, int start, int n)
+ {
// use an insertion sort on small arrays
- if (n < 7) {
- for (int i = start + 1; i < start + n; i++)
- for (int j = i; j > 0 && a[j-1] > a[j]; j--)
- swap(j, j-1, a);
- return;
- }
-
- int pm = n/2; // small arrays, middle element
- if (n > 7) {
- int pl = start;
- int pn = start + n-1;
+ if (n < 7)
+ {
+ for (int i = start + 1; i < start + n; i++)
+ for (int j = i; j > 0 && a[j - 1] > a[j]; j--)
+ swap(j, j - 1, a);
+ return;
+ }
- if (n > 40) { // big arrays, pseudomedian of 9
- int s = n/8;
- pl = med3(pl, pl+s, pl+2*s, a);
- pm = med3(pm-s, pm, pm+s, a);
- pn = med3(pn-2*s, pn-s, pn, a);
+ int pm = n / 2; // small arrays, middle element
+ if (n > 7)
+ {
+ int pl = start;
+ int pn = start + n - 1;
+
+ if (n > 40)
+ { // big arrays, pseudomedian of 9
+ int s = n / 8;
+ pl = med3(pl, pl + s, pl + 2 * s, a);
+ pm = med3(pm - s, pm, pm + s, a);
+ pn = med3(pn - 2 * s, pn - s, pn, a);
+ }
+ pm = med3(pl, pm, pn, a); // mid-size, med of 3
}
- pm = med3(pl, pm, pn, a); // mid-size, med of 3
- }
int pa, pb, pc, pd, pv;
long r1, r2;
- pv = start; swap(pv, pm, a);
+ pv = start;
+ swap(pv, pm, a);
pa = pb = start;
- pc = pd = start + n-1;
-
- for (;;) {
- while (pb <= pc && (r1 = a[pb]) <= (r2 = a[pv])) {
- if (r1 == r2) { swap(pa, pb, a); pa++; }
- pb++;
- }
- while (pc >= pb && (r1 = a[pc]) >= (r2 = a[pv])) {
- if (r1 == r2) { swap(pc, pd, a); pd--; }
- pc--;
- }
- if (pb > pc) break;
- swap(pb, pc, a);
- pb++;
- pc--;
- }
+ pc = pd = start + n - 1;
+
+ for (;;)
+ {
+ while (pb <= pc && (r1 = a[pb]) <= (r2 = a[pv]))
+ {
+ if (r1 == r2)
+ {
+ swap(pa, pb, a);
+ pa++;
+ }
+ pb++;
+ }
+ while (pc >= pb && (r1 = a[pc]) >= (r2 = a[pv]))
+ {
+ if (r1 == r2)
+ {
+ swap(pc, pd, a);
+ pd--;
+ }
+ pc--;
+ }
+ if (pb > pc)
+ break;
+ swap(pb, pc, a);
+ pb++;
+ pc--;
+ }
int pn = start + n;
int s;
- s = Math.min(pa-start, pb-pa); vecswap(start, pb-s, s, a);
- s = Math.min(pd-pc, pn-pd-1); vecswap(pb, pn-s, s, a);
- if ((s = pb-pa) > 1) qsort(a, start, s);
- if ((s = pd-pc) > 1) qsort(a, pn-s, s);
+ s = Math.min(pa - start, pb - pa);
+ vecswap(start, pb - s, s, a);
+ s = Math.min(pd - pc, pn - pd - 1);
+ vecswap(pb, pn - s, s, a);
+ if ((s = pb - pa) > 1)
+ qsort(a, start, s);
+ if ((s = pd - pc) > 1)
+ qsort(a, pn - s, s);
}
- private static void vecswap(int i, int j, int n, long[] a) {
+ private static void vecswap(int i, int j, int n, long[]a)
+ {
for (; n > 0; i++, j++, n--)
swap(i, j, a);
}
*
* @param a the array to sort
*/
- public static void sort(short[] a) {
+ public static void sort(short[]a)
+ {
qsort(a, 0, a.length);
}
- private static int cmp(short i, short j) {
- return i-j;
+ public static void sort(short[] a, int fromIndex, int toIndex)
+ {
+ qsort(a, fromIndex, toIndex);
}
- private static int med3(int a, int b, int c, short[] d) {
- return cmp(d[a], d[b]) < 0 ?
+ private static int cmp(short i, short j)
+ {
+ return i - j;
+ }
+
+ private static int med3(int a, int b, int c, short[]d)
+ {
+ return cmp(d[a], d[b]) < 0 ?
(cmp(d[b], d[c]) < 0 ? b : cmp(d[a], d[c]) < 0 ? c : a)
- : (cmp(d[b], d[c]) > 0 ? b : cmp(d[a], d[c]) > 0 ? c : a);
+ : (cmp(d[b], d[c]) > 0 ? b : cmp(d[a], d[c]) > 0 ? c : a);
}
-
- private static void swap(int i, int j, short[] a) {
+
+ private static void swap(int i, int j, short[]a)
+ {
short c = a[i];
a[i] = a[j];
a[j] = c;
}
- private static void qsort(short[] a, int start, int n) {
+ private static void qsort(short[]a, int start, int n)
+ {
// use an insertion sort on small arrays
- if (n < 7) {
- for (int i = start + 1; i < start + n; i++)
- for (int j = i; j > 0 && cmp(a[j-1], a[j]) > 0; j--)
- swap(j, j-1, a);
- return;
- }
-
- int pm = n/2; // small arrays, middle element
- if (n > 7) {
- int pl = start;
- int pn = start + n-1;
+ if (n < 7)
+ {
+ for (int i = start + 1; i < start + n; i++)
+ for (int j = i; j > 0 && cmp(a[j - 1], a[j]) > 0; j--)
+ swap(j, j - 1, a);
+ return;
+ }
- if (n > 40) { // big arrays, pseudomedian of 9
- int s = n/8;
- pl = med3(pl, pl+s, pl+2*s, a);
- pm = med3(pm-s, pm, pm+s, a);
- pn = med3(pn-2*s, pn-s, pn, a);
+ int pm = n / 2; // small arrays, middle element
+ if (n > 7)
+ {
+ int pl = start;
+ int pn = start + n - 1;
+
+ if (n > 40)
+ { // big arrays, pseudomedian of 9
+ int s = n / 8;
+ pl = med3(pl, pl + s, pl + 2 * s, a);
+ pm = med3(pm - s, pm, pm + s, a);
+ pn = med3(pn - 2 * s, pn - s, pn, a);
+ }
+ pm = med3(pl, pm, pn, a); // mid-size, med of 3
}
- pm = med3(pl, pm, pn, a); // mid-size, med of 3
- }
int pa, pb, pc, pd, pv;
int r;
- pv = start; swap(pv, pm, a);
+ pv = start;
+ swap(pv, pm, a);
pa = pb = start;
- pc = pd = start + n-1;
-
- for (;;) {
- while (pb <= pc && (r = cmp(a[pb], a[pv])) <= 0) {
- if (r == 0) { swap(pa, pb, a); pa++; }
- pb++;
- }
- while (pc >= pb && (r = cmp(a[pc], a[pv])) >= 0) {
- if (r == 0) { swap(pc, pd, a); pd--; }
- pc--;
- }
- if (pb > pc) break;
- swap(pb, pc, a);
- pb++;
- pc--;
- }
+ pc = pd = start + n - 1;
+
+ for (;;)
+ {
+ while (pb <= pc && (r = cmp(a[pb], a[pv])) <= 0)
+ {
+ if (r == 0)
+ {
+ swap(pa, pb, a);
+ pa++;
+ }
+ pb++;
+ }
+ while (pc >= pb && (r = cmp(a[pc], a[pv])) >= 0)
+ {
+ if (r == 0)
+ {
+ swap(pc, pd, a);
+ pd--;
+ }
+ pc--;
+ }
+ if (pb > pc)
+ break;
+ swap(pb, pc, a);
+ pb++;
+ pc--;
+ }
int pn = start + n;
int s;
- s = Math.min(pa-start, pb-pa); vecswap(start, pb-s, s, a);
- s = Math.min(pd-pc, pn-pd-1); vecswap(pb, pn-s, s, a);
- if ((s = pb-pa) > 1) qsort(a, start, s);
- if ((s = pd-pc) > 1) qsort(a, pn-s, s);
+ s = Math.min(pa - start, pb - pa);
+ vecswap(start, pb - s, s, a);
+ s = Math.min(pd - pc, pn - pd - 1);
+ vecswap(pb, pn - s, s, a);
+ if ((s = pb - pa) > 1)
+ qsort(a, start, s);
+ if ((s = pd - pc) > 1)
+ qsort(a, pn - s, s);
}
- private static void vecswap(int i, int j, int n, short[] a) {
+ private static void vecswap(int i, int j, int n, short[]a)
+ {
for (; n > 0; i++, j++, n--)
swap(i, j, a);
}
* than I can, and if I try it will make it more confusing for the
* JIT.
*/
- private static void mergeSort(Object[] a, int from, int to, Comparator c)
+ private static void mergeSort(Object[]a, int from, int to, Comparator c)
{
// First presort the array in chunks of length 6 with insertion sort.
// mergesort would give too much overhead for this length.
for (int chunk = from; chunk < to; chunk += 6)
{
- int end = Math.min(chunk+6, to);
+ int end = Math.min(chunk + 6, to);
for (int i = chunk + 1; i < end; i++)
{
- if (c.compare(a[i-1], a[i]) > 0)
+ if (c.compare(a[i - 1], a[i]) > 0)
{
// not already sorted
- int j=i;
+ int j = i;
Object elem = a[j];
- do
+ do
{
- a[j] = a[j-1];
+ a[j] = a[j - 1];
j--;
- }
- while (j>chunk && c.compare(a[j-1], elem) > 0);
+ }
+ while (j > chunk && c.compare(a[j - 1], elem) > 0);
a[j] = elem;
}
}
}
-
+
int len = to - from;
// If length is smaller or equal 6 we are done.
if (len <= 6)
return;
- Object[] src = a;
- Object[] dest = new Object[len];
- Object[] t = null; // t is used for swapping src and dest
+ Object[]src = a;
+ Object[]dest = new Object[len];
+ Object[]t = null; // t is used for swapping src and dest
// The difference of the fromIndex of the src and dest array.
int srcDestDiff = -from;
// The merges are done in this loop
- for (int size = 6; size < len; size <<= 1)
+ for (int size = 6; size < len; size <<= 1)
{
for (int start = from; start < to; start += size << 1)
{
// end the start of the next sublist (or end of array).
int mid = start + size;
int end = Math.min(to, mid + size);
-
+
// The second list is empty or the elements are already in
// order - no need to merge
- if (mid >= end || c.compare(src[mid - 1], src[mid]) <= 0) {
- System.arraycopy(src, start,
- dest, start + srcDestDiff, end - start);
-
- // The two halves just need swapping - no need to merge
- } else if (c.compare(src[start], src[end - 1]) > 0) {
- System.arraycopy(src, start,
- dest, end - size + srcDestDiff, size);
- System.arraycopy(src, mid,
- dest, start + srcDestDiff, end - mid);
-
- } else {
- // Declare a lot of variables to save repeating
- // calculations. Hopefully a decent JIT will put these
- // in registers and make this fast
- int p1 = start;
- int p2 = mid;
- int i = start + srcDestDiff;
-
- // The main merge loop; terminates as soon as either
- // half is ended
- while (p1 < mid && p2 < end)
- {
- dest[i++] =
- src[c.compare(src[p1], src[p2]) <= 0 ? p1++ : p2++];
- }
-
- // Finish up by copying the remainder of whichever half
- // wasn't finished.
- if (p1 < mid)
- System.arraycopy(src, p1, dest, i, mid - p1);
- else
- System.arraycopy(src, p2, dest, i, end - p2);
- }
+ if (mid >= end || c.compare(src[mid - 1], src[mid]) <= 0)
+ {
+ System.arraycopy(src, start,
+ dest, start + srcDestDiff, end - start);
+
+ // The two halves just need swapping - no need to merge
+ }
+ else if (c.compare(src[start], src[end - 1]) > 0)
+ {
+ System.arraycopy(src, start,
+ dest, end - size + srcDestDiff, size);
+ System.arraycopy(src, mid,
+ dest, start + srcDestDiff, end - mid);
+
+ }
+ else
+ {
+ // Declare a lot of variables to save repeating
+ // calculations. Hopefully a decent JIT will put these
+ // in registers and make this fast
+ int p1 = start;
+ int p2 = mid;
+ int i = start + srcDestDiff;
+
+ // The main merge loop; terminates as soon as either
+ // half is ended
+ while (p1 < mid && p2 < end)
+ {
+ dest[i++] =
+ src[c.compare(src[p1], src[p2]) <= 0 ? p1++ : p2++];
+ }
+
+ // Finish up by copying the remainder of whichever half
+ // wasn't finished.
+ if (p1 < mid)
+ System.arraycopy(src, p1, dest, i, mid - p1);
+ else
+ System.arraycopy(src, p2, dest, i, end - p2);
+ }
}
// swap src and dest ready for the next merge
- t = src; src = dest; dest = t;
+ t = src;
+ src = dest;
+ dest = t;
from += srcDestDiff;
- to += srcDestDiff;
+ to += srcDestDiff;
srcDestDiff = -srcDestDiff;
}
* @exception NullPointerException if an element is null (since
* null.compareTo cannot work)
*/
- public static void sort(Object[] a) {
+ public static void sort(Object[]a)
+ {
mergeSort(a, 0, a.length, defaultComparator);
}
* @exception ClassCastException if any two elements are not mutually
* comparable by the Comparator provided
*/
- public static void sort(Object[] a, Comparator c) {
+ public static void sort(Object[]a, Comparator c)
+ {
mergeSort(a, 0, a.length, c);
}
* are not in range.
* @exception IllegalArgumentException if fromIndex > toIndex
*/
- public static void sort(Object[] a, int fromIndex,
- int toIndex) {
+ public static void sort(Object[]a, int fromIndex, int toIndex)
+ {
if (fromIndex > toIndex)
- throw new IllegalArgumentException("fromIndex "+fromIndex
- +" > toIndex "+toIndex);
+ throw new IllegalArgumentException("fromIndex " + fromIndex
+ + " > toIndex " + toIndex);
mergeSort(a, fromIndex, toIndex, defaultComparator);
}
* are not in range.
* @exception IllegalArgumentException if fromIndex > toIndex
*/
- public static void sort(Object[] a, int fromIndex,
- int toIndex, Comparator c) {
+ public static void sort(Object[]a, int fromIndex, int toIndex, Comparator c)
+ {
if (fromIndex > toIndex)
- throw new IllegalArgumentException("fromIndex "+fromIndex
- +" > toIndex "+toIndex);
+ throw new IllegalArgumentException("fromIndex " + fromIndex
+ + " > toIndex " + toIndex);
mergeSort(a, fromIndex, toIndex, c);
}
* @param a the array to return a view of
* @returns a fixed-size list, changes to which "write through" to the array
*/
- public static List asList(final Object[] a) {
-
- if (a == null) {
- throw new NullPointerException();
- }
+ public static List asList(final Object[]a)
+ {
+ if (a == null)
+ {
+ throw new NullPointerException();
+ }
- return new ListImpl( a );
+ return new ListImpl(a);
}
* Note: When Sun fully specify serialized forms, this class will have to
* be renamed.
*/
- private static class ListImpl extends AbstractList {
-
- ListImpl(Object[] a) {
+ private static class ListImpl extends AbstractList
+ {
+ ListImpl(Object[]a)
+ {
this.a = a;
}
- public Object get(int index) {
+ public Object get(int index)
+ {
return a[index];
}
- public int size() {
+ public int size()
+ {
return a.length;
}
- public Object set(int index, Object element) {
+ public Object set(int index, Object element)
+ {
Object old = a[index];
a[index] = element;
return old;
private Object[] a;
}
-
}