/**
* Copyright [2011] [Datasalt Systems S.L.]
*
* 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.datasalt.utils.io;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.io.WritableComparator;
import org.apache.hadoop.io.WritableUtils;
import org.apache.hadoop.mapreduce.Partitioner;
@SuppressWarnings({ "rawtypes" })
public class TextLongWritable implements WritableComparable<TextLongWritable>{
private Text thisText;
private long thisLong;
public TextLongWritable() {
thisText = new Text();
}
public TextLongWritable(String first, long second) {
this();
this.thisText.set(first);
this.thisLong = second;
}
public void readFields(DataInput input) throws IOException {
thisText.readFields(input);
this.thisLong = input.readLong();
}
public void write(DataOutput output) throws IOException {
thisText.write(output);
output.writeLong(thisLong);
}
public int compareTo(TextLongWritable that){
int firstComparison = this.thisText.compareTo(((TextLongWritable)that).getText());
if(firstComparison != 0){
return firstComparison;
} else {
long thisValue = this.thisLong;
long thatValue = that.getLong();
return (thisValue<thatValue ? -1 : (thisValue==thatValue ? 0 : 1));
}
}
public static class Comparator extends WritableComparator {
public Comparator() {
super(TextLongWritable.class);
}
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
int comparison;
int length1, length2;
try {
length1 = readVInt(b1, s1);
length2 = readVInt(b2, s2);
comparison = compareBytes(b1,
s1 + WritableUtils.decodeVIntSize(b1[s1]), length1, b2, s2
+ WritableUtils.decodeVIntSize(b2[s2]), length2);
if (comparison != 0) {
return comparison;
} else {
long thisValue = readLong(b1, s1 + l1 - Long.SIZE / 8);
long thatValue = readLong(b2, s2 + l2 - Long.SIZE / 8);
int returnV = (thisValue < thatValue ? -1
: (thisValue == thatValue ? 0 : 1));
return returnV;
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
public static class TextElementComparator extends WritableComparator {
public TextElementComparator() {
super(TextLongWritable.class);
}
public int compare(WritableComparable a , WritableComparable b){
return ((TextLongWritable)a).thisText.compareTo(((TextLongWritable)b).getText());
}
public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {
try {
int length1 = readVInt(b1, s1); // text length coded in binary
int length2 = readVInt(b2, s2);
int textOffset1 = WritableUtils.decodeVIntSize(b1[s1]);
int textOffset2 = WritableUtils.decodeVIntSize(b2[s2]);
return compareBytes(b1, s1 + textOffset1, length1, b2,
s2 + textOffset2, length2);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
public static class TextHashPartitioner extends Partitioner<TextLongWritable,Object> {
public int getPartition(TextLongWritable key, Object value, int numReduceTasks) {
return (key.getText().toString().hashCode() & Integer.MAX_VALUE) % numReduceTasks;
}
}
static { // register this comparator
WritableComparator.define(TextLongWritable.class, new Comparator());
}
public String toString(){
StringBuilder builder = new StringBuilder();
builder.append("{").append(thisText).append(",").append(thisLong).append("}");
return builder.toString();
}
public Text getText(){
return thisText;
}
public void setText(String first){
this.thisText.set(first);
}
public long getLong(){
return thisLong;
}
public void setLong(long second){
this.thisLong = second;
}
}