diff --git a/hadoop-common/CHANGES.txt b/hadoop-common/CHANGES.txt index 8c739df144..3da778c808 100644 --- a/hadoop-common/CHANGES.txt +++ b/hadoop-common/CHANGES.txt @@ -324,6 +324,8 @@ Trunk (unreleased changes) HADOOP-7531. Add servlet util methods for handling paths in requests. (eli) + HADOOP-7493. Add ShortWritable. (Uma Maheswara Rao G via szetszwo) + OPTIMIZATIONS HADOOP-7333. Performance improvement in PureJavaCrc32. (Eric Caspole diff --git a/hadoop-common/src/main/java/org/apache/hadoop/io/ShortWritable.java b/hadoop-common/src/main/java/org/apache/hadoop/io/ShortWritable.java new file mode 100644 index 0000000000..be09df1801 --- /dev/null +++ b/hadoop-common/src/main/java/org/apache/hadoop/io/ShortWritable.java @@ -0,0 +1,111 @@ +/** + * 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.hadoop.io; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; + +/** A WritableComparable for shorts. */ +@InterfaceAudience.Public +@InterfaceStability.Stable +public class ShortWritable implements WritableComparable { + private short value; + + public ShortWritable() { + } + + public ShortWritable(short value) { + set(value); + } + + /** Set the value of this ShortWritable. */ + public void set(short value) { + this.value = value; + } + + /** Return the value of this ShortWritable. */ + public short get() { + return value; + } + + /** read the short value */ + @Override + public void readFields(DataInput in) throws IOException { + value = in.readShort(); + } + + /** write short value */ + @Override + public void write(DataOutput out) throws IOException { + out.writeShort(value); + } + + /** Returns true iff o is a ShortWritable with the same value. */ + @Override + public boolean equals(Object o) { + if (!(o instanceof ShortWritable)) + return false; + ShortWritable other = (ShortWritable) o; + return this.value == other.value; + } + + /** hash code */ + @Override + public int hashCode() { + return value; + } + + /** Compares two ShortWritable. */ + @Override + public int compareTo(ShortWritable o) { + short thisValue = this.value; + short thatValue = (o).value; + return (thisValue < thatValue ? -1 : (thisValue == thatValue ? 0 : 1)); + } + + /** Short values in string format */ + @Override + public String toString() { + return Short.toString(value); + } + + /** A Comparator optimized for ShortWritable. */ + public static class Comparator extends WritableComparator { + + public Comparator() { + super(ShortWritable.class); + } + + @Override + public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) { + short thisValue = (short) readUnsignedShort(b1, s1); + short thatValue = (short) readUnsignedShort(b2, s2); + return (thisValue < thatValue ? -1 : (thisValue == thatValue ? 0 : 1)); + } + } + + static { // register this comparator + WritableComparator.define(ShortWritable.class, new Comparator()); + } + +} diff --git a/hadoop-common/src/test/java/org/apache/hadoop/io/TestWritable.java b/hadoop-common/src/test/java/org/apache/hadoop/io/TestWritable.java index a60ef1b8d2..31c237f872 100644 --- a/hadoop-common/src/test/java/org/apache/hadoop/io/TestWritable.java +++ b/hadoop-common/src/test/java/org/apache/hadoop/io/TestWritable.java @@ -18,10 +18,11 @@ package org.apache.hadoop.io; -import java.io.*; +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; import java.util.Random; -import org.apache.hadoop.conf.Configurable; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.util.ReflectionUtils; @@ -68,6 +69,10 @@ public class TestWritable extends TestCase { public void testByteWritable() throws Exception { testWritable(new ByteWritable((byte)128)); } + + public void testShortWritable() throws Exception { + testWritable(new ShortWritable((byte)256)); + } public void testDoubleWritable() throws Exception { testWritable(new DoubleWritable(1.0)); @@ -104,13 +109,13 @@ public class TestWritable extends TestCase { } } - private static class Frob implements WritableComparable { + private static class Frob implements WritableComparable { static { // register default comparator WritableComparator.define(Frob.class, new FrobComparator()); } @Override public void write(DataOutput out) throws IOException {} @Override public void readFields(DataInput in) throws IOException {} - @Override public int compareTo(Object o) { return 0; } + @Override public int compareTo(Frob o) { return 0; } } /** Test that comparator is defined. */ @@ -118,5 +123,31 @@ public class TestWritable extends TestCase { assert(WritableComparator.get(Frob.class) instanceof FrobComparator); } + /** + * Test a user comparator that relies on deserializing both arguments for each + * compare. + */ + public void testShortWritableComparator() throws Exception { + ShortWritable writable1 = new ShortWritable((short)256); + ShortWritable writable2 = new ShortWritable((short) 128); + ShortWritable writable3 = new ShortWritable((short) 256); + + final String SHOULD_NOT_MATCH_WITH_RESULT_ONE = "Result should be 1, should not match the writables"; + assertTrue(SHOULD_NOT_MATCH_WITH_RESULT_ONE, + writable1.compareTo(writable2) == 1); + assertTrue(SHOULD_NOT_MATCH_WITH_RESULT_ONE, WritableComparator.get( + ShortWritable.class).compare(writable1, writable2) == 1); + + final String SHOULD_NOT_MATCH_WITH_RESULT_MINUS_ONE = "Result should be -1, should not match the writables"; + assertTrue(SHOULD_NOT_MATCH_WITH_RESULT_MINUS_ONE, writable2 + .compareTo(writable1) == -1); + assertTrue(SHOULD_NOT_MATCH_WITH_RESULT_MINUS_ONE, WritableComparator.get( + ShortWritable.class).compare(writable2, writable1) == -1); + + final String SHOULD_MATCH = "Result should be 0, should match the writables"; + assertTrue(SHOULD_MATCH, writable1.compareTo(writable1) == 0); + assertTrue(SHOULD_MATCH, WritableComparator.get(ShortWritable.class) + .compare(writable1, writable3) == 0); + } }