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 java.io.ByteArrayOutputStream;
021import java.io.DataOutputStream;
022import java.io.IOException;
023import junit.framework.TestCase;
024import org.apache.hadoop.hbase.HBaseClassTestRule;
025import org.apache.hadoop.hbase.testclassification.IOTests;
026import org.apache.hadoop.hbase.testclassification.SmallTests;
027import org.apache.hadoop.hbase.util.Bytes;
028import org.junit.ClassRule;
029import org.junit.experimental.categories.Category;
030
031@Category({IOTests.class, SmallTests.class})
032public class TestImmutableBytesWritable extends TestCase {
033
034  @ClassRule
035  public static final HBaseClassTestRule CLASS_RULE =
036      HBaseClassTestRule.forClass(TestImmutableBytesWritable.class);
037
038  public void testHash() throws Exception {
039    assertEquals(
040      new ImmutableBytesWritable(Bytes.toBytes("xxabc"), 2, 3).hashCode(),
041      new ImmutableBytesWritable(Bytes.toBytes("abc")).hashCode());
042    assertEquals(
043      new ImmutableBytesWritable(Bytes.toBytes("xxabcd"), 2, 3).hashCode(),
044      new ImmutableBytesWritable(Bytes.toBytes("abc")).hashCode());
045    assertNotSame(
046      new ImmutableBytesWritable(Bytes.toBytes("xxabc"), 2, 3).hashCode(),
047      new ImmutableBytesWritable(Bytes.toBytes("xxabc"), 2, 2).hashCode());
048  }
049
050  public void testSpecificCompare() {
051    ImmutableBytesWritable ibw1 = new ImmutableBytesWritable(new byte[]{0x0f});
052    ImmutableBytesWritable ibw2 = new ImmutableBytesWritable(new byte[]{0x00, 0x00});
053    ImmutableBytesWritable.Comparator c = new ImmutableBytesWritable.Comparator();
054    assertFalse("ibw1 < ibw2", c.compare( ibw1, ibw2 ) < 0 );
055  }
056
057  public void testComparison() throws Exception {
058    runTests("aa", "b", -1);
059    runTests("aa", "aa", 0);
060    runTests("aa", "ab", -1);
061    runTests("aa", "aaa", -1);
062    runTests("", "", 0);
063    runTests("", "a", -1);
064  }
065
066  private void runTests(String aStr, String bStr, int signum)
067    throws Exception {
068    ImmutableBytesWritable a = new ImmutableBytesWritable(
069      Bytes.toBytes(aStr));
070    ImmutableBytesWritable b = new ImmutableBytesWritable(
071      Bytes.toBytes(bStr));
072
073    doComparisonsOnObjects(a, b, signum);
074    doComparisonsOnRaw(a, b, signum);
075
076    // Tests for when the offset is non-zero
077    a = new ImmutableBytesWritable(Bytes.toBytes("xxx" + aStr),
078                                   3, aStr.length());
079    b = new ImmutableBytesWritable(Bytes.toBytes("yy" + bStr),
080                                   2, bStr.length());
081    doComparisonsOnObjects(a, b, signum);
082    doComparisonsOnRaw(a, b, signum);
083
084    // Tests for when offset is nonzero and length doesn't extend to end
085    a = new ImmutableBytesWritable(Bytes.toBytes("xxx" + aStr + "zzz"),
086                                   3, aStr.length());
087    b = new ImmutableBytesWritable(Bytes.toBytes("yy" + bStr + "aaa"),
088                                   2, bStr.length());
089    doComparisonsOnObjects(a, b, signum);
090    doComparisonsOnRaw(a, b, signum);
091  }
092
093
094  private int signum(int i) {
095    if (i > 0) return 1;
096    if (i == 0) return 0;
097    return -1;
098  }
099
100  private void doComparisonsOnRaw(ImmutableBytesWritable a,
101                                  ImmutableBytesWritable b,
102                                  int expectedSignum)
103    throws IOException {
104    ImmutableBytesWritable.Comparator comparator =
105      new ImmutableBytesWritable.Comparator();
106
107    ByteArrayOutputStream baosA = new ByteArrayOutputStream();
108    ByteArrayOutputStream baosB = new ByteArrayOutputStream();
109
110    a.write(new DataOutputStream(baosA));
111    b.write(new DataOutputStream(baosB));
112
113    assertEquals(
114      "Comparing " + a + " and " + b + " as raw",
115      signum(comparator.compare(baosA.toByteArray(), 0, baosA.size(),
116                                baosB.toByteArray(), 0, baosB.size())),
117      expectedSignum);
118
119    assertEquals(
120      "Comparing " + a + " and " + b + " as raw (inverse)",
121      -signum(comparator.compare(baosB.toByteArray(), 0, baosB.size(),
122                                 baosA.toByteArray(), 0, baosA.size())),
123      expectedSignum);
124  }
125
126  private void doComparisonsOnObjects(ImmutableBytesWritable a,
127                                      ImmutableBytesWritable b,
128                                      int expectedSignum) {
129    ImmutableBytesWritable.Comparator comparator =
130      new ImmutableBytesWritable.Comparator();
131    assertEquals(
132      "Comparing " + a + " and " + b + " as objects",
133      signum(comparator.compare(a, b)), expectedSignum);
134    assertEquals(
135      "Comparing " + a + " and " + b + " as objects (inverse)",
136      -signum(comparator.compare(b, a)), expectedSignum);
137  }
138
139}
140