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; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertTrue; 022 023import java.nio.ByteBuffer; 024import java.util.Collections; 025import java.util.Set; 026import java.util.TreeSet; 027 028import org.apache.hadoop.hbase.KeyValue.Type; 029import org.apache.hadoop.hbase.testclassification.MiscTests; 030import org.apache.hadoop.hbase.testclassification.SmallTests; 031import org.apache.hadoop.hbase.util.Bytes; 032import org.junit.ClassRule; 033import org.junit.Test; 034import org.junit.experimental.categories.Category; 035 036@Category({MiscTests.class, SmallTests.class}) 037public class TestCellComparator { 038 039 @ClassRule 040 public static final HBaseClassTestRule CLASS_RULE = 041 HBaseClassTestRule.forClass(TestCellComparator.class); 042 043 private CellComparator comparator = CellComparator.getInstance(); 044 byte[] row1 = Bytes.toBytes("row1"); 045 byte[] row2 = Bytes.toBytes("row2"); 046 byte[] row_1_0 = Bytes.toBytes("row10"); 047 048 byte[] fam1 = Bytes.toBytes("fam1"); 049 byte[] fam2 = Bytes.toBytes("fam2"); 050 byte[] fam_1_2 = Bytes.toBytes("fam12"); 051 052 byte[] qual1 = Bytes.toBytes("qual1"); 053 byte[] qual2 = Bytes.toBytes("qual2"); 054 055 byte[] val = Bytes.toBytes("val"); 056 057 @Test 058 public void testCompareCells() { 059 KeyValue kv1 = new KeyValue(row1, fam1, qual1, val); 060 KeyValue kv2 = new KeyValue(row2, fam1, qual1, val); 061 assertTrue((comparator.compare(kv1, kv2)) < 0); 062 063 kv1 = new KeyValue(row1, fam2, qual1, val); 064 kv2 = new KeyValue(row1, fam1, qual1, val); 065 assertTrue((comparator.compareFamilies(kv1, kv2) > 0)); 066 067 kv1 = new KeyValue(row1, fam1, qual1, 1L, val); 068 kv2 = new KeyValue(row1, fam1, qual1, 2L, val); 069 assertTrue((comparator.compare(kv1, kv2) > 0)); 070 071 kv1 = new KeyValue(row1, fam1, qual1, 1L, Type.Put); 072 kv2 = new KeyValue(row1, fam1, qual1, 1L, Type.Maximum); 073 assertTrue((comparator.compare(kv1, kv2) > 0)); 074 075 kv1 = new KeyValue(row1, fam1, qual1, 1L, Type.Put); 076 kv2 = new KeyValue(row1, fam1, qual1, 1L, Type.Put); 077 assertTrue((CellUtil.equals(kv1, kv2))); 078 } 079 080 @Test 081 public void testCompareCellWithKey() throws Exception { 082 KeyValue kv1 = new KeyValue(row1, fam1, qual1, val); 083 KeyValue kv2 = new KeyValue(row2, fam1, qual1, val); 084 assertTrue( 085 (PrivateCellUtil.compare(comparator, kv1, kv2.getKey(), 0, kv2.getKey().length)) < 0); 086 087 kv1 = new KeyValue(row1, fam2, qual1, val); 088 kv2 = new KeyValue(row1, fam1, qual1, val); 089 assertTrue( 090 (PrivateCellUtil.compare(comparator, kv1, kv2.getKey(), 0, kv2.getKey().length)) > 0); 091 092 kv1 = new KeyValue(row1, fam1, qual1, 1L, val); 093 kv2 = new KeyValue(row1, fam1, qual1, 2L, val); 094 assertTrue( 095 (PrivateCellUtil.compare(comparator, kv1, kv2.getKey(), 0, kv2.getKey().length)) > 0); 096 097 kv1 = new KeyValue(row1, fam1, qual1, 1L, Type.Put); 098 kv2 = new KeyValue(row1, fam1, qual1, 1L, Type.Maximum); 099 assertTrue( 100 (PrivateCellUtil.compare(comparator, kv1, kv2.getKey(), 0, kv2.getKey().length)) > 0); 101 102 kv1 = new KeyValue(row1, fam1, qual1, 1L, Type.Put); 103 kv2 = new KeyValue(row1, fam1, qual1, 1L, Type.Put); 104 assertTrue( 105 (PrivateCellUtil.compare(comparator, kv1, kv2.getKey(), 0, kv2.getKey().length)) == 0); 106 } 107 108 @Test 109 public void testCompareByteBufferedCell() { 110 byte[] r1 = Bytes.toBytes("row1"); 111 byte[] r2 = Bytes.toBytes("row2"); 112 byte[] f1 = Bytes.toBytes("cf1"); 113 byte[] q1 = Bytes.toBytes("qual1"); 114 byte[] q2 = Bytes.toBytes("qual2"); 115 byte[] v = Bytes.toBytes("val1"); 116 KeyValue kv = new KeyValue(r1, f1, q1, v); 117 ByteBuffer buffer = ByteBuffer.wrap(kv.getBuffer()); 118 Cell bbCell1 = new ByteBufferKeyValue(buffer, 0, buffer.remaining()); 119 kv = new KeyValue(r2, f1, q1, v); 120 buffer = ByteBuffer.wrap(kv.getBuffer()); 121 Cell bbCell2 = new ByteBufferKeyValue(buffer, 0, buffer.remaining()); 122 // compareColumns not on CellComparator so use Impl directly 123 assertEquals(0, CellComparatorImpl.COMPARATOR.compareColumns(bbCell1, bbCell2)); 124 assertEquals(0, CellComparatorImpl.COMPARATOR.compareColumns(bbCell1, kv)); 125 kv = new KeyValue(r2, f1, q2, v); 126 buffer = ByteBuffer.wrap(kv.getBuffer()); 127 Cell bbCell3 = new ByteBufferKeyValue(buffer, 0, buffer.remaining()); 128 assertEquals(0, comparator.compareFamilies(bbCell2, bbCell3)); 129 assertTrue(comparator.compareQualifiers(bbCell2, bbCell3) < 0); 130 assertTrue(CellComparatorImpl.COMPARATOR.compareColumns(bbCell2, bbCell3) < 0); 131 132 assertEquals(0, comparator.compareRows(bbCell2, bbCell3)); 133 assertTrue(comparator.compareRows(bbCell1, bbCell2) < 0); 134 } 135 136 /** 137 * Test meta comparisons using our new ByteBufferKeyValue Cell type, the type we use everywhere 138 * in 2.0. 139 */ 140 @Test 141 public void testMetaComparisons() throws Exception { 142 long now = System.currentTimeMillis(); 143 144 // Meta compares 145 Cell aaa = createByteBufferKeyValueFromKeyValue(new KeyValue( 146 Bytes.toBytes("TestScanMultipleVersions,row_0500,1236020145502"), now)); 147 Cell bbb = createByteBufferKeyValueFromKeyValue(new KeyValue( 148 Bytes.toBytes("TestScanMultipleVersions,,99999999999999"), now)); 149 CellComparator c = CellComparatorImpl.META_COMPARATOR; 150 assertTrue(c.compare(bbb, aaa) < 0); 151 152 Cell ccc = createByteBufferKeyValueFromKeyValue( 153 new KeyValue(Bytes.toBytes("TestScanMultipleVersions,,1236023996656"), 154 Bytes.toBytes("info"), Bytes.toBytes("regioninfo"), 1236024396271L, 155 (byte[])null)); 156 assertTrue(c.compare(ccc, bbb) < 0); 157 158 Cell x = createByteBufferKeyValueFromKeyValue( 159 new KeyValue(Bytes.toBytes("TestScanMultipleVersions,row_0500,1236034574162"), 160 Bytes.toBytes("info"), Bytes.toBytes(""), 9223372036854775807L, 161 (byte[])null)); 162 Cell y = createByteBufferKeyValueFromKeyValue( 163 new KeyValue(Bytes.toBytes("TestScanMultipleVersions,row_0500,1236034574162"), 164 Bytes.toBytes("info"), Bytes.toBytes("regioninfo"), 1236034574912L, 165 (byte[])null)); 166 assertTrue(c.compare(x, y) < 0); 167 } 168 169 private static Cell createByteBufferKeyValueFromKeyValue(KeyValue kv) { 170 ByteBuffer bb = ByteBuffer.wrap(kv.getBuffer()); 171 return new ByteBufferKeyValue(bb, 0, bb.remaining()); 172 } 173 174 /** 175 * More tests using ByteBufferKeyValue copied over from TestKeyValue which uses old KVs only. 176 */ 177 @Test 178 public void testMetaComparisons2() { 179 long now = System.currentTimeMillis(); 180 CellComparator c = CellComparatorImpl.META_COMPARATOR; 181 assertTrue(c.compare(createByteBufferKeyValueFromKeyValue(new KeyValue( 182 Bytes.toBytes(TableName.META_TABLE_NAME.getNameAsString()+",a,,0,1"), now)), 183 createByteBufferKeyValueFromKeyValue(new KeyValue( 184 Bytes.toBytes(TableName.META_TABLE_NAME.getNameAsString()+",a,,0,1"), now))) == 0); 185 Cell a = createByteBufferKeyValueFromKeyValue(new KeyValue( 186 Bytes.toBytes(TableName.META_TABLE_NAME.getNameAsString()+",a,,0,1"), now)); 187 Cell b = createByteBufferKeyValueFromKeyValue(new KeyValue( 188 Bytes.toBytes(TableName.META_TABLE_NAME.getNameAsString()+",a,,0,2"), now)); 189 assertTrue(c.compare(a, b) < 0); 190 assertTrue(c.compare(createByteBufferKeyValueFromKeyValue(new KeyValue( 191 Bytes.toBytes(TableName.META_TABLE_NAME.getNameAsString()+",a,,0,2"), now)), 192 createByteBufferKeyValueFromKeyValue(new KeyValue( 193 Bytes.toBytes(TableName.META_TABLE_NAME.getNameAsString()+",a,,0,1"), now))) > 0); 194 assertTrue(c.compare(createByteBufferKeyValueFromKeyValue(new KeyValue( 195 Bytes.toBytes(TableName.META_TABLE_NAME.getNameAsString()+",,1"), now)), 196 createByteBufferKeyValueFromKeyValue(new KeyValue( 197 Bytes.toBytes(TableName.META_TABLE_NAME.getNameAsString()+",,1"), now))) == 0); 198 assertTrue(c.compare(createByteBufferKeyValueFromKeyValue(new KeyValue( 199 Bytes.toBytes(TableName.META_TABLE_NAME.getNameAsString()+",,1"), now)), 200 createByteBufferKeyValueFromKeyValue(new KeyValue( 201 Bytes.toBytes(TableName.META_TABLE_NAME.getNameAsString()+",,2"), now))) < 0); 202 assertTrue(c.compare(createByteBufferKeyValueFromKeyValue(new KeyValue( 203 Bytes.toBytes(TableName.META_TABLE_NAME.getNameAsString()+",,2"), now)), 204 createByteBufferKeyValueFromKeyValue(new KeyValue( 205 Bytes.toBytes(TableName.META_TABLE_NAME.getNameAsString()+",,1"), now))) > 0); 206 } 207 208 @Test 209 public void testBinaryKeys() throws Exception { 210 Set<Cell> set = new TreeSet<>(CellComparatorImpl.COMPARATOR); 211 final byte [] fam = Bytes.toBytes("col"); 212 final byte [] qf = Bytes.toBytes("umn"); 213 final byte [] nb = new byte[0]; 214 Cell [] keys = { 215 createByteBufferKeyValueFromKeyValue( 216 new KeyValue(Bytes.toBytes("aaaaa,\u0000\u0000,2"), fam, qf, 2, nb)), 217 createByteBufferKeyValueFromKeyValue( 218 new KeyValue(Bytes.toBytes("aaaaa,\u0001,3"), fam, qf, 3, nb)), 219 createByteBufferKeyValueFromKeyValue( 220 new KeyValue(Bytes.toBytes("aaaaa,,1"), fam, qf, 1, nb)), 221 createByteBufferKeyValueFromKeyValue( 222 new KeyValue(Bytes.toBytes("aaaaa,\u1000,5"), fam, qf, 5, nb)), 223 createByteBufferKeyValueFromKeyValue( 224 new KeyValue(Bytes.toBytes("aaaaa,a,4"), fam, qf, 4, nb)), 225 createByteBufferKeyValueFromKeyValue( 226 new KeyValue(Bytes.toBytes("a,a,0"), fam, qf, 0, nb)), 227 }; 228 // Add to set with bad comparator 229 Collections.addAll(set, keys); 230 // This will output the keys incorrectly. 231 boolean assertion = false; 232 int count = 0; 233 try { 234 for (Cell k: set) { 235 assertTrue("count=" + count + ", " + k.toString(), count++ == k.getTimestamp()); 236 } 237 } catch (AssertionError e) { 238 // Expected 239 assertion = true; 240 } 241 assertTrue(assertion); 242 // Make set with good comparator 243 set = new TreeSet<>(CellComparatorImpl.META_COMPARATOR); 244 Collections.addAll(set, keys); 245 count = 0; 246 for (Cell k: set) { 247 assertTrue("count=" + count + ", " + k.toString(), count++ == k.getTimestamp()); 248 } 249 } 250}