diff options
Diffstat (limited to 'guava/src/com/google/common/primitives/UnsignedBytes.java')
-rw-r--r-- | guava/src/com/google/common/primitives/UnsignedBytes.java | 388 |
1 files changed, 154 insertions, 234 deletions
diff --git a/guava/src/com/google/common/primitives/UnsignedBytes.java b/guava/src/com/google/common/primitives/UnsignedBytes.java index c503f99..1651295 100644 --- a/guava/src/com/google/common/primitives/UnsignedBytes.java +++ b/guava/src/com/google/common/primitives/UnsignedBytes.java @@ -19,12 +19,16 @@ package com.google.common.primitives; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.annotations.Beta; import com.google.common.annotations.VisibleForTesting; -import sun.misc.Unsafe; +// BEGIN android-changed +//import sun.misc.Unsafe; +// END android-changed +import java.lang.reflect.Field; import java.nio.ByteOrder; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.Comparator; /** @@ -34,35 +38,20 @@ import java.util.Comparator; * the values as signed are found in {@link SignedBytes}, and the methods for * which signedness is not an issue are in {@link Bytes}. * - * <p>See the Guava User Guide article on <a href= - * "http://code.google.com/p/guava-libraries/wiki/PrimitivesExplained"> - * primitive utilities</a>. - * * @author Kevin Bourrillion * @author Martin Buchholz * @author Hiroshi Yamauchi - * @author Louis Wasserman * @since 1.0 */ public final class UnsignedBytes { private UnsignedBytes() {} /** - * The largest power of two that can be represented as an unsigned {@code - * byte}. + * The largest power of two that can be represented as an unsigned {@code byte}. * * @since 10.0 */ - public static final byte MAX_POWER_OF_TWO = (byte) 0x80; - - /** - * The largest value that fits into an unsigned byte. - * - * @since 13.0 - */ - public static final byte MAX_VALUE = (byte) 0xFF; - - private static final int UNSIGNED_MASK = 0xFF; + public static final byte MAX_POWER_OF_TWO = (byte) (1 << 7); /** * Returns the value of the given byte as an integer, when treated as @@ -72,7 +61,7 @@ public final class UnsignedBytes { * @since 6.0 */ public static int toInt(byte value) { - return value & UNSIGNED_MASK; + return value & 0xFF; } /** @@ -86,7 +75,7 @@ public final class UnsignedBytes { * than 255 */ public static byte checkedCast(long value) { - checkArgument(value >> Byte.SIZE == 0, "out of range: %s", value); + checkArgument(value >> 8 == 0, "out of range: %s", value); return (byte) value; } @@ -99,8 +88,8 @@ public final class UnsignedBytes { * {@code value <= 0}, and {@code value} cast to {@code byte} otherwise */ public static byte saturatedCast(long value) { - if (value > toInt(MAX_VALUE)) { - return MAX_VALUE; // -1 + if (value > 255) { + return (byte) 255; // -1 } if (value < 0) { return (byte) 0; @@ -164,71 +153,6 @@ public final class UnsignedBytes { } /** - * Returns a string representation of x, where x is treated as unsigned. - * - * @since 13.0 - */ - @Beta - public static String toString(byte x) { - return toString(x, 10); - } - - /** - * Returns a string representation of {@code x} for the given radix, where {@code x} is treated - * as unsigned. - * - * @param x the value to convert to a string. - * @param radix the radix to use while working with {@code x} - * @throws IllegalArgumentException if {@code radix} is not between {@link Character#MIN_RADIX} - * and {@link Character#MAX_RADIX}. - * @since 13.0 - */ - @Beta - public static String toString(byte x, int radix) { - checkArgument(radix >= Character.MIN_RADIX && radix <= Character.MAX_RADIX, - "radix (%s) must be between Character.MIN_RADIX and Character.MAX_RADIX", radix); - // Benchmarks indicate this is probably not worth optimizing. - return Integer.toString(toInt(x), radix); - } - - /** - * Returns the unsigned {@code byte} value represented by the given decimal string. - * - * @throws NumberFormatException if the string does not contain a valid unsigned {@code byte} - * value - * @throws NullPointerException if {@code s} is null - * (in contrast to {@link Byte#parseByte(String)}) - * @since 13.0 - */ - @Beta - public static byte parseUnsignedByte(String string) { - return parseUnsignedByte(string, 10); - } - - /** - * Returns the unsigned {@code byte} value represented by a string with the given radix. - * - * @param string the string containing the unsigned {@code byte} representation to be parsed. - * @param radix the radix to use while parsing {@code string} - * @throws NumberFormatException if the string does not contain a valid unsigned {@code byte} - * with the given radix, or if {@code radix} is not between {@link Character#MIN_RADIX} - * and {@link Character#MAX_RADIX}. - * @throws NullPointerException if {@code s} is null - * (in contrast to {@link Byte#parseByte(String)}) - * @since 13.0 - */ - @Beta - public static byte parseUnsignedByte(String string, int radix) { - int parse = Integer.parseInt(checkNotNull(string), radix); - // We need to throw a NumberFormatException, so we have to duplicate checkedCast. =( - if (parse >> Byte.SIZE == 0) { - return (byte) parse; - } else { - throw new NumberFormatException("out of range: " + parse); - } - } - - /** * Returns a string containing the supplied {@code byte} values separated by * {@code separator}. For example, {@code join(":", (byte) 1, (byte) 2, * (byte) 255)} returns the string {@code "1:2:255"}. @@ -244,10 +168,10 @@ public final class UnsignedBytes { } // For pre-sizing a builder, just get the right order of magnitude - StringBuilder builder = new StringBuilder(array.length * (3 + separator.length())); + StringBuilder builder = new StringBuilder(array.length * 5); builder.append(toInt(array[0])); for (int i = 1; i < array.length; i++) { - builder.append(separator).append(toString(array[i])); + builder.append(separator).append(toInt(array[i])); } return builder.toString(); } @@ -289,133 +213,123 @@ public final class UnsignedBytes { static final String UNSAFE_COMPARATOR_NAME = LexicographicalComparatorHolder.class.getName() + "$UnsafeComparator"; - static final Comparator<byte[]> BEST_COMPARATOR = getBestComparator(); - - @VisibleForTesting - enum UnsafeComparator implements Comparator<byte[]> { - INSTANCE; - - static final boolean littleEndian = - ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN); - - /* - * The following static final fields exist for performance reasons. - * - * In UnsignedBytesBenchmark, accessing the following objects via static - * final fields is the fastest (more than twice as fast as the Java - * implementation, vs ~1.5x with non-final static fields, on x86_32) - * under the Hotspot server compiler. The reason is obviously that the - * non-final fields need to be reloaded inside the loop. - * - * And, no, defining (final or not) local variables out of the loop still - * isn't as good because the null check on the theUnsafe object remains - * inside the loop and BYTE_ARRAY_BASE_OFFSET doesn't get - * constant-folded. - * - * The compiler can treat static final fields as compile-time constants - * and can constant-fold them while (final or not) local variables are - * run time values. - */ - - static final Unsafe theUnsafe; - - /** The offset to the first element in a byte array. */ - static final int BYTE_ARRAY_BASE_OFFSET; - - static { - theUnsafe = getUnsafe(); - - BYTE_ARRAY_BASE_OFFSET = theUnsafe.arrayBaseOffset(byte[].class); - - // sanity check - this should never fail - if (theUnsafe.arrayIndexScale(byte[].class) != 1) { - throw new AssertionError(); - } - } - - /** - * Returns a sun.misc.Unsafe. Suitable for use in a 3rd party package. - * Replace with a simple call to Unsafe.getUnsafe when integrating - * into a jdk. - * - * @return a sun.misc.Unsafe - */ - private static sun.misc.Unsafe getUnsafe() { - try { - return sun.misc.Unsafe.getUnsafe(); - } catch (SecurityException tryReflectionInstead) {} - try { - return java.security.AccessController.doPrivileged - (new java.security.PrivilegedExceptionAction<sun.misc.Unsafe>() { - public sun.misc.Unsafe run() throws Exception { - Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class; - for (java.lang.reflect.Field f : k.getDeclaredFields()) { - f.setAccessible(true); - Object x = f.get(null); - if (k.isInstance(x)) - return k.cast(x); - } - throw new NoSuchFieldError("the Unsafe"); - }}); - } catch (java.security.PrivilegedActionException e) { - throw new RuntimeException("Could not initialize intrinsics", - e.getCause()); - } - } - - @Override public int compare(byte[] left, byte[] right) { - int minLength = Math.min(left.length, right.length); - int minWords = minLength / Longs.BYTES; - - /* - * Compare 8 bytes at a time. Benchmarking shows comparing 8 bytes at a - * time is no slower than comparing 4 bytes at a time even on 32-bit. - * On the other hand, it is substantially faster on 64-bit. - */ - for (int i = 0; i < minWords * Longs.BYTES; i += Longs.BYTES) { - long lw = theUnsafe.getLong(left, BYTE_ARRAY_BASE_OFFSET + (long) i); - long rw = theUnsafe.getLong(right, BYTE_ARRAY_BASE_OFFSET + (long) i); - long diff = lw ^ rw; - - if (diff != 0) { - if (!littleEndian) { - return UnsignedLongs.compare(lw, rw); - } - - // Use binary search - int n = 0; - int y; - int x = (int) diff; - if (x == 0) { - x = (int) (diff >>> 32); - n = 32; - } - - y = x << 16; - if (y == 0) { - n += 16; - } else { - x = y; - } - - y = x << 8; - if (y == 0) { - n += 8; - } - return (int) (((lw >>> n) & UNSIGNED_MASK) - ((rw >>> n) & UNSIGNED_MASK)); - } - } - - // The epilogue to cover the last (minLength % 8) elements. - for (int i = minWords * Longs.BYTES; i < minLength; i++) { - int result = UnsignedBytes.compare(left[i], right[i]); - if (result != 0) { - return result; - } - } - return left.length - right.length; - } - } + // BEGIN android-changed + + static final Comparator<byte[]> BEST_COMPARATOR = lexicographicalComparatorJavaImpl(); + + // @VisibleForTesting + // enum UnsafeComparator implements Comparator<byte[]> { + // INSTANCE; + + // static final boolean littleEndian = + // ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN); + + // /* + // * The following static final fields exist for performance reasons. + // * + // * In UnsignedBytesBenchmark, accessing the following objects via static + // * final fields is the fastest (more than twice as fast as the Java + // * implementation, vs ~1.5x with non-final static fields, on x86_32) + // * under the Hotspot server compiler. The reason is obviously that the + // * non-final fields need to be reloaded inside the loop. + // * + // * And, no, defining (final or not) local variables out of the loop still + // * isn't as good because the null check on the theUnsafe object remains + // * inside the loop and BYTE_ARRAY_BASE_OFFSET doesn't get + // * constant-folded. + // * + // * The compiler can treat static final fields as compile-time constants + // * and can constant-fold them while (final or not) local variables are + // * run time values. + // */ + + // static final Unsafe theUnsafe; + + // /** The offset to the first element in a byte array. */ + // static final int BYTE_ARRAY_BASE_OFFSET; + + // static { + // theUnsafe = (Unsafe) AccessController.doPrivileged( + // new PrivilegedAction<Object>() { + // @Override + // public Object run() { + // try { + // Field f = Unsafe.class.getDeclaredField("theUnsafe"); + // f.setAccessible(true); + // return f.get(null); + // } catch (NoSuchFieldException e) { + // // It doesn't matter what we throw; + // // it's swallowed in getBestComparator(). + // throw new Error(); + // } catch (IllegalAccessException e) { + // throw new Error(); + // } + // } + // }); + + // BYTE_ARRAY_BASE_OFFSET = theUnsafe.arrayBaseOffset(byte[].class); + + // // sanity check - this should never fail + // if (theUnsafe.arrayIndexScale(byte[].class) != 1) { + // throw new AssertionError(); + // } + // } + + // @Override public int compare(byte[] left, byte[] right) { + // int minLength = Math.min(left.length, right.length); + // int minWords = minLength / Longs.BYTES; + + // /* + // * Compare 8 bytes at a time. Benchmarking shows comparing 8 bytes at a + // * time is no slower than comparing 4 bytes at a time even on 32-bit. + // * On the other hand, it is substantially faster on 64-bit. + // */ + // for (int i = 0; i < minWords * Longs.BYTES; i += Longs.BYTES) { + // long lw = theUnsafe.getLong(left, BYTE_ARRAY_BASE_OFFSET + (long) i); + // long rw = theUnsafe.getLong(right, BYTE_ARRAY_BASE_OFFSET + (long) i); + // long diff = lw ^ rw; + + // if (diff != 0) { + // if (!littleEndian) { + // return UnsignedLongs.compare(lw, rw); + // } + + // // Use binary search + // int n = 0; + // int y; + // int x = (int) diff; + // if (x == 0) { + // x = (int) (diff >>> 32); + // n = 32; + // } + + // y = x << 16; + // if (y == 0) { + // n += 16; + // } else { + // x = y; + // } + + // y = x << 8; + // if (y == 0) { + // n += 8; + // } + // return (int) (((lw >>> n) & 0xFFL) - ((rw >>> n) & 0xFFL)); + // } + // } + + // // The epilogue to cover the last (minLength % 8) elements. + // for (int i = minWords * Longs.BYTES; i < minLength; i++) { + // int result = UnsignedBytes.compare(left[i], right[i]); + // if (result != 0) { + // return result; + // } + // } + // return left.length - right.length; + // } + // } + + // END android-changed enum PureJavaComparator implements Comparator<byte[]> { INSTANCE; @@ -432,22 +346,28 @@ public final class UnsignedBytes { } } - /** - * Returns the Unsafe-using Comparator, or falls back to the pure-Java - * implementation if unable to do so. - */ - static Comparator<byte[]> getBestComparator() { - try { - Class<?> theClass = Class.forName(UNSAFE_COMPARATOR_NAME); - - // yes, UnsafeComparator does implement Comparator<byte[]> - @SuppressWarnings("unchecked") - Comparator<byte[]> comparator = - (Comparator<byte[]>) theClass.getEnumConstants()[0]; - return comparator; - } catch (Throwable t) { // ensure we really catch *everything* - return lexicographicalComparatorJavaImpl(); - } - } + // BEGIN android-changed + + // /** + // * Returns the Unsafe-using Comparator, or falls back to the pure-Java + // * implementation if unable to do so. + // */ + // static Comparator<byte[]> getBestComparator() { + // try { + // Class<?> theClass = Class.forName(UNSAFE_COMPARATOR_NAME); + + // // yes, UnsafeComparator does implement Comparator<byte[]> + // @SuppressWarnings("unchecked") + // Comparator<byte[]> comparator = + // (Comparator<byte[]>) theClass.getEnumConstants()[0]; + // return comparator; + // } catch (Throwable t) { // ensure we really catch *everything* + // return lexicographicalComparatorJavaImpl(); + // } + // } + + // END android-changed + } } + |