blob: 559df339d939d48f80394d2be023b32152a7e0a8 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.thrift;
import java.io.Serializable;
import java.nio.ByteBuffer;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Collection;
public final class TBaseHelper {
private TBaseHelper(){}
private static final Comparator comparator = new NestedStructureComparator();
public static int compareTo(Object o1, Object o2) {
if (o1 instanceof Comparable) {
return compareTo((Comparable)o1, (Comparable)o2);
} else if (o1 instanceof List) {
return compareTo((List)o1, (List)o2);
} else if (o1 instanceof Set) {
return compareTo((Set)o1, (Set)o2);
} else if (o1 instanceof Map) {
return compareTo((Map)o1, (Map)o2);
} else if (o1 instanceof byte[]) {
return compareTo((byte[])o1, (byte[])o2);
} else {
throw new IllegalArgumentException("Cannot compare objects of type " + o1.getClass());
}
}
public static int compareTo(boolean a, boolean b) {
return Boolean.valueOf(a).compareTo(b);
}
public static int compareTo(byte a, byte b) {
if (a < b) {
return -1;
} else if (b < a) {
return 1;
} else {
return 0;
}
}
public static int compareTo(short a, short b) {
if (a < b) {
return -1;
} else if (b < a) {
return 1;
} else {
return 0;
}
}
public static int compareTo(int a, int b) {
if (a < b) {
return -1;
} else if (b < a) {
return 1;
} else {
return 0;
}
}
public static int compareTo(long a, long b) {
if (a < b) {
return -1;
} else if (b < a) {
return 1;
} else {
return 0;
}
}
public static int compareTo(double a, double b) {
if (a < b) {
return -1;
} else if (b < a) {
return 1;
} else {
return 0;
}
}
public static int compareTo(String a, String b) {
return a.compareTo(b);
}
public static int compareTo(byte[] a, byte[] b) {
int sizeCompare = compareTo(a.length, b.length);
if (sizeCompare != 0) {
return sizeCompare;
}
for (int i = 0; i < a.length; i++) {
int byteCompare = compareTo(a[i], b[i]);
if (byteCompare != 0) {
return byteCompare;
}
}
return 0;
}
public static int compareTo(Comparable a, Comparable b) {
return a.compareTo(b);
}
public static int compareTo(List a, List b) {
int lastComparison = compareTo(a.size(), b.size());
if (lastComparison != 0) {
return lastComparison;
}
for (int i = 0; i < a.size(); i++) {
lastComparison = comparator.compare(a.get(i), b.get(i));
if (lastComparison != 0) {
return lastComparison;
}
}
return 0;
}
public static int compareTo(Set a, Set b) {
int lastComparison = compareTo(a.size(), b.size());
if (lastComparison != 0) {
return lastComparison;
}
SortedSet sortedA = new TreeSet(comparator);
sortedA.addAll(a);
SortedSet sortedB = new TreeSet(comparator);
sortedB.addAll(b);
Iterator iterA = sortedA.iterator();
Iterator iterB = sortedB.iterator();
// Compare each item.
while (iterA.hasNext() && iterB.hasNext()) {
lastComparison = comparator.compare(iterA.next(), iterB.next());
if (lastComparison != 0) {
return lastComparison;
}
}
return 0;
}
public static int compareTo(Map a, Map b) {
int lastComparison = compareTo(a.size(), b.size());
if (lastComparison != 0) {
return lastComparison;
}
// Sort a and b so we can compare them.
SortedMap sortedA = new TreeMap(comparator);
sortedA.putAll(a);
Iterator<Map.Entry> iterA = sortedA.entrySet().iterator();
SortedMap sortedB = new TreeMap(comparator);
sortedB.putAll(b);
Iterator<Map.Entry> iterB = sortedB.entrySet().iterator();
// Compare each item.
while (iterA.hasNext() && iterB.hasNext()) {
Map.Entry entryA = iterA.next();
Map.Entry entryB = iterB.next();
lastComparison = comparator.compare(entryA.getKey(), entryB.getKey());
if (lastComparison != 0) {
return lastComparison;
}
lastComparison = comparator.compare(entryA.getValue(), entryB.getValue());
if (lastComparison != 0) {
return lastComparison;
}
}
return 0;
}
/**
* Comparator to compare items inside a structure (e.g. a list, set, or map).
*/
private static class NestedStructureComparator implements Comparator, Serializable {
public int compare(Object oA, Object oB) {
if (oA == null && oB == null) {
return 0;
} else if (oA == null) {
return -1;
} else if (oB == null) {
return 1;
} else if (oA instanceof List) {
return compareTo((List)oA, (List)oB);
} else if (oA instanceof Set) {
return compareTo((Set)oA, (Set)oB);
} else if (oA instanceof Map) {
return compareTo((Map)oA, (Map)oB);
} else if (oA instanceof byte[]) {
return compareTo((byte[])oA, (byte[])oB);
} else {
return compareTo((Comparable)oA, (Comparable)oB);
}
}
}
public static void toString(Collection<ByteBuffer> bbs, StringBuilder sb) {
Iterator<ByteBuffer> it = bbs.iterator();
if (!it.hasNext()) {
sb.append("[]");
} else {
sb.append("[");
while (true) {
ByteBuffer bb = it.next();
org.apache.thrift.TBaseHelper.toString(bb, sb);
if (!it.hasNext()) {
sb.append("]");
return;
} else {
sb.append(", ");
}
}
}
}
public static void toString(ByteBuffer bb, StringBuilder sb) {
byte[] buf = bb.array();
int arrayOffset = bb.arrayOffset();
int offset = arrayOffset + bb.position();
int origLimit = arrayOffset + bb.limit();
int limit = (origLimit - offset > 128) ? offset + 128 : origLimit;
for (int i = offset; i < limit; i++) {
if (i > offset) {
sb.append(" ");
}
sb.append(paddedByteString(buf[i]));
}
if (origLimit != limit) {
sb.append("...");
}
}
public static String paddedByteString(byte b) {
int extended = (b | 0x100) & 0x1ff;
return Integer.toHexString(extended).toUpperCase().substring(1);
}
public static byte[] byteBufferToByteArray(ByteBuffer byteBuffer) {
if (wrapsFullArray(byteBuffer)) {
return byteBuffer.array();
}
byte[] target = new byte[byteBuffer.remaining()];
byteBufferToByteArray(byteBuffer, target, 0);
return target;
}
public static boolean wrapsFullArray(ByteBuffer byteBuffer) {
return byteBuffer.hasArray()
&& byteBuffer.position() == 0
&& byteBuffer.arrayOffset() == 0
&& byteBuffer.remaining() == byteBuffer.capacity();
}
public static int byteBufferToByteArray(ByteBuffer byteBuffer, byte[] target, int offset) {
int remaining = byteBuffer.remaining();
System.arraycopy(byteBuffer.array(),
byteBuffer.arrayOffset() + byteBuffer.position(),
target,
offset,
remaining);
return remaining;
}
public static ByteBuffer rightSize(ByteBuffer in) {
if (in == null) {
return null;
}
if (wrapsFullArray(in)) {
return in;
}
return ByteBuffer.wrap(byteBufferToByteArray(in));
}
public static ByteBuffer copyBinary(final ByteBuffer orig) {
if (orig == null) {
return null;
}
ByteBuffer copy = ByteBuffer.wrap(new byte[orig.remaining()]);
if (orig.hasArray()) {
System.arraycopy(orig.array(), orig.arrayOffset() + orig.position(), copy.array(), 0, orig.remaining());
} else {
orig.slice().get(copy.array());
}
return copy;
}
public static byte[] copyBinary(final byte[] orig) {
if (orig == null) {
return null;
}
byte[] copy = new byte[orig.length];
System.arraycopy(orig, 0, copy, 0, orig.length);
return copy;
}
public static int hashCode(long value) {
int low = (int) value;
int high = (int) (value >>> 32);
return high * 127 + low;
}
public static int hashCode(double value) {
return hashCode(Double.doubleToRawLongBits(value));
}
}