1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase;
21
22 import java.io.IOException;
23 import java.util.Set;
24 import java.util.TreeSet;
25
26 import junit.framework.TestCase;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.apache.hadoop.hbase.KeyValue.KVComparator;
31 import org.apache.hadoop.hbase.KeyValue.MetaComparator;
32 import org.apache.hadoop.hbase.KeyValue.Type;
33 import org.apache.hadoop.hbase.util.Bytes;
34
35 public class TestKeyValue extends TestCase {
36 private final Log LOG = LogFactory.getLog(this.getClass().getName());
37
38 public void testColumnCompare() throws Exception {
39 final byte [] a = Bytes.toBytes("aaa");
40 byte [] family1 = Bytes.toBytes("abc");
41 byte [] qualifier1 = Bytes.toBytes("def");
42 byte [] family2 = Bytes.toBytes("abcd");
43 byte [] qualifier2 = Bytes.toBytes("ef");
44
45 KeyValue aaa = new KeyValue(a, family1, qualifier1, 0L, Type.Put, a);
46 assertFalse(aaa.matchingColumn(family2, qualifier2));
47 assertTrue(aaa.matchingColumn(family1, qualifier1));
48 aaa = new KeyValue(a, family2, qualifier2, 0L, Type.Put, a);
49 assertFalse(aaa.matchingColumn(family1, qualifier1));
50 assertTrue(aaa.matchingColumn(family2,qualifier2));
51 byte [] nullQualifier = new byte[0];
52 aaa = new KeyValue(a, family1, nullQualifier, 0L, Type.Put, a);
53 assertTrue(aaa.matchingColumn(family1,null));
54 assertFalse(aaa.matchingColumn(family2,qualifier2));
55 }
56
57 public void testBasics() throws Exception {
58 LOG.info("LOWKEY: " + KeyValue.LOWESTKEY.toString());
59 check(Bytes.toBytes(getName()),
60 Bytes.toBytes(getName()), Bytes.toBytes(getName()), 1,
61 Bytes.toBytes(getName()));
62
63 check(Bytes.toBytes(getName()), Bytes.toBytes(getName()), null, 1, null);
64 check(HConstants.EMPTY_BYTE_ARRAY, Bytes.toBytes(getName()), null, 1, null);
65 }
66
67 private void check(final byte [] row, final byte [] family, byte [] qualifier,
68 final long timestamp, final byte [] value) {
69 KeyValue kv = new KeyValue(row, family, qualifier, timestamp, value);
70 assertTrue(Bytes.compareTo(kv.getRow(), row) == 0);
71 assertTrue(kv.matchingColumn(family, qualifier));
72
73 LOG.info(kv.toString());
74 }
75
76 public void testPlainCompare() throws Exception {
77 final byte [] a = Bytes.toBytes("aaa");
78 final byte [] b = Bytes.toBytes("bbb");
79 final byte [] fam = Bytes.toBytes("col");
80 final byte [] qf = Bytes.toBytes("umn");
81
82 KeyValue aaa = new KeyValue(a, fam, qf, a);
83 KeyValue bbb = new KeyValue(b, fam, qf, b);
84 byte [] keyabb = aaa.getKey();
85 byte [] keybbb = bbb.getKey();
86 assertTrue(KeyValue.COMPARATOR.compare(aaa, bbb) < 0);
87 assertTrue(KeyValue.KEY_COMPARATOR.compare(keyabb, 0, keyabb.length, keybbb,
88 0, keybbb.length) < 0);
89 assertTrue(KeyValue.COMPARATOR.compare(bbb, aaa) > 0);
90 assertTrue(KeyValue.KEY_COMPARATOR.compare(keybbb, 0, keybbb.length, keyabb,
91 0, keyabb.length) > 0);
92
93 assertTrue(KeyValue.COMPARATOR.compare(bbb, bbb) == 0);
94 assertTrue(KeyValue.KEY_COMPARATOR.compare(keybbb, 0, keybbb.length, keybbb,
95 0, keybbb.length) == 0);
96 assertTrue(KeyValue.COMPARATOR.compare(aaa, aaa) == 0);
97 assertTrue(KeyValue.KEY_COMPARATOR.compare(keyabb, 0, keyabb.length, keyabb,
98 0, keyabb.length) == 0);
99
100 aaa = new KeyValue(a, fam, qf, 1, a);
101 bbb = new KeyValue(a, fam, qf, 2, a);
102 assertTrue(KeyValue.COMPARATOR.compare(aaa, bbb) > 0);
103 assertTrue(KeyValue.COMPARATOR.compare(bbb, aaa) < 0);
104 assertTrue(KeyValue.COMPARATOR.compare(aaa, aaa) == 0);
105
106
107 aaa = new KeyValue(a, fam, qf, 1, KeyValue.Type.Delete, a);
108 bbb = new KeyValue(a, fam, qf, 1, a);
109 assertTrue(KeyValue.COMPARATOR.compare(aaa, bbb) < 0);
110 assertTrue(KeyValue.COMPARATOR.compare(bbb, aaa) > 0);
111 assertTrue(KeyValue.COMPARATOR.compare(aaa, aaa) == 0);
112 }
113
114 public void testMoreComparisons() throws Exception {
115
116 long now = System.currentTimeMillis();
117 KeyValue a = new KeyValue(Bytes.toBytes(".META.,,99999999999999"), now);
118 KeyValue b = new KeyValue(Bytes.toBytes(".META.,,1"), now);
119 KVComparator c = new KeyValue.RootComparator();
120 assertTrue(c.compare(b, a) < 0);
121 KeyValue aa = new KeyValue(Bytes.toBytes(".META.,,1"), now);
122 KeyValue bb = new KeyValue(Bytes.toBytes(".META.,,1"),
123 Bytes.toBytes("info"), Bytes.toBytes("regioninfo"), 1235943454602L,
124 (byte[])null);
125 assertTrue(c.compare(aa, bb) < 0);
126
127
128 KeyValue aaa = new KeyValue(
129 Bytes.toBytes("TestScanMultipleVersions,row_0500,1236020145502"), now);
130 KeyValue bbb = new KeyValue(
131 Bytes.toBytes("TestScanMultipleVersions,,99999999999999"), now);
132 c = new KeyValue.MetaComparator();
133 assertTrue(c.compare(bbb, aaa) < 0);
134
135 KeyValue aaaa = new KeyValue(Bytes.toBytes("TestScanMultipleVersions,,1236023996656"),
136 Bytes.toBytes("info"), Bytes.toBytes("regioninfo"), 1236024396271L,
137 (byte[])null);
138 assertTrue(c.compare(aaaa, bbb) < 0);
139
140 KeyValue x = new KeyValue(Bytes.toBytes("TestScanMultipleVersions,row_0500,1236034574162"),
141 Bytes.toBytes("info"), Bytes.toBytes(""), 9223372036854775807L,
142 (byte[])null);
143 KeyValue y = new KeyValue(Bytes.toBytes("TestScanMultipleVersions,row_0500,1236034574162"),
144 Bytes.toBytes("info"), Bytes.toBytes("regioninfo"), 1236034574912L,
145 (byte[])null);
146 assertTrue(c.compare(x, y) < 0);
147 comparisons(new KeyValue.MetaComparator());
148 comparisons(new KeyValue.KVComparator());
149 metacomparisons(new KeyValue.RootComparator());
150 metacomparisons(new KeyValue.MetaComparator());
151 }
152
153 public void testBadMetaCompareSingleDelim() {
154 MetaComparator c = new KeyValue.MetaComparator();
155 long now = System.currentTimeMillis();
156
157
158 KeyValue a = new KeyValue(Bytes.toBytes("table,a1"), now);
159 KeyValue b = new KeyValue(Bytes.toBytes("table,a2"), now);
160 try {
161 c.compare(a, b);
162 } catch (IllegalArgumentException iae) {
163 assertEquals(".META. key must have two ',' delimiters and have the following" +
164 " format: '<table>,<key>,<etc>'", iae.getMessage());
165 return;
166 }
167 fail("Expected IllegalArgumentException");
168 }
169
170 public void testMetaComparatorTableKeysWithCommaOk() {
171 MetaComparator c = new KeyValue.MetaComparator();
172 long now = System.currentTimeMillis();
173
174
175 KeyValue a = new KeyValue(Bytes.toBytes("table,key,with,commas1,1234"), now);
176 KeyValue b = new KeyValue(Bytes.toBytes("table,key,with,commas2,0123"), now);
177 assertTrue(c.compare(a, b) < 0);
178 }
179
180
181
182
183
184
185 public void testKeyValueBorderCases() throws IOException {
186
187
188 KeyValue rowA = new KeyValue(Bytes.toBytes("testtable,www.hbase.org/,1234"),
189 Bytes.toBytes("fam"), Bytes.toBytes(""), Long.MAX_VALUE, (byte[])null);
190 KeyValue rowB = new KeyValue(Bytes.toBytes("testtable,www.hbase.org/%20,99999"),
191 Bytes.toBytes("fam"), Bytes.toBytes(""), Long.MAX_VALUE, (byte[])null);
192 assertTrue(KeyValue.META_COMPARATOR.compare(rowA, rowB) < 0);
193
194 rowA = new KeyValue(Bytes.toBytes("testtable,,1234"), Bytes.toBytes("fam"),
195 Bytes.toBytes(""), Long.MAX_VALUE, (byte[])null);
196 rowB = new KeyValue(Bytes.toBytes("testtable,$www.hbase.org/,99999"),
197 Bytes.toBytes("fam"), Bytes.toBytes(""), Long.MAX_VALUE, (byte[])null);
198 assertTrue(KeyValue.META_COMPARATOR.compare(rowA, rowB) < 0);
199
200 rowA = new KeyValue(Bytes.toBytes(".META.,testtable,www.hbase.org/,1234,4321"),
201 Bytes.toBytes("fam"), Bytes.toBytes(""), Long.MAX_VALUE, (byte[])null);
202 rowB = new KeyValue(Bytes.toBytes(".META.,testtable,www.hbase.org/%20,99999,99999"),
203 Bytes.toBytes("fam"), Bytes.toBytes(""), Long.MAX_VALUE, (byte[])null);
204 assertTrue(KeyValue.ROOT_COMPARATOR.compare(rowA, rowB) < 0);
205 }
206
207 private void metacomparisons(final KeyValue.MetaComparator c) {
208 long now = System.currentTimeMillis();
209 assertTrue(c.compare(new KeyValue(Bytes.toBytes(".META.,a,,0,1"), now),
210 new KeyValue(Bytes.toBytes(".META.,a,,0,1"), now)) == 0);
211 KeyValue a = new KeyValue(Bytes.toBytes(".META.,a,,0,1"), now);
212 KeyValue b = new KeyValue(Bytes.toBytes(".META.,a,,0,2"), now);
213 assertTrue(c.compare(a, b) < 0);
214 assertTrue(c.compare(new KeyValue(Bytes.toBytes(".META.,a,,0,2"), now),
215 new KeyValue(Bytes.toBytes(".META.,a,,0,1"), now)) > 0);
216 }
217
218 private void comparisons(final KeyValue.KVComparator c) {
219 long now = System.currentTimeMillis();
220 assertTrue(c.compare(new KeyValue(Bytes.toBytes(".META.,,1"), now),
221 new KeyValue(Bytes.toBytes(".META.,,1"), now)) == 0);
222 assertTrue(c.compare(new KeyValue(Bytes.toBytes(".META.,,1"), now),
223 new KeyValue(Bytes.toBytes(".META.,,2"), now)) < 0);
224 assertTrue(c.compare(new KeyValue(Bytes.toBytes(".META.,,2"), now),
225 new KeyValue(Bytes.toBytes(".META.,,1"), now)) > 0);
226 }
227
228 public void testBinaryKeys() throws Exception {
229 Set<KeyValue> set = new TreeSet<KeyValue>(KeyValue.COMPARATOR);
230 final byte [] fam = Bytes.toBytes("col");
231 final byte [] qf = Bytes.toBytes("umn");
232 final byte [] nb = new byte[0];
233 KeyValue [] keys = {new KeyValue(Bytes.toBytes("aaaaa,\u0000\u0000,2"), fam, qf, 2, nb),
234 new KeyValue(Bytes.toBytes("aaaaa,\u0001,3"), fam, qf, 3, nb),
235 new KeyValue(Bytes.toBytes("aaaaa,,1"), fam, qf, 1, nb),
236 new KeyValue(Bytes.toBytes("aaaaa,\u1000,5"), fam, qf, 5, nb),
237 new KeyValue(Bytes.toBytes("aaaaa,a,4"), fam, qf, 4, nb),
238 new KeyValue(Bytes.toBytes("a,a,0"), fam, qf, 0, nb),
239 };
240
241 for (int i = 0; i < keys.length; i++) {
242 set.add(keys[i]);
243 }
244
245 boolean assertion = false;
246 int count = 0;
247 try {
248 for (KeyValue k: set) {
249 assertTrue(count++ == k.getTimestamp());
250 }
251 } catch (junit.framework.AssertionFailedError e) {
252
253 assertion = true;
254 }
255 assertTrue(assertion);
256
257 set = new TreeSet<KeyValue>(new KeyValue.MetaComparator());
258 for (int i = 0; i < keys.length; i++) {
259 set.add(keys[i]);
260 }
261 count = 0;
262 for (KeyValue k: set) {
263 assertTrue(count++ == k.getTimestamp());
264 }
265
266 KeyValue [] rootKeys = {
267 new KeyValue(Bytes.toBytes(".META.,aaaaa,\u0000\u0000,0,2"), fam, qf, 2, nb),
268 new KeyValue(Bytes.toBytes(".META.,aaaaa,\u0001,0,3"), fam, qf, 3, nb),
269 new KeyValue(Bytes.toBytes(".META.,aaaaa,,0,1"), fam, qf, 1, nb),
270 new KeyValue(Bytes.toBytes(".META.,aaaaa,\u1000,0,5"), fam, qf, 5, nb),
271 new KeyValue(Bytes.toBytes(".META.,aaaaa,a,0,4"), fam, qf, 4, nb),
272 new KeyValue(Bytes.toBytes(".META.,,0"), fam, qf, 0, nb),
273 };
274
275 set = new TreeSet<KeyValue>(new KeyValue.MetaComparator());
276
277 for (int i = 0; i < keys.length; i++) {
278 set.add(rootKeys[i]);
279 }
280 assertion = false;
281 count = 0;
282 try {
283 for (KeyValue k: set) {
284 assertTrue(count++ == k.getTimestamp());
285 }
286 } catch (junit.framework.AssertionFailedError e) {
287
288 assertion = true;
289 }
290
291 set = new TreeSet<KeyValue>(new KeyValue.RootComparator());
292
293 for (int i = 0; i < keys.length; i++) {
294 set.add(rootKeys[i]);
295 }
296 count = 0;
297 for (KeyValue k: set) {
298 assertTrue(count++ == k.getTimestamp());
299 }
300 }
301
302 public void testStackedUpKeyValue() {
303
304
305
306
307 }
308
309 private final byte[] rowA = Bytes.toBytes("rowA");
310 private final byte[] rowB = Bytes.toBytes("rowB");
311
312 private final byte[] family = Bytes.toBytes("family");
313 private final byte[] qualA = Bytes.toBytes("qfA");
314
315 private void assertKVLess(KeyValue.KVComparator c,
316 KeyValue less,
317 KeyValue greater) {
318 int cmp = c.compare(less,greater);
319 assertTrue(cmp < 0);
320 cmp = c.compare(greater,less);
321 assertTrue(cmp > 0);
322 }
323
324 public void testFirstLastOnRow() {
325 final KVComparator c = KeyValue.COMPARATOR;
326 long ts = 1;
327
328
329
330 final KeyValue firstOnRowA = KeyValue.createFirstOnRow(rowA);
331 final KeyValue kvA_1 = new KeyValue(rowA, null, null, ts, Type.Put);
332 final KeyValue kvA_2 = new KeyValue(rowA, family, qualA, ts, Type.Put);
333
334 final KeyValue lastOnRowA = KeyValue.createLastOnRow(rowA);
335 final KeyValue firstOnRowB = KeyValue.createFirstOnRow(rowB);
336 final KeyValue kvB = new KeyValue(rowB, family, qualA, ts, Type.Put);
337
338 assertKVLess(c, firstOnRowA, firstOnRowB);
339 assertKVLess(c, firstOnRowA, kvA_1);
340 assertKVLess(c, firstOnRowA, kvA_2);
341 assertKVLess(c, kvA_1, kvA_2);
342 assertKVLess(c, kvA_2, firstOnRowB);
343 assertKVLess(c, kvA_1, firstOnRowB);
344
345 assertKVLess(c, lastOnRowA, firstOnRowB);
346 assertKVLess(c, firstOnRowB, kvB);
347 assertKVLess(c, lastOnRowA, kvB);
348
349 assertKVLess(c, kvA_2, lastOnRowA);
350 assertKVLess(c, kvA_1, lastOnRowA);
351 assertKVLess(c, firstOnRowA, lastOnRowA);
352 }
353
354 public void testCreateKeyOnly() throws Exception {
355 long ts = 1;
356 byte [] value = Bytes.toBytes("a real value");
357 byte [] evalue = new byte[0];
358
359 for (byte[] val : new byte[][]{value, evalue}) {
360 for (boolean useLen : new boolean[]{false,true}) {
361 KeyValue kv1 = new KeyValue(rowA, family, qualA, ts, val);
362 KeyValue kv1ko = kv1.createKeyOnly(useLen);
363
364 assertTrue(kv1.equals(kv1ko));
365
366 assertTrue(kv1ko.getValue().length == (useLen?Bytes.SIZEOF_INT:0));
367 if (useLen) {
368 assertEquals(kv1.getValueLength(), Bytes.toInt(kv1ko.getValue()));
369 }
370 }
371 }
372 }
373 }