提交 ae1cb491 编写于 作者: V vinnie

Merge

......@@ -217,7 +217,7 @@ SUNWprivate_1.1 {
Java_java_lang_Throwable_fillInStackTrace;
Java_java_lang_Throwable_getStackTraceDepth;
Java_java_lang_Throwable_getStackTraceElement;
Java_java_lang_UNIXProcess_initIDs;
Java_java_lang_UNIXProcess_init;
Java_java_lang_UNIXProcess_waitForProcessExit;
Java_java_lang_UNIXProcess_forkAndExec;
Java_java_lang_UNIXProcess_destroyProcess;
......
......@@ -217,7 +217,7 @@ SUNWprivate_1.1 {
Java_java_lang_Throwable_fillInStackTrace;
Java_java_lang_Throwable_getStackTraceDepth;
Java_java_lang_Throwable_getStackTraceElement;
Java_java_lang_UNIXProcess_initIDs;
Java_java_lang_UNIXProcess_init;
Java_java_lang_UNIXProcess_waitForProcessExit;
Java_java_lang_UNIXProcess_forkAndExec;
Java_java_lang_UNIXProcess_destroyProcess;
......
......@@ -184,7 +184,7 @@ import java.security.PrivilegedAction;
for (int i=0; i<markerInterfaces.length; i++) {
interfaces[i+1] = markerInterfaces[i].getName().replace('.', '/');
}
cw.visit(CLASSFILE_VERSION, ACC_SUPER + ACC_FINAL,
cw.visit(CLASSFILE_VERSION, ACC_SUPER + ACC_FINAL + ACC_SYNTHETIC,
lambdaClassName, null,
NAME_MAGIC_ACCESSOR_IMPL, interfaces);
......
......@@ -25,12 +25,10 @@
package java.nio.file.attribute;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Date;
import java.util.Formatter;
import java.util.Locale;
import java.util.TimeZone;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
......@@ -51,42 +49,35 @@ public final class FileTime
implements Comparable<FileTime>
{
/**
* The value since the epoch; can be negative.
*/
private final long value;
/**
* The unit of granularity to interpret the value.
* The unit of granularity to interpret the value. Null if
* this {@code FileTime} is converted from an {@code Instant},
* the {@code value} and {@code unit} pair will not be used
* in this scenario.
*/
private final TimeUnit unit;
/**
* The value return by toString (created lazily)
* The value since the epoch; can be negative.
*/
private String valueAsString;
private final long value;
/**
* The value in days and excess nanos (created lazily)
* The value as Instant (created lazily, if not from an instant)
*/
private DaysAndNanos daysAndNanos;
private Instant instant;
/**
* Returns a DaysAndNanos object representing the value.
* The value return by toString (created lazily)
*/
private DaysAndNanos asDaysAndNanos() {
if (daysAndNanos == null)
daysAndNanos = new DaysAndNanos(value, unit);
return daysAndNanos;
}
private String valueAsString;
/**
* Initializes a new instance of this class.
*/
private FileTime(long value, TimeUnit unit) {
if (unit == null)
throw new NullPointerException();
private FileTime(long value, TimeUnit unit, Instant instant) {
this.value = value;
this.unit = unit;
this.instant = instant;
}
/**
......@@ -102,7 +93,8 @@ public final class FileTime
* @return a {@code FileTime} representing the given value
*/
public static FileTime from(long value, TimeUnit unit) {
return new FileTime(value, unit);
Objects.requireNonNull(unit, "unit");
return new FileTime(value, unit, null);
}
/**
......@@ -115,7 +107,22 @@ public final class FileTime
* @return a {@code FileTime} representing the given value
*/
public static FileTime fromMillis(long value) {
return new FileTime(value, TimeUnit.MILLISECONDS);
return new FileTime(value, TimeUnit.MILLISECONDS, null);
}
/**
* Returns a {@code FileTime} representing the same point of time value
* on the time-line as the provided {@code Instant} object.
*
* @param instant
* the instant to convert
* @return a {@code FileTime} representing the same point on the time-line
* as the provided instant
* @since 1.8
*/
public static FileTime from(Instant instant) {
Objects.requireNonNull(instant, "instant");
return new FileTime(0, null, instant);
}
/**
......@@ -132,7 +139,22 @@ public final class FileTime
* since the epoch (1970-01-01T00:00:00Z); can be negative
*/
public long to(TimeUnit unit) {
return unit.convert(this.value, this.unit);
Objects.requireNonNull(unit, "unit");
if (this.unit != null) {
return unit.convert(this.value, this.unit);
} else {
long secs = unit.convert(instant.getEpochSecond(), TimeUnit.SECONDS);
if (secs == Long.MIN_VALUE || secs == Long.MAX_VALUE) {
return secs;
}
long nanos = unit.convert(instant.getNano(), TimeUnit.NANOSECONDS);
long r = secs + nanos;
// Math.addExact() variant
if (((secs ^ r) & (nanos ^ r)) < 0) {
return (secs < 0) ? Long.MIN_VALUE : Long.MAX_VALUE;
}
return r;
}
}
/**
......@@ -145,7 +167,110 @@ public final class FileTime
* @return the value in milliseconds, since the epoch (1970-01-01T00:00:00Z)
*/
public long toMillis() {
return unit.toMillis(value);
if (unit != null) {
return unit.toMillis(value);
} else {
long secs = instant.getEpochSecond();
int nanos = instant.getNano();
// Math.multiplyExact() variant
long r = secs * 1000;
long ax = Math.abs(secs);
if (((ax | 1000) >>> 31 != 0)) {
if ((r / 1000) != secs) {
return (secs < 0) ? Long.MIN_VALUE : Long.MAX_VALUE;
}
}
return r + nanos / 1000_000;
}
}
/**
* Time unit constants for conversion.
*/
private static final long HOURS_PER_DAY = 24L;
private static final long MINUTES_PER_HOUR = 60L;
private static final long SECONDS_PER_MINUTE = 60L;
private static final long SECONDS_PER_HOUR = SECONDS_PER_MINUTE * MINUTES_PER_HOUR;
private static final long SECONDS_PER_DAY = SECONDS_PER_HOUR * HOURS_PER_DAY;
private static final long MILLIS_PER_SECOND = 1000L;
private static final long MICROS_PER_SECOND = 1000_000L;
private static final long NANOS_PER_SECOND = 1000_000_000L;
private static final int NANOS_PER_MILLI = 1000_000;
private static final int NANOS_PER_MICRO = 1000;
// The epoch second of Instant.MIN.
private static final long MIN_SECOND = -31557014167219200L;
// The epoch second of Instant.MAX.
private static final long MAX_SECOND = 31556889864403199L;
/*
* Scale d by m, checking for overflow.
*/
private static long scale(long d, long m, long over) {
if (d > over) return Long.MAX_VALUE;
if (d < -over) return Long.MIN_VALUE;
return d * m;
}
/**
* Converts this {@code FileTime} object to an {@code Instant}.
*
* <p> The conversion creates an {@code Instant} that represents the
* same point on the time-line as this {@code FileTime}.
*
* <p> {@code FileTime} can store points on the time-line further in the
* future and further in the past than {@code Instant}. Conversion
* from such further time points saturates to {@link Instant.MIN} if
* earlier than {@code Instant.MIN} or {@link Instant.MAX} if later
* than {@code Instant.MAX}.
*
* @return an instant representing the same point on the time-line as
* this {@code FileTime} object
* @since 1.8
*/
public Instant toInstant() {
if (instant == null) {
long secs = 0L;
int nanos = 0;
switch (unit) {
case DAYS:
secs = scale(value, SECONDS_PER_DAY,
Long.MAX_VALUE/SECONDS_PER_DAY);
break;
case HOURS:
secs = scale(value, SECONDS_PER_HOUR,
Long.MAX_VALUE/SECONDS_PER_HOUR);
break;
case MINUTES:
secs = scale(value, SECONDS_PER_MINUTE,
Long.MAX_VALUE/SECONDS_PER_MINUTE);
break;
case SECONDS:
secs = value;
break;
case MILLISECONDS:
secs = Math.floorDiv(value, MILLIS_PER_SECOND);
nanos = (int)Math.floorMod(value, MILLIS_PER_SECOND)
* NANOS_PER_MILLI;
break;
case MICROSECONDS:
secs = Math.floorDiv(value, MICROS_PER_SECOND);
nanos = (int)Math.floorMod(value, MICROS_PER_SECOND)
* NANOS_PER_MICRO;
break;
case NANOSECONDS:
secs = Math.floorDiv(value, NANOS_PER_SECOND);
nanos = (int)Math.floorMod(value, NANOS_PER_SECOND);
break;
default : throw new AssertionError("Unit not handled");
}
if (secs <= MIN_SECOND)
instant = Instant.MIN;
else if (secs >= MAX_SECOND)
instant = Instant.MAX;
else
instant = Instant.ofEpochSecond(secs, nanos);
}
return instant;
}
/**
......@@ -176,8 +301,25 @@ public final class FileTime
*/
@Override
public int hashCode() {
// hashcode of days/nanos representation to satisfy contract with equals
return asDaysAndNanos().hashCode();
// hashcode of instant representation to satisfy contract with equals
return toInstant().hashCode();
}
private long toDays() {
if (unit != null) {
return unit.toDays(value);
} else {
return TimeUnit.SECONDS.toDays(toInstant().getEpochSecond());
}
}
private long toExcessNanos(long days) {
if (unit != null) {
return unit.toNanos(value - unit.convert(days, TimeUnit.DAYS));
} else {
return TimeUnit.SECONDS.toNanos(toInstant().getEpochSecond()
- TimeUnit.DAYS.toSeconds(days));
}
}
/**
......@@ -194,14 +336,52 @@ public final class FileTime
@Override
public int compareTo(FileTime other) {
// same granularity
if (unit == other.unit) {
return (value < other.value) ? -1 : (value == other.value ? 0 : 1);
if (unit != null && unit == other.unit) {
return Long.compare(value, other.value);
} else {
// compare using days/nanos representation when unit differs
return asDaysAndNanos().compareTo(other.asDaysAndNanos());
// compare using instant representation when unit differs
long secs = toInstant().getEpochSecond();
long secsOther = other.toInstant().getEpochSecond();
int cmp = Long.compare(secs, secsOther);
if (cmp != 0) {
return cmp;
}
cmp = Long.compare(toInstant().getNano(), other.toInstant().getNano());
if (cmp != 0) {
return cmp;
}
if (secs != MAX_SECOND && secs != MIN_SECOND) {
return 0;
}
// if both this and other's Instant reps are MIN/MAX,
// use daysSinceEpoch and nanosOfDays, which will not
// saturate during calculation.
long days = toDays();
long daysOther = other.toDays();
if (days == daysOther) {
return Long.compare(toExcessNanos(days), other.toExcessNanos(daysOther));
}
return Long.compare(days, daysOther);
}
}
// days in a 400 year cycle = 146097
// days in a 10,000 year cycle = 146097 * 25
// seconds per day = 86400
private static final long DAYS_PER_10000_YEARS = 146097L * 25L;
private static final long SECONDS_PER_10000_YEARS = 146097L * 25L * 86400L;
private static final long SECONDS_0000_TO_1970 = ((146097L * 5L) - (30L * 365L + 7L)) * 86400L;
// append year/month/day/hour/minute/second/nano with width and 0 padding
private StringBuilder append(StringBuilder sb, int w, int d) {
while (w > 0) {
sb.append((char)(d/w + '0'));
d = d % w;
w /= 10;
}
return sb;
}
/**
* Returns the string representation of this {@code FileTime}. The string
* is returned in the <a
......@@ -229,135 +409,67 @@ public final class FileTime
*/
@Override
public String toString() {
String v = valueAsString;
if (v == null) {
// overflow saturates to Long.MIN_VALUE or Long.MAX_VALUE so this
// limits the range:
// [-292275056-05-16T16:47:04.192Z,292278994-08-17T07:12:55.807Z]
long ms = toMillis();
// nothing to do when seconds/minutes/hours/days
String fractionAsString = "";
if (unit.compareTo(TimeUnit.SECONDS) < 0) {
long fraction = asDaysAndNanos().fractionOfSecondInNanos();
if (fraction != 0L) {
// fraction must be positive
if (fraction < 0L) {
final long MAX_FRACTION_PLUS_1 = 1000L * 1000L * 1000L;
fraction += MAX_FRACTION_PLUS_1;
if (ms != Long.MIN_VALUE) ms--;
}
// convert to String, adding leading zeros as required and
// stripping any trailing zeros
String s = Long.toString(fraction);
int len = s.length();
int width = 9 - len;
StringBuilder sb = new StringBuilder(".");
while (width-- > 0) {
sb.append('0');
}
if (s.charAt(len-1) == '0') {
// drop trailing zeros
len--;
while (s.charAt(len-1) == '0')
len--;
sb.append(s.substring(0, len));
} else {
sb.append(s);
}
fractionAsString = sb.toString();
}
if (valueAsString == null) {
long secs = 0L;
int nanos = 0;
if (instant == null && unit.compareTo(TimeUnit.SECONDS) >= 0) {
secs = unit.toSeconds(value);
} else {
secs = toInstant().getEpochSecond();
nanos = toInstant().getNano();
}
// create calendar to use with formatter.
GregorianCalendar cal =
new GregorianCalendar(TimeZone.getTimeZone("UTC"), Locale.ROOT);
if (value < 0L)
cal.setGregorianChange(new Date(Long.MIN_VALUE));
cal.setTimeInMillis(ms);
// years are negative before common era
String sign = (cal.get(Calendar.ERA) == GregorianCalendar.BC) ? "-" : "";
// [-]YYYY-MM-DDThh:mm:ss[.s]Z
v = new Formatter(Locale.ROOT)
.format("%s%tFT%tR:%tS%sZ", sign, cal, cal, cal, fractionAsString)
.toString();
valueAsString = v;
}
return v;
}
/**
* Represents a FileTime's value as two longs: the number of days since
* the epoch, and the excess (in nanoseconds). This is used for comparing
* values with different units of granularity.
*/
private static class DaysAndNanos implements Comparable<DaysAndNanos> {
// constants for conversion
private static final long C0 = 1L;
private static final long C1 = C0 * 24L;
private static final long C2 = C1 * 60L;
private static final long C3 = C2 * 60L;
private static final long C4 = C3 * 1000L;
private static final long C5 = C4 * 1000L;
private static final long C6 = C5 * 1000L;
/**
* The value (in days) since the epoch; can be negative.
*/
private final long days;
/**
* The excess (in nanoseconds); can be negative if days &lt;= 0.
*/
private final long excessNanos;
/**
* Initializes a new instance of this class.
*/
DaysAndNanos(long value, TimeUnit unit) {
long scale;
switch (unit) {
case DAYS : scale = C0; break;
case HOURS : scale = C1; break;
case MINUTES : scale = C2; break;
case SECONDS : scale = C3; break;
case MILLISECONDS : scale = C4; break;
case MICROSECONDS : scale = C5; break;
case NANOSECONDS : scale = C6; break;
default : throw new AssertionError("Unit not handled");
LocalDateTime ldt;
int year = 0;
if (secs >= -SECONDS_0000_TO_1970) {
// current era
long zeroSecs = secs - SECONDS_PER_10000_YEARS + SECONDS_0000_TO_1970;
long hi = Math.floorDiv(zeroSecs, SECONDS_PER_10000_YEARS) + 1;
long lo = Math.floorMod(zeroSecs, SECONDS_PER_10000_YEARS);
ldt = LocalDateTime.ofEpochSecond(lo - SECONDS_0000_TO_1970, nanos, ZoneOffset.UTC);
year = ldt.getYear() + (int)hi * 10000;
} else {
// before current era
long zeroSecs = secs + SECONDS_0000_TO_1970;
long hi = zeroSecs / SECONDS_PER_10000_YEARS;
long lo = zeroSecs % SECONDS_PER_10000_YEARS;
ldt = LocalDateTime.ofEpochSecond(lo - SECONDS_0000_TO_1970, nanos, ZoneOffset.UTC);
year = ldt.getYear() + (int)hi * 10000;
}
this.days = unit.toDays(value);
this.excessNanos = unit.toNanos(value - (this.days * scale));
}
/**
* Returns the fraction of a second, in nanoseconds.
*/
long fractionOfSecondInNanos() {
return excessNanos % (1000L * 1000L * 1000L);
}
@Override
public boolean equals(Object obj) {
return (obj instanceof DaysAndNanos) ?
compareTo((DaysAndNanos)obj) == 0 : false;
}
@Override
public int hashCode() {
return (int)(days ^ (days >>> 32) ^
excessNanos ^ (excessNanos >>> 32));
}
@Override
public int compareTo(DaysAndNanos other) {
if (this.days != other.days)
return (this.days < other.days) ? -1 : 1;
return (this.excessNanos < other.excessNanos) ? -1 :
(this.excessNanos == other.excessNanos) ? 0 : 1;
if (year <= 0) {
year = year - 1;
}
int fraction = ldt.getNano();
StringBuilder sb = new StringBuilder(64);
sb.append(year < 0 ? "-" : "");
year = Math.abs(year);
if (year < 10000) {
append(sb, 1000, Math.abs(year));
} else {
sb.append(String.valueOf(year));
}
sb.append('-');
append(sb, 10, ldt.getMonthValue());
sb.append('-');
append(sb, 10, ldt.getDayOfMonth());
sb.append('T');
append(sb, 10, ldt.getHour());
sb.append(':');
append(sb, 10, ldt.getMinute());
sb.append(':');
append(sb, 10, ldt.getSecond());
if (fraction != 0) {
sb.append('.');
// adding leading zeros and stripping any trailing zeros
int w = 100_000_000;
while (fraction % 10 == 0) {
fraction /= 10;
w /= 10;
}
append(sb, w, fraction);
}
sb.append('Z');
valueAsString = sb.toString();
}
return valueAsString;
}
}
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -104,9 +104,21 @@ public class ArrayList<E> extends AbstractList<E>
{
private static final long serialVersionUID = 8683452581122892189L;
/**
* Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* Shared empty array instance used for empty instances.
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == EMPTY_ELEMENTDATA will be expanded to
* DEFAULT_CAPACITY when the first element is added.
*/
private transient Object[] elementData;
......@@ -136,7 +148,8 @@ public class ArrayList<E> extends AbstractList<E>
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this(10);
super();
this.elementData = EMPTY_ELEMENTDATA;
}
/**
......@@ -162,8 +175,7 @@ public class ArrayList<E> extends AbstractList<E>
*/
public void trimToSize() {
modCount++;
int oldCapacity = elementData.length;
if (size < oldCapacity) {
if (size < elementData.length) {
elementData = Arrays.copyOf(elementData, size);
}
}
......@@ -176,12 +188,29 @@ public class ArrayList<E> extends AbstractList<E>
* @param minCapacity the desired minimum capacity
*/
public void ensureCapacity(int minCapacity) {
if (minCapacity > 0)
ensureCapacityInternal(minCapacity);
int minExpand = (elementData != EMPTY_ELEMENTDATA)
// any size if real element table
? 0
// larger than default for empty table. It's already supposed to be
// at default size.
: DEFAULT_CAPACITY;
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity);
}
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
......@@ -450,7 +479,7 @@ public class ArrayList<E> extends AbstractList<E>
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // Let gc do its work
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
......@@ -495,7 +524,7 @@ public class ArrayList<E> extends AbstractList<E>
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // Let gc do its work
elementData[--size] = null; // clear to let GC do its work
}
/**
......@@ -505,7 +534,7 @@ public class ArrayList<E> extends AbstractList<E>
public void clear() {
modCount++;
// Let gc do its work
// clear to let GC do its work
for (int i = 0; i < size; i++)
elementData[i] = null;
......@@ -586,10 +615,12 @@ public class ArrayList<E> extends AbstractList<E>
System.arraycopy(elementData, toIndex, elementData, fromIndex,
numMoved);
// Let gc do its work
// clear to let GC do its work
int newSize = size - (toIndex-fromIndex);
while (size != newSize)
elementData[--size] = null;
for (int i = newSize; i < size; i++) {
elementData[i] = null;
}
size = newSize;
}
/**
......@@ -677,6 +708,7 @@ public class ArrayList<E> extends AbstractList<E>
w += size - r;
}
if (w != size) {
// clear to let GC do its work
for (int i = w; i < size; i++)
elementData[i] = null;
modCount += size - w;
......@@ -701,17 +733,17 @@ public class ArrayList<E> extends AbstractList<E>
int expectedModCount = modCount;
s.defaultWriteObject();
// Write out array length
s.writeInt(elementData.length);
// Write out size as capacity for behavioural compatibility with clone()
s.writeInt(size);
// Write out all elements in the proper order.
for (int i=0; i<size; i++)
for (int i=0; i<size; i++) {
s.writeObject(elementData[i]);
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
/**
......@@ -720,16 +752,24 @@ public class ArrayList<E> extends AbstractList<E>
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
elementData = EMPTY_ELEMENTDATA;
// Read in size, and any hidden stuff
s.defaultReadObject();
// Read in array length and allocate array
int arrayLength = s.readInt();
Object[] a = elementData = new Object[arrayLength];
// Read in capacity
s.readInt(); // ignored
if (size > 0) {
// be like clone(), allocate array based upon size not capacity
ensureCapacityInternal(size);
// Read in all elements in the proper order.
for (int i=0; i<size; i++)
a[i] = s.readObject();
Object[] a = elementData;
// Read in all elements in the proper order.
for (int i=0; i<size; i++) {
a[i] = s.readObject();
}
}
}
/**
......
......@@ -261,6 +261,7 @@ public class Comparators {
* according to the supplied {@code Comparator}
*/
public static<T> BinaryOperator<T> lesserOf(Comparator<? super T> comparator) {
Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
}
......@@ -274,6 +275,7 @@ public class Comparators {
* according to the supplied {@code Comparator}
*/
public static<T> BinaryOperator<T> greaterOf(Comparator<? super T> comparator) {
Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
}
}
......@@ -129,7 +129,7 @@ public class HashMap<K,V>
/**
* The default initial capacity - MUST be a power of two.
*/
static final int DEFAULT_INITIAL_CAPACITY = 16;
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
/**
* The maximum capacity, used if a higher value is implicitly specified
......@@ -143,10 +143,15 @@ public class HashMap<K,V>
*/
static final float DEFAULT_LOAD_FACTOR = 0.75f;
/**
* An empty table instance to share when the table is not inflated.
*/
static final Entry<?,?>[] EMPTY_TABLE = {};
/**
* The table, resized as necessary. Length MUST Always be a power of two.
*/
transient Entry<?,?>[] table;
transient Entry<?,?>[] table = EMPTY_TABLE;
/**
* The number of key-value mappings contained in this map.
......@@ -157,6 +162,8 @@ public class HashMap<K,V>
* The next size value at which to resize (capacity * load factor).
* @serial
*/
// If table == EMPTY_TABLE then this is the initial capacity at which the
// table will be created when inflated.
int threshold;
/**
......@@ -223,14 +230,8 @@ public class HashMap<K,V>
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor);
// Find a power of 2 >= initialCapacity
int capacity = 1;
while (capacity < initialCapacity)
capacity <<= 1;
this.loadFactor = loadFactor;
threshold = (int)Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1);
table = new Entry<?,?>[capacity];
threshold = initialCapacity;
init();
}
......@@ -265,9 +266,33 @@ public class HashMap<K,V>
public HashMap(Map<? extends K, ? extends V> m) {
this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1,
DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);
inflateTable(threshold);
putAllForCreate(m);
}
private static int roundUpToPowerOf2(int number) {
// assert number >= 0 : "number must be non-negative";
int rounded = number >= MAXIMUM_CAPACITY
? MAXIMUM_CAPACITY
: (rounded = Integer.highestOneBit(number)) != 0
? (Integer.bitCount(number) > 1) ? rounded << 1 : rounded
: 1;
return rounded;
}
/**
* Inflates the table.
*/
private void inflateTable(int toSize) {
// Find a power of 2 >= toSize
int capacity = roundUpToPowerOf2(toSize);
threshold = (int) Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1);
table = new Entry[capacity];
}
// internal utilities
/**
......@@ -305,6 +330,7 @@ public class HashMap<K,V>
* Returns index for hash code h.
*/
static int indexFor(int h, int length) {
// assert Integer.bitCount(length) == 1 : "length must be a non-zero power of 2";
return h & (length-1);
}
......@@ -369,6 +395,10 @@ public class HashMap<K,V>
*/
@SuppressWarnings("unchecked")
final Entry<K,V> getEntry(Object key) {
if (isEmpty()) {
return null;
}
int hash = (key == null) ? 0 : hash(key);
for (Entry<?,?> e = table[indexFor(hash, table.length)];
e != null;
......@@ -381,7 +411,6 @@ public class HashMap<K,V>
return null;
}
/**
* Associates the specified value with the specified key in this map.
* If the map previously contained a mapping for the key, the old
......@@ -395,6 +424,9 @@ public class HashMap<K,V>
* previously associated <tt>null</tt> with <tt>key</tt>.)
*/
public V put(K key, V value) {
if (table == EMPTY_TABLE) {
inflateTable(threshold);
}
if (key == null)
return putForNullKey(value);
int hash = hash(key);
......@@ -529,6 +561,10 @@ public class HashMap<K,V>
if (numKeysToBeAdded == 0)
return;
if (table == EMPTY_TABLE) {
inflateTable((int) Math.max(numKeysToBeAdded * loadFactor, threshold));
}
/*
* Expand the map if the map if the number of mappings to be added
* is greater than or equal to threshold. This is conservative; the
......@@ -573,6 +609,9 @@ public class HashMap<K,V>
* for this key.
*/
final Entry<K,V> removeEntryForKey(Object key) {
if (isEmpty()) {
return null;
}
int hash = (key == null) ? 0 : hash(key);
int i = indexFor(hash, table.length);
@SuppressWarnings("unchecked")
......@@ -605,7 +644,7 @@ public class HashMap<K,V>
* for matching.
*/
final Entry<K,V> removeMapping(Object o) {
if (!(o instanceof Map.Entry))
if (isEmpty() || !(o instanceof Map.Entry))
return null;
Map.Entry<?,?> entry = (Map.Entry<?,?>) o;
......@@ -641,9 +680,7 @@ public class HashMap<K,V>
*/
public void clear() {
modCount++;
Entry<?,?>[] tab = table;
for (int i = 0; i < tab.length; i++)
tab[i] = null;
Arrays.fill(table, null);
size = 0;
}
......@@ -693,7 +730,14 @@ public class HashMap<K,V>
} catch (CloneNotSupportedException e) {
// assert false;
}
result.table = new Entry<?,?>[table.length];
if (result.table != EMPTY_TABLE) {
result.inflateTable(Math.min(
(int) Math.min(
size * Math.min(1 / loadFactor, 4.0f),
// we have limits...
HashMap.MAXIMUM_CAPACITY),
table.length));
}
result.entrySet = null;
result.modCount = 0;
result.size = 0;
......@@ -749,8 +793,7 @@ public class HashMap<K,V>
}
public final int hashCode() {
return (key==null ? 0 : key.hashCode()) ^
(value==null ? 0 : value.hashCode());
return Objects.hashCode(getKey()) ^ Objects.hashCode(getValue());
}
public final String toString() {
......@@ -1017,14 +1060,15 @@ public class HashMap<K,V>
private void writeObject(java.io.ObjectOutputStream s)
throws IOException
{
Iterator<Map.Entry<K,V>> i =
(size > 0) ? entrySet0().iterator() : null;
// Write out the threshold, loadfactor, and any hidden stuff
s.defaultWriteObject();
// Write out number of buckets
s.writeInt(table.length);
if (table==EMPTY_TABLE) {
s.writeInt(roundUpToPowerOf2(threshold));
} else {
s.writeInt(table.length);
}
// Write out size (number of Mappings)
s.writeInt(size);
......@@ -1049,16 +1093,18 @@ public class HashMap<K,V>
{
// Read in the threshold (ignored), loadfactor, and any hidden stuff
s.defaultReadObject();
if (loadFactor <= 0 || Float.isNaN(loadFactor))
if (loadFactor <= 0 || Float.isNaN(loadFactor)) {
throw new InvalidObjectException("Illegal load factor: " +
loadFactor);
}
// set hashMask
// set other fields that need values
Holder.UNSAFE.putIntVolatile(this, Holder.HASHSEED_OFFSET,
sun.misc.Hashing.randomHashSeed(this));
table = EMPTY_TABLE;
// Read in number of buckets and allocate the bucket array;
s.readInt(); // ignored
// Read in number of buckets
s.readInt(); // ignored.
// Read number of mappings
int mappings = s.readInt();
......@@ -1066,23 +1112,21 @@ public class HashMap<K,V>
throw new InvalidObjectException("Illegal mappings count: " +
mappings);
int initialCapacity = (int) Math.min(
// capacity chosen by number of mappings
// and desired load (if >= 0.25)
mappings * Math.min(1 / loadFactor, 4.0f),
// we have limits...
HashMap.MAXIMUM_CAPACITY);
int capacity = 1;
// find smallest power of two which holds all mappings
while (capacity < initialCapacity) {
capacity <<= 1;
// capacity chosen by number of mappings and desired load (if >= 0.25)
int capacity = (int) Math.min(
mappings * Math.min(1 / loadFactor, 4.0f),
// we have limits...
HashMap.MAXIMUM_CAPACITY);
// allocate the bucket array;
if (mappings > 0) {
inflateTable(capacity);
} else {
threshold = capacity;
}
table = new Entry<?,?>[capacity];
threshold = (int) Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1);
init(); // Give subclass a chance to do its thing.
// Read the keys and values, and put the mappings in the HashMap
for (int i=0; i<mappings; i++) {
@SuppressWarnings("unchecked")
......
/*
* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -25,6 +25,8 @@
package java.util;
import java.util.function.Supplier;
/**
* This class consists of {@code static} utility methods for operating
* on objects. These utilities include {@code null}-safe or {@code
......@@ -226,4 +228,30 @@ public final class Objects {
throw new NullPointerException(message);
return obj;
}
/**
* Checks that the specified object reference is not {@code null} and
* throws a customized {@link NullPointerException} if it is.
*
* <p>Unlike the method {@link requireNonNull(Object, String},
* this method allows creation of the message to be deferred until
* after the null check is made. While this may confer a
* performance advantage in the non-null case, when deciding to
* call this method care should be taken that the costs of
* creating the message supplier are less than the cost of just
* creating the string message directly.
*
* @param obj the object reference to check for nullity
* @param messageSupplier supplier of the detail message to be
* used in the event that a {@code NullPointerException} is thrown
* @param <T> the type of the reference
* @return {@code obj} if not {@code null}
* @throws NullPointerException if {@code obj} is {@code null}
* @since 1.8
*/
public static <T> T requireNonNull(T obj, Supplier<String> messageSupplier) {
if (obj == null)
throw new NullPointerException(messageSupplier.get());
return obj;
}
}
......@@ -466,7 +466,10 @@ public class ZipFileSystem extends FileSystem {
if (eSrc.type == Entry.NEW || eSrc.type == Entry.FILECH)
{
u.type = eSrc.type; // make it the same type
if (!deletesrc) { // if it's not "rename", just take the data
if (deletesrc) { // if it's a "rename", take the data
u.bytes = eSrc.bytes;
u.file = eSrc.file;
} else { // if it's not "rename", copy the data
if (eSrc.bytes != null)
u.bytes = Arrays.copyOf(eSrc.bytes, eSrc.bytes.length);
else if (eSrc.file != null) {
......@@ -1118,7 +1121,7 @@ public class ZipFileSystem extends FileSystem {
if (old != null) {
removeFromTree(old);
}
if (e.type == Entry.NEW || e.type == Entry.FILECH) {
if (e.type == Entry.NEW || e.type == Entry.FILECH || e.type == Entry.COPY) {
IndexNode parent = inodes.get(LOOKUPKEY.as(getParent(e.name)));
e.sibling = parent.child;
parent.child = e;
......@@ -2326,12 +2329,12 @@ public class ZipFileSystem extends FileSystem {
private void removeFromTree(IndexNode inode) {
IndexNode parent = inodes.get(LOOKUPKEY.as(getParent(inode.name)));
IndexNode child = parent.child;
if (child == inode) {
if (child.equals(inode)) {
parent.child = child.sibling;
} else {
IndexNode last = child;
while ((child = child.sibling) != null) {
if (child == inode) {
if (child.equals(inode)) {
last.sibling = child.sibling;
break;
} else {
......
......@@ -143,9 +143,9 @@ typedef struct _SurfaceType {
* structure from the information present in a given Java Composite
* object.
*/
typedef JNIEXPORT void (JNICALL CompInfoFunc)(JNIEnv *env,
CompositeInfo *pCompInfo,
jobject Composite);
typedef void (JNICALL CompInfoFunc)(JNIEnv *env,
CompositeInfo *pCompInfo,
jobject Composite);
/*
* The additional information needed to implement a primitive that
......
......@@ -94,13 +94,13 @@ typedef struct {
JNIEXPORT void JNICALL nptInitialize
(NptEnv **pnpt, char *nptVersion, char *options);
typedef JNIEXPORT void (JNICALL *NptInitialize)
(NptEnv **pnpt, char *nptVersion, char *options);
typedef void (JNICALL *NptInitialize)
(NptEnv **pnpt, char *nptVersion, char *options);
JNIEXPORT void JNICALL nptTerminate
(NptEnv* npt, char *options);
typedef JNIEXPORT void (JNICALL *NptTerminate)
(NptEnv* npt, char *options);
typedef void (JNICALL *NptTerminate)
(NptEnv* npt, char *options);
#ifdef __cplusplus
} /* extern "C" */
......
......@@ -270,11 +270,10 @@ final class UNIXProcess extends Process {
return !hasExited;
}
/* This routine initializes JNI field offsets for the class */
private static native void initIDs();
private static native void init();
static {
initIDs();
init();
}
/**
......
......@@ -270,11 +270,10 @@ final class UNIXProcess extends Process {
return !hasExited;
}
/* This routine initializes JNI field offsets for the class */
private static native void initIDs();
private static native void init();
static {
initIDs();
init();
}
/**
......
......@@ -328,10 +328,9 @@ final class UNIXProcess extends Process {
}
/* This routine initializes JNI field offsets for the class */
private static native void initIDs();
private static native void init();
static {
initIDs();
init();
}
}
......@@ -26,8 +26,17 @@
#ifndef _JAVASOFT_JNI_MD_H_
#define _JAVASOFT_JNI_MD_H_
#define JNIEXPORT
#define JNIIMPORT
#ifndef __has_attribute
#define __has_attribute(x) 0
#endif
#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility)
#define JNIEXPORT __attribute__((visibility("default")))
#define JNIIMPORT __attribute__((visibility("default")))
#else
#define JNIEXPORT
#define JNIIMPORT
#endif
#define JNICALL
typedef int jint;
......
......@@ -31,21 +31,24 @@
#ifdef __APPLE__
#include <crt_externs.h>
#define environ (*_NSGetEnviron())
#else
/* This is one of the rare times it's more portable to declare an
* external symbol explicitly, rather than via a system header.
* The declaration is standardized as part of UNIX98, but there is
* no standard (not even de-facto) header file where the
* declaration is to be found. See:
* http://www.opengroup.org/onlinepubs/009695399/functions/environ.html
* http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_02.html
*
* "All identifiers in this volume of IEEE Std 1003.1-2001, except
* environ, are defined in at least one of the headers" (!)
*/
extern char **environ;
#endif
JNIEXPORT jobjectArray JNICALL
Java_java_lang_ProcessEnvironment_environ(JNIEnv *env, jclass ign)
{
/* This is one of the rare times it's more portable to declare an
* external symbol explicitly, rather than via a system header.
* The declaration is standardized as part of UNIX98, but there is
* no standard (not even de-facto) header file where the
* declaration is to be found. See:
* http://www.opengroup.org/onlinepubs/007908799/xbd/envvar.html */
#ifndef __APPLE__
extern char ** environ; /* environ[i] looks like: VAR=VALUE\0 */
#endif
jsize count = 0;
jsize i, j;
jobjectArray result;
......
......@@ -52,6 +52,19 @@
#ifdef __APPLE__
#include <crt_externs.h>
#define environ (*_NSGetEnviron())
#else
/* This is one of the rare times it's more portable to declare an
* external symbol explicitly, rather than via a system header.
* The declaration is standardized as part of UNIX98, but there is
* no standard (not even de-facto) header file where the
* declaration is to be found. See:
* http://www.opengroup.org/onlinepubs/009695399/functions/environ.html
* http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_02.html
*
* "All identifiers in this volume of IEEE Std 1003.1-2001, except
* environ, are defined in at least one of the headers" (!)
*/
extern char **environ;
#endif
/*
......@@ -152,19 +165,6 @@
} while((_result == -1) && (errno == EINTR)); \
} while(0)
/* This is one of the rare times it's more portable to declare an
* external symbol explicitly, rather than via a system header.
* The declaration is standardized as part of UNIX98, but there is
* no standard (not even de-facto) header file where the
* declaration is to be found. See:
* http://www.opengroup.org/onlinepubs/009695399/functions/environ.html
* http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_02.html
*
* "All identifiers in this volume of IEEE Std 1003.1-2001, except
* environ, are defined in at least one of the headers" (!)
*/
extern char **environ;
static void
setSIGCHLDHandler(JNIEnv *env)
......@@ -241,52 +241,41 @@ countOccurrences(const char *s, char c)
}
static const char * const *
splitPath(JNIEnv *env, const char *path)
effectivePathv(JNIEnv *env)
{
const char *p, *q;
char **pathv;
char *p;
int i;
const char *path = effectivePath();
int count = countOccurrences(path, ':') + 1;
pathv = NEW(char*, count+1);
pathv[count] = NULL;
for (p = path, i = 0; i < count; i++, p = q + 1) {
for (q = p; (*q != ':') && (*q != '\0'); q++)
;
if (q == p) /* empty PATH component => "." */
pathv[i] = "./";
else {
int addSlash = ((*(q - 1)) != '/');
pathv[i] = NEW(char, q - p + addSlash + 1);
memcpy(pathv[i], p, q - p);
if (addSlash)
pathv[i][q - p] = '/';
pathv[i][q - p + addSlash] = '\0';
}
size_t pathvsize = sizeof(const char *) * (count+1);
size_t pathsize = strlen(path) + 1;
const char **pathv = (const char **) xmalloc(env, pathvsize + pathsize);
if (pathv == NULL)
return NULL;
p = (char *) pathv + pathvsize;
memcpy(p, path, pathsize);
/* split PATH by replacing ':' with NULs; empty components => "." */
for (i = 0; i < count; i++) {
char *q = p + strcspn(p, ":");
pathv[i] = (p == q) ? "." : p;
*q = '\0';
p = q + 1;
}
return (const char * const *) pathv;
pathv[count] = NULL;
return pathv;
}
/**
* Cached value of JVM's effective PATH.
* The cached and split version of the JDK's effective PATH.
* (We don't support putenv("PATH=...") in native code)
*/
static const char *parentPath;
/**
* Split, canonicalized version of parentPath
*/
static const char * const *parentPathv;
static jfieldID field_exitcode;
JNIEXPORT void JNICALL
Java_java_lang_UNIXProcess_initIDs(JNIEnv *env, jclass clazz)
Java_java_lang_UNIXProcess_init(JNIEnv *env, jclass clazz)
{
field_exitcode = (*env)->GetFieldID(env, clazz, "exitcode", "I");
parentPath = effectivePath();
parentPathv = splitPath(env, parentPath);
parentPathv = effectivePathv(env);
setSIGCHLDHandler(env);
}
......@@ -486,6 +475,9 @@ throwIOException(JNIEnv *env, int errnum, const char *defaultDetail)
}
/* ASCII Decimal representation uses 2.4 times as many bits as binary. */
errmsg = NEW(char, strlen(format) + strlen(detail) + 3 * sizeof(errnum));
if (errmsg == NULL)
return;
sprintf(errmsg, format, errnum, detail);
s = JNU_NewStringPlatform(env, errmsg);
if (s != NULL) {
......@@ -590,11 +582,13 @@ JDK_execvpe(const char *file,
for (dirs = parentPathv; *dirs; dirs++) {
const char * dir = *dirs;
int dirlen = strlen(dir);
if (filelen + dirlen + 1 >= PATH_MAX) {
if (filelen + dirlen + 2 >= PATH_MAX) {
errno = ENAMETOOLONG;
continue;
}
memcpy(expanded_file, dir, dirlen);
if (expanded_file[dirlen - 1] != '/')
expanded_file[dirlen++] = '/';
memcpy(expanded_file + dirlen, file, filelen);
expanded_file[dirlen + filelen] = '\0';
execve_with_shell_fallback(expanded_file, argv, envp);
......
......@@ -43,7 +43,7 @@
static void *awtHandle = NULL;
typedef JNIEXPORT jint JNICALL JNI_OnLoad_type(JavaVM *vm, void *reserved);
typedef jint JNICALL JNI_OnLoad_type(JavaVM *vm, void *reserved);
/* Initialize the Java VM instance variable when the library is
first loaded */
......@@ -206,7 +206,7 @@ Java_sun_awt_motif_XsessionWMcommand(JNIEnv *env, jobject this,
jobject frame, jstring jcommand)
{
/* type of the old backdoor function */
typedef JNIEXPORT void JNICALL
typedef void JNICALL
XsessionWMcommand_type(JNIEnv *env, jobject this,
jobject frame, jstring jcommand);
......@@ -234,7 +234,7 @@ Java_sun_awt_motif_XsessionWMcommand(JNIEnv *env, jobject this,
JNIEXPORT void JNICALL
Java_sun_awt_motif_XsessionWMcommand_New(JNIEnv *env, jobjectArray jargv)
{
typedef JNIEXPORT void JNICALL
typedef void JNICALL
XsessionWMcommand_New_type(JNIEnv *env, jobjectArray jargv);
static XsessionWMcommand_New_type *XsessionWMcommand = NULL;
......
......@@ -138,14 +138,31 @@ public class ZipFSTester {
Path dst3 = Paths.get(tmpName + "_Tmp");
Files.move(dst2, dst3);
checkEqual(src, dst3);
if (Files.exists(dst2))
throw new RuntimeException("Failed!");
// copyback + move
Files.copy(dst3, dst);
Path dst4 = getPathWithParents(fs, tmpName + "_Tmp0");
Files.move(dst, dst4);
checkEqual(src, dst4);
// delete
if (Files.exists(dst2))
Files.delete(dst4);
if (Files.exists(dst4))
throw new RuntimeException("Failed!");
Files.delete(dst3);
if (Files.exists(dst3))
throw new RuntimeException("Failed!");
// move (existing entry)
Path dst5 = fs.getPath("META-INF/MANIFEST.MF");
if (Files.exists(dst5)) {
Path dst6 = fs.getPath("META-INF/MANIFEST.MF_TMP");
Files.move(dst5, dst6);
walk(fs.getPath("/"));
}
// newInputStream on dir
Path parent = dst2.getParent();
try {
......
......@@ -22,7 +22,7 @@
#
# @test
# @bug 6990846 7009092 7009085 7015391 7014948 7005986 7017840 7007596
# 7157656
# 7157656 8002390
# @summary Test ZipFileSystem demo
# @build Basic PathOps ZipFSTester
# @run shell basic.sh
......
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8012028
* @summary Generated Lambda implementing class should be final
*/
import java.lang.reflect.Modifier;
import java.io.Serializable;
public class LambdaClassFinal {
interface I {
void m();
}
interface Iser extends Serializable {
void m();
}
static void assertTrue(boolean cond) {
if (!cond)
throw new AssertionError();
}
public static void main(String[] args) throws Exception {
new LambdaClassFinal().test();
}
void test() throws Exception {
I lam = () -> { };
assertTrue((lam.getClass().getModifiers() & Modifier.FINAL) != 0);
Iser slam = () -> { };
assertTrue((slam.getClass().getModifiers() & Modifier.FINAL) != 0);
}
}
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8008941
* @summary Generated Lambda implementing class should be synthetic
*/
import java.lang.reflect.Modifier;
import java.io.Serializable;
public class LambdaClassSynthetic {
interface I {
void m();
}
interface Iser extends Serializable {
void m();
}
static void assertTrue(boolean cond) {
if (!cond)
throw new AssertionError();
}
public static void main(String[] args) throws Exception {
new LambdaClassFinal().test();
}
void test() throws Exception {
I lam = () -> { };
assertTrue(lam.getClass().isSynthetic());
Iser slam = () -> { };
assertTrue(slam.getClass().isSynthetic());
}
}
......@@ -22,14 +22,17 @@
*/
/* @test
* @bug 6844313
* @bug 6844313 8011647
* @summary Unit test for java.nio.file.FileTime
*/
import java.nio.file.attribute.FileTime;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
import static java.util.concurrent.TimeUnit.*;
import java.util.Random;
import java.util.EnumSet;
public class Basic {
......@@ -40,27 +43,59 @@ public class Basic {
long tomorrowInDays = TimeUnit.DAYS.convert(now, MILLISECONDS) + 1;
long yesterdayInDays = TimeUnit.DAYS.convert(now, MILLISECONDS) - 1;
Instant nowInstant = Instant.ofEpochMilli(now);
// equals
eq(now, MILLISECONDS, now, MILLISECONDS);
eq(now, MILLISECONDS, now*1000L, MICROSECONDS);
neq(now, MILLISECONDS, 0, MILLISECONDS);
neq(now, MILLISECONDS, 0, MICROSECONDS);
eq(nowInstant, now, MILLISECONDS);
eq(nowInstant, now*1000L, MICROSECONDS);
neq(nowInstant, 0, MILLISECONDS);
neq(nowInstant, 0, MICROSECONDS);
// compareTo
cmp(now, MILLISECONDS, now, MILLISECONDS, 0);
cmp(now, MILLISECONDS, now*1000L, MICROSECONDS, 0);
cmp(now, MILLISECONDS, now-1234, MILLISECONDS, 1);
cmp(now, MILLISECONDS, now+1234, MILLISECONDS, -1);
cmp(tomorrowInDays, DAYS, now, MILLISECONDS, 1);
cmp(now, MILLISECONDS, tomorrowInDays, DAYS, -1);
cmp(yesterdayInDays, DAYS, now, MILLISECONDS, -1);
cmp(now, MILLISECONDS, yesterdayInDays, DAYS, 1);
cmp(yesterdayInDays, DAYS, now, MILLISECONDS, -1);
cmp(Long.MAX_VALUE, DAYS, Long.MAX_VALUE, NANOSECONDS, 1);
cmp(Long.MAX_VALUE, DAYS, Long.MIN_VALUE, NANOSECONDS, 1);
cmp(Long.MIN_VALUE, DAYS, Long.MIN_VALUE, NANOSECONDS, -1);
cmp(Long.MIN_VALUE, DAYS, Long.MAX_VALUE, NANOSECONDS, -1);
cmp(Instant.MIN, Long.MIN_VALUE, DAYS, 1);
cmp(Instant.MIN, Long.MIN_VALUE, HOURS, 1);
cmp(Instant.MIN, Long.MIN_VALUE, MINUTES, 1);
cmp(Instant.MIN, Long.MIN_VALUE, SECONDS, 1);
cmp(Instant.MIN, Instant.MIN.getEpochSecond() - 1, SECONDS, 1);
cmp(Instant.MIN, Instant.MIN.getEpochSecond() - 100, SECONDS, 1);
cmp(Instant.MIN, Instant.MIN.getEpochSecond(), SECONDS, 0);
cmp(Instant.MAX, Long.MAX_VALUE, DAYS, -1);
cmp(Instant.MAX, Long.MAX_VALUE, HOURS, -1);
cmp(Instant.MAX, Long.MAX_VALUE, MINUTES, -1);
cmp(Instant.MAX, Long.MAX_VALUE, SECONDS, -1);
cmp(Instant.MAX, Instant.MAX.getEpochSecond() + 1, SECONDS, -1);
cmp(Instant.MAX, Instant.MAX.getEpochSecond() + 100, SECONDS, -1);
cmp(Instant.MAX, Instant.MAX.getEpochSecond(), SECONDS, 0);
cmp(nowInstant, now, MILLISECONDS, 0);
cmp(nowInstant, now*1000L, MICROSECONDS, 0);
cmp(nowInstant, now-1234, MILLISECONDS, 1);
cmp(nowInstant, now+1234, MILLISECONDS, -1);
cmp(nowInstant, tomorrowInDays, DAYS, -1);
cmp(nowInstant, yesterdayInDays, DAYS, 1);
// to(TimeUnit)
to(MILLISECONDS.convert(1, DAYS) - 1, MILLISECONDS);
to(MILLISECONDS.convert(1, DAYS) + 0, MILLISECONDS);
......@@ -77,6 +112,64 @@ public class Basic {
to(Long.MAX_VALUE, unit);
}
// toInstant()
int N = 1000;
for (TimeUnit unit : EnumSet.allOf(TimeUnit.class)) {
for (int i = 0; i < N; i++) {
long value = rand.nextLong();
FileTime ft = FileTime.from(value, unit);
Instant instant = ft.toInstant();
if (instant != Instant.MIN && instant != Instant.MAX) {
eqTime(value, unit, instant);
}
}
}
for (TimeUnit unit : EnumSet.allOf(TimeUnit.class)) {
long value = Long.MIN_VALUE;
FileTime ft = FileTime.from(value, unit);
Instant instant = ft.toInstant();
if (unit.compareTo(TimeUnit.SECONDS) < 0) {
eqTime(value, unit, instant);
} else if (!instant.equals(Instant.MIN)) {
throw new RuntimeException("should overflow to MIN");
}
value = Long.MAX_VALUE;
ft = FileTime.from(value, unit);
instant = ft.toInstant();
if (unit.compareTo(TimeUnit.SECONDS) < 0) {
eqTime(value, unit, instant);
} else if (!instant.equals(Instant.MAX)) {
throw new RuntimeException("should overflow to MAX");
}
}
// from(Instant)
final long MAX_SECOND = 31556889864403199L;
for (int i = 0; i < N; i++) {
long v = rand.nextLong();
long secs = v % MAX_SECOND;
Instant instant = Instant.ofEpochSecond(secs, rand.nextInt(1000_000_000));
FileTime ft = FileTime.from(instant);
if (!ft.toInstant().equals(instant) || ft.to(SECONDS) != secs) {
throw new RuntimeException("from(Instant) failed");
}
long millis = v;
instant = Instant.ofEpochMilli(millis);
ft = FileTime.from(instant);
if (!ft.toInstant().equals(instant) ||
ft.toMillis() != instant.toEpochMilli()) {
throw new RuntimeException("from(Instant) failed");
}
long nanos = v;
ft = FileTime.from(nanos, NANOSECONDS);
secs = nanos / 1000_000_000;
nanos = nanos % 1000_000_000;
instant = Instant.ofEpochSecond(secs, nanos);
if (!ft.equals(FileTime.from(instant))) {
throw new RuntimeException("from(Instant) failed");
}
}
// toString
ts(1L, DAYS, "1970-01-02T00:00:00Z");
ts(1L, HOURS, "1970-01-01T01:00:00Z");
......@@ -108,11 +201,18 @@ public class Basic {
// NTFS epoch in usec.
ts(-11644473600000000L, MICROSECONDS, "1601-01-01T00:00:00Z");
// nulls
ts(Instant.MIN, "-1000000001-01-01T00:00:00Z");
ts(Instant.MAX, "1000000000-12-31T23:59:59.999999999Z");
try {
FileTime.from(0L, null);
throw new RuntimeException("NullPointerException expected");
} catch (NullPointerException npe) { }
try {
FileTime.from(null);
throw new RuntimeException("NullPointerException expected");
} catch (NullPointerException npe) { }
FileTime time = FileTime.fromMillis(now);
if (time.equals(null))
throw new RuntimeException("should not be equal to null");
......@@ -120,6 +220,39 @@ public class Basic {
time.compareTo(null);
throw new RuntimeException("NullPointerException expected");
} catch (NullPointerException npe) { }
// Instant + toMilli() overflow
overflow(Long.MAX_VALUE,
FileTime.from(Instant.MAX).toMillis());
overflow(Long.MAX_VALUE,
FileTime.from(Instant.ofEpochSecond(Long.MAX_VALUE / 1000 + 1))
.toMillis());
overflow(Long.MIN_VALUE,
FileTime.from(Instant.MIN).toMillis());
overflow(Long.MIN_VALUE,
FileTime.from(Instant.ofEpochSecond(Long.MIN_VALUE / 1000 - 1))
.toMillis());
// Instant + to(TimeUnit) overflow
overflow(Long.MAX_VALUE,
FileTime.from(Instant.ofEpochSecond(Long.MAX_VALUE / 1000 + 1))
.to(MILLISECONDS));
overflow(Long.MAX_VALUE,
FileTime.from(Instant.ofEpochSecond(Long.MAX_VALUE / 1000,
MILLISECONDS.toNanos(1000)))
.to(MILLISECONDS));
overflow(Long.MIN_VALUE,
FileTime.from(Instant.ofEpochSecond(Long.MIN_VALUE / 1000 - 1))
.to(MILLISECONDS));
overflow(Long.MIN_VALUE,
FileTime.from(Instant.ofEpochSecond(Long.MIN_VALUE / 1000,
-MILLISECONDS.toNanos(1)))
.to(MILLISECONDS));
}
static void overflow(long minmax, long v) {
if (v != minmax)
throw new RuntimeException("saturates to Long.MIN/MAX_VALUE expected");
}
static void cmp(long v1, TimeUnit u1, long v2, TimeUnit u2, int expected) {
......@@ -128,6 +261,12 @@ public class Basic {
throw new RuntimeException("unexpected order");
}
static void cmp(Instant ins, long v2, TimeUnit u2, int expected) {
int result = FileTime.from(ins).compareTo(FileTime.from(v2, u2));
if (result != expected)
throw new RuntimeException("unexpected order");
}
static void eq(long v1, TimeUnit u1, long v2, TimeUnit u2) {
FileTime t1 = FileTime.from(v1, u1);
FileTime t2 = FileTime.from(v2, u2);
......@@ -137,6 +276,28 @@ public class Basic {
throw new RuntimeException("hashCodes should be equal");
}
static void eq(Instant ins, long v2, TimeUnit u2) {
FileTime t1 = FileTime.from(ins);
FileTime t2 = FileTime.from(v2, u2);
if (!t1.equals(t2))
throw new RuntimeException("not equal");
if (t1.hashCode() != t2.hashCode())
throw new RuntimeException("hashCodes should be equal");
}
static void eqTime(long value, TimeUnit unit, Instant instant) {
long secs = SECONDS.convert(value, unit);
long nanos = NANOSECONDS.convert(value - unit.convert(secs, SECONDS), unit);
if (nanos < 0) { // normalize nanoOfSecond to positive
secs -= 1;
nanos += 1000_000_000;
}
if (secs != instant.getEpochSecond() || (int)nanos != instant.getNano()) {
System.err.println(" ins=" + instant);
throw new RuntimeException("ft and instant are not the same time point");
}
}
static void neq(long v1, TimeUnit u1, long v2, TimeUnit u2) {
FileTime t1 = FileTime.from(v1, u1);
FileTime t2 = FileTime.from(v2, u2);
......@@ -144,6 +305,13 @@ public class Basic {
throw new RuntimeException("should not be equal");
}
static void neq(Instant ins, long v2, TimeUnit u2) {
FileTime t1 = FileTime.from(ins);
FileTime t2 = FileTime.from(v2, u2);
if (t1.equals(t2))
throw new RuntimeException("should not be equal");
}
static void to(long v, TimeUnit unit) {
FileTime t = FileTime.from(v, unit);
for (TimeUnit u: TimeUnit.values()) {
......@@ -164,4 +332,14 @@ public class Basic {
throw new RuntimeException();
}
}
static void ts(Instant instant, String expected) {
String result = FileTime.from(instant).toString();
if (!result.equals(expected)) {
System.err.format("FileTime.from(%s).toString() failed\n", instant);
System.err.format("Expected: %s\n", expected);
System.err.format(" Got: %s\n", result);
throw new RuntimeException();
}
}
}
......@@ -23,8 +23,8 @@
/*
* @test
* @bug 8001667
* @run testng ComparatorsTest
* @bug 8001667 8010279
* @run testng BasicTest
*/
import java.util.Comparator;
......@@ -33,6 +33,7 @@ import java.util.AbstractMap;
import java.util.Map;
import org.testng.annotations.Test;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;
......@@ -41,12 +42,13 @@ import java.util.function.ToDoubleFunction;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.assertSame;
import static org.testng.Assert.fail;
/**
* Unit tests for helper methods in Comparators
*/
@Test(groups = "unit")
public class ComparatorsTest {
public class BasicTest {
private static class Thing {
public final int intField;
public final long longField;
......@@ -95,7 +97,7 @@ public class ComparatorsTest {
Thing[] things = new Thing[intValues.length];
for (int i=0; i<intValues.length; i++)
things[i] = new Thing(intValues[i], 0L, 0.0, null);
Comparator<Thing> comp = Comparators.comparing(new ToIntFunction<ComparatorsTest.Thing>() {
Comparator<Thing> comp = Comparators.comparing(new ToIntFunction<BasicTest.Thing>() {
@Override
public int applyAsInt(Thing thing) {
return thing.getIntField();
......@@ -109,7 +111,7 @@ public class ComparatorsTest {
Thing[] things = new Thing[longValues.length];
for (int i=0; i<longValues.length; i++)
things[i] = new Thing(0, longValues[i], 0.0, null);
Comparator<Thing> comp = Comparators.comparing(new ToLongFunction<ComparatorsTest.Thing>() {
Comparator<Thing> comp = Comparators.comparing(new ToLongFunction<BasicTest.Thing>() {
@Override
public long applyAsLong(Thing thing) {
return thing.getLongField();
......@@ -123,7 +125,7 @@ public class ComparatorsTest {
Thing[] things = new Thing[doubleValues.length];
for (int i=0; i<doubleValues.length; i++)
things[i] = new Thing(0, 0L, doubleValues[i], null);
Comparator<Thing> comp = Comparators.comparing(new ToDoubleFunction<ComparatorsTest.Thing>() {
Comparator<Thing> comp = Comparators.comparing(new ToDoubleFunction<BasicTest.Thing>() {
@Override
public double applyAsDouble(Thing thing) {
return thing.getDoubleField();
......@@ -350,4 +352,61 @@ public class ComparatorsTest {
.apply(people[0], people[1]),
people[1]);
}
}
\ No newline at end of file
public void testNulls() {
try {
Comparators.<String>naturalOrder().compare("abc", (String) null);
fail("expected NPE with naturalOrder");
} catch (NullPointerException npe) {}
try {
Comparators.<String>naturalOrder().compare((String) null, "abc");
fail("expected NPE with naturalOrder");
} catch (NullPointerException npe) {}
try {
Comparators.<String>reverseOrder().compare("abc", (String) null);
fail("expected NPE with naturalOrder");
} catch (NullPointerException npe) {}
try {
Comparators.<String>reverseOrder().compare((String) null, "abc");
fail("expected NPE with naturalOrder");
} catch (NullPointerException npe) {}
try {
Comparator<Map.Entry<String, String>> cmp = Comparators.byKey(null);
fail("byKey(null) should throw NPE");
} catch (NullPointerException npe) {}
try {
Comparator<Map.Entry<String, String>> cmp = Comparators.byValue(null);
fail("byValue(null) should throw NPE");
} catch (NullPointerException npe) {}
try {
Comparator<People> cmp = Comparators.comparing((Function<People, String>) null);
fail("comparing(null) should throw NPE");
} catch (NullPointerException npe) {}
try {
Comparator<People> cmp = Comparators.comparing((ToIntFunction<People>) null);
fail("comparing(null) should throw NPE");
} catch (NullPointerException npe) {}
try {
Comparator<People> cmp = Comparators.comparing((ToLongFunction<People>) null);
fail("comparing(null) should throw NPE");
} catch (NullPointerException npe) {}
try {
Comparator<People> cmp = Comparators.comparing((ToDoubleFunction<People>) null);
fail("comparing(null) should throw NPE");
} catch (NullPointerException npe) {}
try {
BinaryOperator<String> op = Comparators.lesserOf(null);
fail("lesserOf(null) should throw NPE");
} catch (NullPointerException npe) {}
try {
BinaryOperator<String> op = Comparators.greaterOf(null);
fail("lesserOf(null) should throw NPE");
} catch (NullPointerException npe) {}
}
}
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8011200
* @run testng BasicSerialization
* @summary Ensure Maps can be serialized and deserialized.
* @author Mike Duigou
*/
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ByteArrayInputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap;
import org.testng.annotations.Test;
import org.testng.annotations.DataProvider;
import static org.testng.Assert.fail;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertSame;
public class BasicSerialization {
enum IntegerEnum {
e0, e1, e2, e3, e4, e5, e6, e7, e8, e9,
e10, e11, e12, e13, e14, e15, e16, e17, e18, e19,
e20, e21, e22, e23, e24, e25, e26, e27, e28, e29,
e30, e31, e32, e33, e34, e35, e36, e37, e38, e39,
e40, e41, e42, e43, e44, e45, e46, e47, e48, e49,
e50, e51, e52, e53, e54, e55, e56, e57, e58, e59,
e60, e61, e62, e63, e64, e65, e66, e67, e68, e69,
e70, e71, e72, e73, e74, e75, e76, e77, e78, e79,
e80, e81, e82, e83, e84, e85, e86, e87, e88, e89,
e90, e91, e92, e93, e94, e95, e96, e97, e98, e99,
EXTRA_KEY;
public static final int SIZE = values().length;
};
private static final int TEST_SIZE = IntegerEnum.SIZE - 1;
/**
* Realized keys ensure that there is always a hard ref to all test objects.
*/
private static final IntegerEnum[] KEYS = new IntegerEnum[TEST_SIZE];
/**
* Realized values ensure that there is always a hard ref to all test
* objects.
*/
private static final String[] VALUES = new String[TEST_SIZE];
static {
IntegerEnum[] keys = IntegerEnum.values();
for (int each = 0; each < TEST_SIZE; each++) {
KEYS[each] = keys[each];
VALUES[each] = keys[each].name();
}
}
private static final IntegerEnum EXTRA_KEY = IntegerEnum.EXTRA_KEY;
private static final String EXTRA_VALUE = IntegerEnum.EXTRA_KEY.name();
public static <K, V> Map<K, V> mapClone(Map<K, V> map) {
Method cloneMethod;
try {
cloneMethod = map.getClass().getMethod("clone", new Class[]{});
} catch (NoSuchMethodException | SecurityException all) {
cloneMethod = null;
}
if (null != cloneMethod) {
try {
Map<K, V> result = (Map<K, V>)cloneMethod.invoke(map, new Object[]{});
return result;
} catch (Exception all) {
fail("clone() failed " + map.getClass().getSimpleName(), all);
return null;
}
} else {
Constructor<? extends Map> copyConstructor;
try {
copyConstructor = (Constructor<? extends Map>)map.getClass().getConstructor(new Class[]{Map.class});
Map<K, V> result = (Map<K, V>)copyConstructor.newInstance(new Object[]{map});
return result;
} catch (Exception all) {
return serialClone(map);
}
}
}
@Test(dataProvider = "Map<IntegerEnum,String>")
public void testSerialization(String description, Map<IntegerEnum, String> map) {
Object foo = new Object();
Map<IntegerEnum, String> clone = mapClone(map);
Map<IntegerEnum, String> serialClone = serialClone(map);
assertEquals(map, map, description + ":should equal self");
assertEquals(clone, map, description + ":should equal clone");
assertEquals(map, clone, description + ": should equal orginal map");
assertEquals(serialClone, map, description + ": should equal deserialized clone");
assertEquals(map, serialClone, description + ": should equal original map");
assertEquals(serialClone, clone, description + ": deserialized clone should equal clone");
assertEquals(clone, serialClone, description + ": clone should equal deserialized clone");
assertFalse(map.containsKey(EXTRA_KEY), description + ":unexpected key");
assertFalse(clone.containsKey(EXTRA_KEY), description + ":unexpected key");
assertFalse(serialClone.containsKey(EXTRA_KEY), description + ":unexpected key");
map.put(EXTRA_KEY, EXTRA_VALUE);
clone.put(EXTRA_KEY, EXTRA_VALUE);
serialClone.put(EXTRA_KEY, EXTRA_VALUE);
assertTrue(map.containsKey(EXTRA_KEY), description + ":missing key");
assertTrue(clone.containsKey(EXTRA_KEY), description + ":missing key");
assertTrue(serialClone.containsKey(EXTRA_KEY), description + ":missing key");
assertSame(map.get(EXTRA_KEY), EXTRA_VALUE, description + ":wrong value");
assertSame(clone.get(EXTRA_KEY), EXTRA_VALUE, description + ":wrong value");
assertSame(serialClone.get(EXTRA_KEY), EXTRA_VALUE, description + ":wrong value");
assertEquals(map, map, description + ":should equal self");
assertEquals(clone, map, description + ":should equal clone");
assertEquals(map, clone, description + ": should equal orginal map");
assertEquals(serialClone, map, description + ": should equal deserialized clone");
assertEquals(map, serialClone, description + ": should equal original map");
assertEquals(serialClone, clone, description + ": deserialized clone should equal clone");
assertEquals(clone, serialClone, description + ": clone should equal deserialized clone");
}
static byte[] serializedForm(Object obj) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
new ObjectOutputStream(baos).writeObject(obj);
return baos.toByteArray();
} catch (IOException e) {
fail("Unexpected Exception", e);
return null;
}
}
static Object readObject(byte[] bytes) throws IOException, ClassNotFoundException {
InputStream is = new ByteArrayInputStream(bytes);
return new ObjectInputStream(is).readObject();
}
@SuppressWarnings("unchecked")
static <T> T serialClone(T obj) {
try {
return (T)readObject(serializedForm(obj));
} catch (IOException | ClassNotFoundException e) {
fail("Unexpected Exception", e);
return null;
}
}
@DataProvider(name = "Map<IntegerEnum,String>", parallel = true)
private static Iterator<Object[]> makeMaps() {
return Arrays.asList(
// empty
new Object[]{"HashMap", new HashMap()},
new Object[]{"LinkedHashMap", new LinkedHashMap()},
new Object[]{"Collections.checkedMap(HashMap)", Collections.checkedMap(new HashMap(), IntegerEnum.class, String.class)},
new Object[]{"Collections.synchronizedMap(HashMap)", Collections.synchronizedMap(new HashMap())},
// null hostile
new Object[]{"EnumMap", new EnumMap(IntegerEnum.class)},
new Object[]{"Hashtable", new Hashtable()},
new Object[]{"TreeMap", new TreeMap()},
new Object[]{"ConcurrentHashMap", new ConcurrentHashMap()},
new Object[]{"ConcurrentSkipListMap", new ConcurrentSkipListMap()},
new Object[]{"Collections.checkedMap(ConcurrentHashMap)", Collections.checkedMap(new ConcurrentHashMap(), IntegerEnum.class, String.class)},
new Object[]{"Collections.synchronizedMap(EnumMap)", Collections.synchronizedMap(new EnumMap(IntegerEnum.class))},
// filled
new Object[]{"HashMap", fillMap(new HashMap())},
new Object[]{"LinkedHashMap", fillMap(new LinkedHashMap())},
new Object[]{"Collections.checkedMap(HashMap)", Collections.checkedMap(fillMap(new HashMap()), IntegerEnum.class, String.class)},
new Object[]{"Collections.synchronizedMap(HashMap)", Collections.synchronizedMap(fillMap(new HashMap()))},
// null hostile
new Object[]{"EnumMap", fillMap(new EnumMap(IntegerEnum.class))},
new Object[]{"Hashtable", fillMap(new Hashtable())},
new Object[]{"TreeMap", fillMap(new TreeMap())},
new Object[]{"ConcurrentHashMap", fillMap(new ConcurrentHashMap())},
new Object[]{"ConcurrentSkipListMap", fillMap(new ConcurrentSkipListMap())},
new Object[]{"Collections.checkedMap(ConcurrentHashMap)", Collections.checkedMap(fillMap(new ConcurrentHashMap()), IntegerEnum.class, String.class)},
new Object[]{"Collections.synchronizedMap(EnumMap)", Collections.synchronizedMap(fillMap(new EnumMap(IntegerEnum.class)))}).iterator();
}
private static Map<IntegerEnum, String> fillMap(Map<IntegerEnum, String> result) {
for (int each = 0; each < TEST_SIZE; each++) {
result.put(KEYS[each], VALUES[each]);
}
return result;
}
}
/*
* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -23,12 +23,13 @@
/*
* @test
* @bug 6797535 6889858 6891113
* @bug 6797535 6889858 6891113 8011800
* @summary Basic tests for methods in java.util.Objects
* @author Joseph D. Darcy
*/
import java.util.*;
import java.util.function.*;
public class BasicObjectsTest {
public static void main(String... args) {
......@@ -40,7 +41,7 @@ public class BasicObjectsTest {
errors += testToString();
errors += testToString2();
errors += testCompare();
errors += testNonNull();
errors += testRequireNonNull();
if (errors > 0 )
throw new RuntimeException();
}
......@@ -158,49 +159,54 @@ public class BasicObjectsTest {
return errors;
}
private static int testNonNull() {
private static int testRequireNonNull() {
int errors = 0;
String s;
// Test 1-arg variant
try {
s = Objects.requireNonNull("pants");
if (s != "pants") {
System.err.printf("1-arg non-null failed to return its arg");
errors++;
}
} catch (NullPointerException e) {
System.err.printf("1-arg nonNull threw unexpected NPE");
errors++;
}
final String RNN_1 = "1-arg requireNonNull";
final String RNN_2 = "2-arg requireNonNull";
final String RNN_3 = "Supplier requireNonNull";
try {
s = Objects.requireNonNull(null);
System.err.printf("1-arg nonNull failed to throw NPE");
errors++;
} catch (NullPointerException e) {
// Expected
}
Function<String, String> rnn1 = s -> Objects.requireNonNull(s);
Function<String, String> rnn2 = s -> Objects.requireNonNull(s, "trousers");
Function<String, String> rnn3 = s -> Objects.requireNonNull(s, () -> "trousers");
errors += testRNN_NonNull(rnn1, RNN_1);
errors += testRNN_NonNull(rnn2, RNN_2);
errors += testRNN_NonNull(rnn3, RNN_3);
errors += testRNN_Null(rnn1, RNN_1, null);
errors += testRNN_Null(rnn2, RNN_2, "trousers");
errors += testRNN_Null(rnn3, RNN_3, "trousers");
return errors;
}
// Test 2-arg variant
private static int testRNN_NonNull(Function<String, String> testFunc,
String testFuncName) {
int errors = 0;
try {
s = Objects.requireNonNull("pants", "trousers");
String s = testFunc.apply("pants");
if (s != "pants") {
System.err.printf("2-arg nonNull failed to return its arg");
System.err.printf(testFuncName + " failed to return its arg");
errors++;
}
} catch (NullPointerException e) {
System.err.printf("2-arg nonNull threw unexpected NPE");
System.err.printf(testFuncName + " threw unexpected NPE");
errors++;
}
return errors;
}
private static int testRNN_Null(Function<String, String> testFunc,
String testFuncName,
String expectedMessage) {
int errors = 0;
try {
s = Objects.requireNonNull(null, "pantaloons");
System.err.printf("2-arg nonNull failed to throw NPE");
String s = testFunc.apply(null);
System.err.printf(testFuncName + " failed to throw NPE");
errors++;
} catch (NullPointerException e) {
if (e.getMessage() != "pantaloons") {
System.err.printf("2-arg nonNull threw NPE w/ bad detail msg");
if (e.getMessage() != expectedMessage) {
System.err.printf(testFuncName + " threw NPE w/ bad detail msg");
errors++;
}
}
......
......@@ -486,40 +486,40 @@ public class Basic {
CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
CompletableFuture<Integer> cf2 = supplyAsync(() -> 2);
cf3 = cf1.applyToEither(cf2, (x) -> { check(x == 1 || x == 2); return x; });
check(cf1.isDone() || cf2.isDone());
checkCompletedNormally(cf3, new Object[] {1, 2});
check(cf1.isDone() || cf2.isDone());
cf1 = supplyAsync(() -> 1);
cf2 = supplyAsync(() -> 2);
cf3 = cf1.applyToEitherAsync(cf2, (x) -> { check(x == 1 || x == 2); return x; });
check(cf1.isDone() || cf2.isDone());
checkCompletedNormally(cf3, new Object[] {1, 2});
check(cf1.isDone() || cf2.isDone());
cf1 = supplyAsync(() -> 1);
cf2 = supplyAsync(() -> 2);
cf3 = cf1.applyToEitherAsync(cf2, (x) -> { check(x == 1 || x == 2); return x; }, executor);
check(cf1.isDone() || cf2.isDone());
checkCompletedNormally(cf3, new Object[] {1, 2});
check(cf1.isDone() || cf2.isDone());
cf1 = supplyAsync(() -> { throw new RuntimeException(); });
cf2 = supplyAsync(() -> 2);
cf3 = cf1.applyToEither(cf2, (x) -> { check(x == 2); return x; });
check(cf1.isDone() || cf2.isDone());
try { check(cf3.join() == 1); } catch (CompletionException x) { pass(); }
check(cf3.isDone());
check(cf1.isDone() || cf2.isDone());
cf1 = supplyAsync(() -> 1);
cf2 = supplyAsync(() -> { throw new RuntimeException(); });
cf3 = cf1.applyToEitherAsync(cf2, (x) -> { check(x == 1); return x; });
check(cf1.isDone() || cf2.isDone());
try { check(cf3.join() == 1); } catch (CompletionException x) { pass(); }
check(cf3.isDone());
check(cf1.isDone() || cf2.isDone());
cf1 = supplyAsync(() -> { throw new RuntimeException(); });
cf2 = supplyAsync(() -> { throw new RuntimeException(); });
cf3 = cf1.applyToEitherAsync(cf2, (x) -> { fail(); return x; });
check(cf1.isDone() || cf2.isDone());
checkCompletedExceptionally(cf3);
check(cf1.isDone() || cf2.isDone());
} catch (Throwable t) { unexpected(t); }
//----------------------------------------------------------------
......@@ -531,45 +531,45 @@ public class Basic {
CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
CompletableFuture<Integer> cf2 = supplyAsync(() -> 2);
cf3 = cf1.acceptEither(cf2, (x) -> { check(x == 1 || x == 2); atomicInt.incrementAndGet(); });
check(cf1.isDone() || cf2.isDone());
checkCompletedNormally(cf3, null);
check(cf1.isDone() || cf2.isDone());
check(atomicInt.get() == (before + 1));
before = atomicInt.get();
cf1 = supplyAsync(() -> 1);
cf2 = supplyAsync(() -> 2);
cf3 = cf1.acceptEitherAsync(cf2, (x) -> { check(x == 1 || x == 2); atomicInt.incrementAndGet(); });
check(cf1.isDone() || cf2.isDone());
checkCompletedNormally(cf3, null);
check(cf1.isDone() || cf2.isDone());
check(atomicInt.get() == (before + 1));
before = atomicInt.get();
cf1 = supplyAsync(() -> 1);
cf2 = supplyAsync(() -> 2);
cf3 = cf2.acceptEitherAsync(cf1, (x) -> { check(x == 1 || x == 2); atomicInt.incrementAndGet(); }, executor);
check(cf1.isDone() || cf2.isDone());
checkCompletedNormally(cf3, null);
check(cf1.isDone() || cf2.isDone());
check(atomicInt.get() == (before + 1));
cf1 = supplyAsync(() -> { throw new RuntimeException(); });
cf2 = supplyAsync(() -> 2);
cf3 = cf2.acceptEitherAsync(cf1, (x) -> { check(x == 2); }, executor);
check(cf1.isDone() || cf2.isDone());
try { check(cf3.join() == null); } catch (CompletionException x) { pass(); }
check(cf3.isDone());
check(cf1.isDone() || cf2.isDone());
cf1 = supplyAsync(() -> 1);
cf2 = supplyAsync(() -> { throw new RuntimeException(); });
cf3 = cf2.acceptEitherAsync(cf1, (x) -> { check(x == 1); });
check(cf1.isDone() || cf2.isDone());
try { check(cf3.join() == null); } catch (CompletionException x) { pass(); }
check(cf3.isDone());
check(cf1.isDone() || cf2.isDone());
cf1 = supplyAsync(() -> { throw new RuntimeException(); });
cf2 = supplyAsync(() -> { throw new RuntimeException(); });
cf3 = cf2.acceptEitherAsync(cf1, (x) -> { fail(); });
check(cf1.isDone() || cf2.isDone());
checkCompletedExceptionally(cf3);
check(cf1.isDone() || cf2.isDone());
} catch (Throwable t) { unexpected(t); }
//----------------------------------------------------------------
......@@ -581,50 +581,50 @@ public class Basic {
CompletableFuture<Void> cf1 = runAsync(() -> { });
CompletableFuture<Void> cf2 = runAsync(() -> { });
cf3 = cf1.runAfterEither(cf2, () -> { atomicInt.incrementAndGet(); });
check(cf1.isDone() || cf2.isDone());
checkCompletedNormally(cf3, null);
check(cf1.isDone() || cf2.isDone());
check(atomicInt.get() == (before + 1));
before = atomicInt.get();
cf1 = runAsync(() -> { });
cf2 = runAsync(() -> { });
cf3 = cf1.runAfterEitherAsync(cf2, () -> { atomicInt.incrementAndGet(); });
check(cf1.isDone() || cf2.isDone());
checkCompletedNormally(cf3, null);
check(cf1.isDone() || cf2.isDone());
check(atomicInt.get() == (before + 1));
before = atomicInt.get();
cf1 = runAsync(() -> { });
cf2 = runAsync(() -> { });
cf3 = cf2.runAfterEitherAsync(cf1, () -> { atomicInt.incrementAndGet(); }, executor);
check(cf1.isDone() || cf2.isDone());
checkCompletedNormally(cf3, null);
check(cf1.isDone() || cf2.isDone());
check(atomicInt.get() == (before + 1));
before = atomicInt.get();
cf1 = runAsync(() -> { throw new RuntimeException(); });
cf2 = runAsync(() -> { });
cf3 = cf2.runAfterEither(cf1, () -> { atomicInt.incrementAndGet(); });
check(cf1.isDone() || cf2.isDone());
try { check(cf3.join() == null); } catch (CompletionException x) { pass(); }
check(cf3.isDone());
check(cf1.isDone() || cf2.isDone());
check(atomicInt.get() == (before + 1));
before = atomicInt.get();
cf1 = runAsync(() -> { });
cf2 = runAsync(() -> { throw new RuntimeException(); });
cf3 = cf1.runAfterEitherAsync(cf2, () -> { atomicInt.incrementAndGet(); });
check(cf1.isDone() || cf2.isDone());
try { check(cf3.join() == null); } catch (CompletionException x) { pass(); }
check(cf3.isDone());
check(cf1.isDone() || cf2.isDone());
check(atomicInt.get() == (before + 1));
before = atomicInt.get();
cf1 = runAsync(() -> { throw new RuntimeException(); });
cf2 = runAsync(() -> { throw new RuntimeException(); });
cf3 = cf2.runAfterEitherAsync(cf1, () -> { atomicInt.incrementAndGet(); }, executor);
check(cf1.isDone() || cf2.isDone());
checkCompletedExceptionally(cf3);
check(cf1.isDone() || cf2.isDone());
check(atomicInt.get() == before);
} catch (Throwable t) { unexpected(t); }
......@@ -670,16 +670,16 @@ public class Basic {
//----------------------------------------------------------------
// anyOf tests
//----------------------------------------------------------------
//try {
// CompletableFuture<Object> cf3;
// for (int k=0; k < 10; k++){
// CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
// CompletableFuture<Integer> cf2 = supplyAsync(() -> 2);
// cf3 = CompletableFuture.anyOf(cf1, cf2);
// check(cf1.isDone() || cf2.isDone());
// checkCompletedNormally(cf3, new Object[] {1, 2});
// }
//} catch (Throwable t) { unexpected(t); }
try {
CompletableFuture<Object> cf3;
for (int k=0; k < 10; k++){
CompletableFuture<Integer> cf1 = supplyAsync(() -> 1);
CompletableFuture<Integer> cf2 = supplyAsync(() -> 2);
cf3 = CompletableFuture.anyOf(cf1, cf2);
checkCompletedNormally(cf3, new Object[] {1, 2});
check(cf1.isDone() || cf2.isDone());
}
} catch (Throwable t) { unexpected(t); }
//----------------------------------------------------------------
// allOf tests
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册