Merge -r 1441474:1441475 from trunk to branch-2. Fixes: HADOOP-9124. SortedMapWritable violates contract of Map interface for equals() and hashCode(). Contributed by Surenkumar Nihalani
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1441476 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
3946c10b13
commit
a4abf4f573
|
@ -274,6 +274,9 @@ Release 2.0.3-alpha - Unreleased
|
||||||
|
|
||||||
HADOOP-8981. TestMetricsSystemImpl fails on Windows. (Xuan Gong via suresh)
|
HADOOP-8981. TestMetricsSystemImpl fails on Windows. (Xuan Gong via suresh)
|
||||||
|
|
||||||
|
HADOOP-9124. SortedMapWritable violates contract of Map interface for
|
||||||
|
equals() and hashCode(). (Surenkumar Nihalani via tomwhite)
|
||||||
|
|
||||||
Release 2.0.2-alpha - 2012-09-07
|
Release 2.0.2-alpha - 2012-09-07
|
||||||
|
|
||||||
INCOMPATIBLE CHANGES
|
INCOMPATIBLE CHANGES
|
||||||
|
|
|
@ -203,4 +203,27 @@ public class SortedMapWritable extends AbstractMapWritable
|
||||||
e.getValue().write(out);
|
e.getValue().write(out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj instanceof SortedMapWritable) {
|
||||||
|
Map map = (Map) obj;
|
||||||
|
if (size() != map.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return entrySet().equals(map.entrySet());
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return instance.hashCode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,15 +17,20 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.hadoop.io;
|
package org.apache.hadoop.io;
|
||||||
|
|
||||||
import java.util.Map;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import java.util.Map;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests SortedMapWritable
|
* Tests SortedMapWritable
|
||||||
*/
|
*/
|
||||||
public class TestSortedMapWritable extends TestCase {
|
public class TestSortedMapWritable {
|
||||||
/** the test */
|
/** the test */
|
||||||
|
@Test
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void testSortedMapWritable() {
|
public void testSortedMapWritable() {
|
||||||
Text[] keys = {
|
Text[] keys = {
|
||||||
|
@ -90,6 +95,7 @@ public class TestSortedMapWritable extends TestCase {
|
||||||
/**
|
/**
|
||||||
* Test that number of "unknown" classes is propagated across multiple copies.
|
* Test that number of "unknown" classes is propagated across multiple copies.
|
||||||
*/
|
*/
|
||||||
|
@Test
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public void testForeignClass() {
|
public void testForeignClass() {
|
||||||
SortedMapWritable inMap = new SortedMapWritable();
|
SortedMapWritable inMap = new SortedMapWritable();
|
||||||
|
@ -99,4 +105,63 @@ public class TestSortedMapWritable extends TestCase {
|
||||||
SortedMapWritable copyOfCopy = new SortedMapWritable(outMap);
|
SortedMapWritable copyOfCopy = new SortedMapWritable(outMap);
|
||||||
assertEquals(1, copyOfCopy.getNewClasses());
|
assertEquals(1, copyOfCopy.getNewClasses());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests if equal and hashCode method still hold the contract.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testEqualsAndHashCode() {
|
||||||
|
String failureReason;
|
||||||
|
SortedMapWritable mapA = new SortedMapWritable();
|
||||||
|
SortedMapWritable mapB = new SortedMapWritable();
|
||||||
|
|
||||||
|
// Sanity checks
|
||||||
|
failureReason = "SortedMapWritable couldn't be initialized. Got null reference";
|
||||||
|
assertNotNull(failureReason, mapA);
|
||||||
|
assertNotNull(failureReason, mapB);
|
||||||
|
|
||||||
|
// Basic null check
|
||||||
|
assertFalse("equals method returns true when passed null", mapA.equals(null));
|
||||||
|
|
||||||
|
// When entry set is empty, they should be equal
|
||||||
|
assertTrue("Two empty SortedMapWritables are no longer equal", mapA.equals(mapB));
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
Text[] keys = {
|
||||||
|
new Text("key1"),
|
||||||
|
new Text("key2")
|
||||||
|
};
|
||||||
|
|
||||||
|
BytesWritable[] values = {
|
||||||
|
new BytesWritable("value1".getBytes()),
|
||||||
|
new BytesWritable("value2".getBytes())
|
||||||
|
};
|
||||||
|
|
||||||
|
mapA.put(keys[0], values[0]);
|
||||||
|
mapB.put(keys[1], values[1]);
|
||||||
|
|
||||||
|
// entrySets are different
|
||||||
|
failureReason = "Two SortedMapWritables with different data are now equal";
|
||||||
|
assertTrue(failureReason, mapA.hashCode() != mapB.hashCode());
|
||||||
|
assertTrue(failureReason, !mapA.equals(mapB));
|
||||||
|
assertTrue(failureReason, !mapB.equals(mapA));
|
||||||
|
|
||||||
|
mapA.put(keys[1], values[1]);
|
||||||
|
mapB.put(keys[0], values[0]);
|
||||||
|
|
||||||
|
// entrySets are now same
|
||||||
|
failureReason = "Two SortedMapWritables with same entry sets formed in different order are now different";
|
||||||
|
assertEquals(failureReason, mapA.hashCode(), mapB.hashCode());
|
||||||
|
assertTrue(failureReason, mapA.equals(mapB));
|
||||||
|
assertTrue(failureReason, mapB.equals(mapA));
|
||||||
|
|
||||||
|
// Let's check if entry sets of same keys but different values
|
||||||
|
mapA.put(keys[0], values[1]);
|
||||||
|
mapA.put(keys[1], values[0]);
|
||||||
|
|
||||||
|
failureReason = "Two SortedMapWritables with different content are now equal";
|
||||||
|
assertTrue(failureReason, mapA.hashCode() != mapB.hashCode());
|
||||||
|
assertTrue(failureReason, !mapA.equals(mapB));
|
||||||
|
assertTrue(failureReason, !mapB.equals(mapA));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue