diff options
author | Brian S. O'Neill <bronee@gmail.com> | 2008-05-14 23:46:11 +0000 |
---|---|---|
committer | Brian S. O'Neill <bronee@gmail.com> | 2008-05-14 23:46:11 +0000 |
commit | 2dc31dcd188d031a6704a613decee88b074aad8f (patch) | |
tree | f5c05c6d6eaa7dee7c063b7980612013a8e950f6 /src/main/java/com/amazon/carbonado/util | |
parent | 0c32c3144d64c217c1065326a8990b75234c5c5f (diff) |
Moved utility comparators to util package.
Diffstat (limited to 'src/main/java/com/amazon/carbonado/util')
-rw-r--r-- | src/main/java/com/amazon/carbonado/util/Comparators.java | 315 |
1 files changed, 315 insertions, 0 deletions
diff --git a/src/main/java/com/amazon/carbonado/util/Comparators.java b/src/main/java/com/amazon/carbonado/util/Comparators.java new file mode 100644 index 0000000..c3ba418 --- /dev/null +++ b/src/main/java/com/amazon/carbonado/util/Comparators.java @@ -0,0 +1,315 @@ +/*
+ * Copyright 2007 Amazon Technologies, Inc. or its affiliates.
+ * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks
+ * of Amazon Technologies, Inc. or its affiliates. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.amazon.carbonado.util;
+
+import java.util.Comparator;
+
+import org.cojen.classfile.TypeDesc;
+
+/**
+ * Collection of utility comparators.
+ *
+ * @author Brian S O'Neill
+ */
+public class Comparators {
+ /**
+ * Returns a comparator which can sort single or multi-dimensional arrays
+ * of primitves or Comparables.
+ *
+ * @param unsigned applicable only to arrays of bytes, shorts, ints, or longs
+ * @return null if unsupported
+ */
+ public static <T> Comparator<T> arrayComparator(Class<T> arrayType, boolean unsigned) {
+ if (!arrayType.isArray()) {
+ throw new IllegalArgumentException();
+ }
+
+ Comparator c;
+
+ TypeDesc componentType = TypeDesc.forClass(arrayType.getComponentType());
+ switch (componentType.getTypeCode()) {
+ case TypeDesc.BYTE_CODE:
+ c = unsigned ? UnsignedByteArray : SignedByteArray;
+ break;
+ case TypeDesc.SHORT_CODE:
+ c = unsigned ? UnsignedShortArray : SignedShortArray;
+ break;
+ case TypeDesc.INT_CODE:
+ c = unsigned ? UnsignedIntArray : SignedIntArray;
+ break;
+ case TypeDesc.LONG_CODE:
+ c = unsigned ? UnsignedLongArray : SignedLongArray;
+ break;
+ case TypeDesc.BOOLEAN_CODE:
+ c = BooleanArray;
+ break;
+ case TypeDesc.CHAR_CODE:
+ c = CharArray;
+ break;
+ case TypeDesc.FLOAT_CODE:
+ c = FloatArray;
+ break;
+ case TypeDesc.DOUBLE_CODE:
+ c = DoubleArray;
+ break;
+ case TypeDesc.OBJECT_CODE: default:
+ if (componentType.isArray()) {
+ c = new ComparatorArray(arrayComparator(componentType.toClass(), unsigned));
+ } else if (Comparable.class.isAssignableFrom(componentType.toClass())) {
+ c = ComparableArray;
+ } else {
+ c = null;
+ }
+ break;
+ }
+
+ return (Comparator<T>) c;
+ }
+
+ private static final Comparator<byte[]> SignedByteArray = new Comparator<byte[]>() {
+ public int compare(byte[] a, byte[] b) {
+ int len = Math.min(a.length, b.length);
+ for (int i=0; i<len; i++) {
+ byte ai = a[i];
+ byte bi = b[i];
+ if (ai != bi) {
+ return ai - bi;
+ }
+ }
+ return a.length - b.length;
+ }
+ };
+
+ private static final Comparator<byte[]> UnsignedByteArray = new Comparator<byte[]>() {
+ public int compare(byte[] a, byte[] b) {
+ int len = Math.min(a.length, b.length);
+ for (int i=0; i<len; i++) {
+ byte ai = a[i];
+ byte bi = b[i];
+ if (ai != bi) {
+ return (ai & 0xff) - (bi & 0xff);
+ }
+ }
+ return a.length - b.length;
+ }
+ };
+
+ private static final Comparator<short[]> SignedShortArray = new Comparator<short[]>() {
+ public int compare(short[] a, short[] b) {
+ int len = Math.min(a.length, b.length);
+ for (int i=0; i<len; i++) {
+ short ai = a[i];
+ short bi = b[i];
+ if (ai != bi) {
+ return ai - bi;
+ }
+ }
+ return a.length - b.length;
+ }
+ };
+
+ private static final Comparator<short[]> UnsignedShortArray = new Comparator<short[]>() {
+ public int compare(short[] a, short[] b) {
+ int len = Math.min(a.length, b.length);
+ for (int i=0; i<len; i++) {
+ short ai = a[i];
+ short bi = b[i];
+ if (ai != bi) {
+ return (ai & 0xffff) - (bi & 0xffff);
+ }
+ }
+ return a.length - b.length;
+ }
+ };
+
+ private static final Comparator<int[]> SignedIntArray = new Comparator<int[]>() {
+ public int compare(int[] a, int[] b) {
+ int len = Math.min(a.length, b.length);
+ for (int i=0; i<len; i++) {
+ int ai = a[i];
+ int bi = b[i];
+ if (ai != bi) {
+ return ai < bi ? -1 : 1;
+ }
+ }
+ return a.length - b.length;
+ }
+ };
+
+ private static final Comparator<int[]> UnsignedIntArray = new Comparator<int[]>() {
+ public int compare(int[] a, int[] b) {
+ int len = Math.min(a.length, b.length);
+ for (int i=0; i<len; i++) {
+ int ai = a[i];
+ int bi = b[i];
+ if (ai != bi) {
+ return (ai & 0xffffffffL) < (bi & 0xffffffffL) ? -1 : 1;
+ }
+ }
+ return a.length - b.length;
+ }
+ };
+
+ private static final Comparator<long[]> SignedLongArray = new Comparator<long[]>() {
+ public int compare(long[] a, long[] b) {
+ int len = Math.min(a.length, b.length);
+ for (int i=0; i<len; i++) {
+ long ai = a[i];
+ long bi = b[i];
+ if (ai != bi) {
+ return ai < bi ? -1 : 1;
+ }
+ }
+ return a.length - b.length;
+ }
+ };
+
+ private static final Comparator<long[]> UnsignedLongArray = new Comparator<long[]>() {
+ public int compare(long[] a, long[] b) {
+ int len = Math.min(a.length, b.length);
+ for (int i=0; i<len; i++) {
+ long ai = a[i];
+ long bi = b[i];
+ if (ai != bi) {
+ long sai = ai >>> 1;
+ long sbi = bi >>> 1;
+ if (sai < sbi) {
+ return -1;
+ }
+ if (sai > sbi) {
+ return 1;
+ }
+ return (ai & 1) == 0 ? -1 : 1;
+ }
+ }
+ return a.length - b.length;
+ }
+ };
+
+ private static final Comparator<boolean[]> BooleanArray = new Comparator<boolean[]>() {
+ public int compare(boolean[] a, boolean[] b) {
+ int len = Math.min(a.length, b.length);
+ for (int i=0; i<len; i++) {
+ boolean ai = a[i];
+ boolean bi = b[i];
+ if (ai != bi) {
+ return ai ? 1 : -1;
+ }
+ }
+ return a.length - b.length;
+ }
+ };
+
+ private static final Comparator<char[]> CharArray = new Comparator<char[]>() {
+ public int compare(char[] a, char[] b) {
+ int len = Math.min(a.length, b.length);
+ for (int i=0; i<len; i++) {
+ char ai = a[i];
+ char bi = b[i];
+ if (ai != bi) {
+ return ai - bi;
+ }
+ }
+ return a.length - b.length;
+ }
+ };
+
+ private static final Comparator<float[]> FloatArray = new Comparator<float[]>() {
+ public int compare(float[] a, float[] b) {
+ int len = Math.min(a.length, b.length);
+ for (int i=0; i<len; i++) {
+ float ai = a[i];
+ float bi = b[i];
+ if (ai != bi) {
+ return Float.compare(ai, bi);
+ }
+ }
+ return a.length - b.length;
+ }
+ };
+
+ private static final Comparator<double[]> DoubleArray = new Comparator<double[]>() {
+ public int compare(double[] a, double[] b) {
+ int len = Math.min(a.length, b.length);
+ for (int i=0; i<len; i++) {
+ double ai = a[i];
+ double bi = b[i];
+ if (ai != bi) {
+ return Double.compare(ai, bi);
+ }
+ }
+ return a.length - b.length;
+ }
+ };
+
+ private static final Comparator<Comparable[]> ComparableArray = new Comparator<Comparable[]>()
+ {
+ public int compare(Comparable[] a, Comparable[] b) {
+ int len = Math.min(a.length, b.length);
+ for (int i=0; i<len; i++) {
+ Comparable ai = a[i];
+ Comparable bi = b[i];
+ if (ai == bi) {
+ continue;
+ }
+ if (ai == null) {
+ return 1;
+ }
+ if (bi == null) {
+ return -1;
+ }
+ int compare = ai.compareTo(bi);
+ if (compare != 0) {
+ return compare;
+ }
+ }
+ return a.length - b.length;
+ }
+ };
+
+ private static class ComparatorArray implements Comparator<Object[]> {
+ private final Comparator<Object> mComparator;
+
+ ComparatorArray(Comparator<Object> comparator) {
+ mComparator = comparator;
+ }
+
+ public int compare(Object[] a, Object[] b) {
+ int len = Math.min(a.length, b.length);
+ for (int i=0; i<len; i++) {
+ Object ai = a[i];
+ Object bi = b[i];
+ if (ai == bi) {
+ continue;
+ }
+ if (ai == null) {
+ return 1;
+ }
+ if (bi == null) {
+ return -1;
+ }
+ int compare = mComparator.compare(ai, bi);
+ if (compare != 0) {
+ return compare;
+ }
+ }
+ return a.length - b.length;
+ }
+ }
+}
|