com.aliyun.odps.io.BytesWritable Maven / Gradle / Ivy
Show all versions of odps-sdk-commons Show documentation
/**
* 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 com.aliyun.odps.io;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
/**
* BytesWritable 提供了 byte[] 的 {@link Writable} 和 {@link WritableComparable} 的实现.
*/
public class BytesWritable extends BinaryComparable implements
WritableComparable {
private static final int LENGTH_BYTES = 4;
private static final byte[] EMPTY_BYTES = {};
private int size;
private byte[] bytes;
/**
* 默认构造 空 byte[] 的 BytesWritable.
*/
public BytesWritable() {
this(EMPTY_BYTES);
}
/**
* 构造值为给定 byte 数组的 BytesWritable.
*
* @param bytes
*/
public BytesWritable(byte[] bytes) {
this.bytes = bytes;
this.size = bytes.length;
}
/**
* 返回此 byte 数组的内容
*
* @return 此 byte 数组的内容,数据只有在 bytes[0, getLength() - 1]直接有效
*/
public byte[] getBytes() {
return bytes;
}
/**
* 返回内容长度.
*/
public int getLength() {
return size;
}
/**
* 更改数组内容长度.
*
*
* 注意:更改后,有效数据内容只由bytes[0, 更改前 getLength() -1], 新增加的数组内容是未定义的,数组的容量按需增加。
*
* @param size
* 新内容长度
*/
public void setSize(int size) {
if (size > getCapacity()) {
setCapacity(size * 3 / 2);
}
this.size = size;
}
/**
* 获取字节数组容量.
*
* @return 字节数组容量,即:bytes.length.
*/
public int getCapacity() {
return bytes.length;
}
/**
* 更该字节数组容量
*
* @param new_cap
* 新容量大小
*/
public void setCapacity(int new_cap) {
if (new_cap != getCapacity()) {
byte[] new_data = new byte[new_cap];
if (new_cap < size) {
size = new_cap;
}
if (size != 0) {
System.arraycopy(bytes, 0, new_data, 0, size);
}
bytes = new_data;
}
}
/**
* 更新数据内容为给定 BytesWritable 的数据.
*
*
* 等价于:set(newData.getBytes(), 0, newData.getLength())
*
* @param newData
* 新数据
*/
public void set(BytesWritable newData) {
set(newData.bytes, 0, newData.size);
}
/**
* 更新数据内容为给定字节数组中的数据.
*
* @param newData
* 源数组
* @param offset
* 数据内容在 newData 中的偏移量
* @param length
* 数据内容长度
*/
public void set(byte[] newData, int offset, int length) {
setSize(0);
setSize(length);
System.arraycopy(newData, offset, bytes, 0, size);
}
@Override
public void readFields(DataInput in) throws IOException {
setSize(0); // clear the old data
setSize(in.readInt());
in.readFully(bytes, 0, size);
}
@Override
public void write(DataOutput out) throws IOException {
out.writeInt(size);
out.write(bytes, 0, size);
}
@Override
public int hashCode() {
return super.hashCode();
}
/**
* 判断两个 BytesWritable 内容是否相同.
*
* @param right_obj
* @return 如果两个都是 BytesWritable 且内容相同,返回true,否则返回false
*/
@Override
public boolean equals(Object right_obj) {
if (right_obj instanceof BytesWritable) {
return super.equals(right_obj);
}
return false;
}
/**
* 输出数据的十六进制内容.
*/
@Override
public String toString() {
StringBuffer sb = new StringBuffer(3 * size);
for (int idx = 0; idx < size; idx++) {
// if not the first, put a blank separator in
if (idx != 0) {
sb.append(' ');
}
String num = Integer.toHexString(0xff & bytes[idx]);
// if it is only one digit, add a leading 0.
if (num.length() < 2) {
sb.append('0');
}
sb.append(num);
}
return sb.toString();
}
/**
* BytesWritable 对象的 {@link WritableComparator} 自然顺序实现(升序).
*/
public static class Comparator extends WritableComparator {
public Comparator() {
super(BytesWritable.class);
}
/**
* 基于二进制内容的 LongWritable 对象比较函数.
*
*
* 直接使用 {@link #compareBytes(byte[], int, int, byte[], int, int)} 进行二进制内容的比较
*/
@Override
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
return compareBytes(b1, s1 + LENGTH_BYTES, l1 - LENGTH_BYTES, b2, s2
+ LENGTH_BYTES,
l2 - LENGTH_BYTES);
}
}
static { // register this comparator
WritableComparator.define(BytesWritable.class, new Comparator());
}
}