001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.io; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertFalse; 022import static org.junit.Assert.assertNotSame; 023 024import java.io.ByteArrayOutputStream; 025import java.io.DataOutputStream; 026import java.io.IOException; 027import org.apache.hadoop.hbase.HBaseClassTestRule; 028import org.apache.hadoop.hbase.testclassification.IOTests; 029import org.apache.hadoop.hbase.testclassification.SmallTests; 030import org.apache.hadoop.hbase.util.Bytes; 031import org.junit.ClassRule; 032import org.junit.Test; 033import org.junit.experimental.categories.Category; 034 035@Category({ IOTests.class, SmallTests.class }) 036public class TestImmutableBytesWritable { 037 038 @ClassRule 039 public static final HBaseClassTestRule CLASS_RULE = 040 HBaseClassTestRule.forClass(TestImmutableBytesWritable.class); 041 042 @Test 043 public void testHash() throws Exception { 044 assertEquals(new ImmutableBytesWritable(Bytes.toBytes("xxabc"), 2, 3).hashCode(), 045 new ImmutableBytesWritable(Bytes.toBytes("abc")).hashCode()); 046 assertEquals(new ImmutableBytesWritable(Bytes.toBytes("xxabcd"), 2, 3).hashCode(), 047 new ImmutableBytesWritable(Bytes.toBytes("abc")).hashCode()); 048 assertNotSame(new ImmutableBytesWritable(Bytes.toBytes("xxabc"), 2, 3).hashCode(), 049 new ImmutableBytesWritable(Bytes.toBytes("xxabc"), 2, 2).hashCode()); 050 } 051 052 @Test 053 public void testSpecificCompare() { 054 ImmutableBytesWritable ibw1 = new ImmutableBytesWritable(new byte[] { 0x0f }); 055 ImmutableBytesWritable ibw2 = new ImmutableBytesWritable(new byte[] { 0x00, 0x00 }); 056 ImmutableBytesWritable.Comparator c = new ImmutableBytesWritable.Comparator(); 057 assertFalse("ibw1 < ibw2", c.compare(ibw1, ibw2) < 0); 058 } 059 060 @Test 061 public void testComparison() throws Exception { 062 runTests("aa", "b", -1); 063 runTests("aa", "aa", 0); 064 runTests("aa", "ab", -1); 065 runTests("aa", "aaa", -1); 066 runTests("", "", 0); 067 runTests("", "a", -1); 068 } 069 070 private void runTests(String aStr, String bStr, int signum) throws Exception { 071 ImmutableBytesWritable a = new ImmutableBytesWritable(Bytes.toBytes(aStr)); 072 ImmutableBytesWritable b = new ImmutableBytesWritable(Bytes.toBytes(bStr)); 073 074 doComparisonsOnObjects(a, b, signum); 075 doComparisonsOnRaw(a, b, signum); 076 077 // Tests for when the offset is non-zero 078 a = new ImmutableBytesWritable(Bytes.toBytes("xxx" + aStr), 3, aStr.length()); 079 b = new ImmutableBytesWritable(Bytes.toBytes("yy" + bStr), 2, bStr.length()); 080 doComparisonsOnObjects(a, b, signum); 081 doComparisonsOnRaw(a, b, signum); 082 083 // Tests for when offset is nonzero and length doesn't extend to end 084 a = new ImmutableBytesWritable(Bytes.toBytes("xxx" + aStr + "zzz"), 3, aStr.length()); 085 b = new ImmutableBytesWritable(Bytes.toBytes("yy" + bStr + "aaa"), 2, bStr.length()); 086 doComparisonsOnObjects(a, b, signum); 087 doComparisonsOnRaw(a, b, signum); 088 } 089 090 private int signum(int i) { 091 if (i > 0) return 1; 092 if (i == 0) return 0; 093 return -1; 094 } 095 096 private void doComparisonsOnRaw(ImmutableBytesWritable a, ImmutableBytesWritable b, 097 int expectedSignum) throws IOException { 098 ImmutableBytesWritable.Comparator comparator = new ImmutableBytesWritable.Comparator(); 099 100 ByteArrayOutputStream baosA = new ByteArrayOutputStream(); 101 ByteArrayOutputStream baosB = new ByteArrayOutputStream(); 102 103 a.write(new DataOutputStream(baosA)); 104 b.write(new DataOutputStream(baosB)); 105 106 assertEquals("Comparing " + a + " and " + b + " as raw", signum(comparator 107 .compare(baosA.toByteArray(), 0, baosA.size(), baosB.toByteArray(), 0, baosB.size())), 108 expectedSignum); 109 110 assertEquals( 111 "Comparing " + a + " and " + b + " as raw (inverse)", -signum(comparator 112 .compare(baosB.toByteArray(), 0, baosB.size(), baosA.toByteArray(), 0, baosA.size())), 113 expectedSignum); 114 } 115 116 private void doComparisonsOnObjects(ImmutableBytesWritable a, ImmutableBytesWritable b, 117 int expectedSignum) { 118 ImmutableBytesWritable.Comparator comparator = new ImmutableBytesWritable.Comparator(); 119 assertEquals("Comparing " + a + " and " + b + " as objects", signum(comparator.compare(a, b)), 120 expectedSignum); 121 assertEquals("Comparing " + a + " and " + b + " as objects (inverse)", 122 -signum(comparator.compare(b, a)), expectedSignum); 123 } 124 125}