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.client;
21
22 import static org.apache.hadoop.hbase.HBaseTestCase.assertByteEquals;
23
24 import java.io.IOException;
25 import java.nio.ByteBuffer;
26 import java.util.Arrays;
27 import java.util.List;
28 import java.util.NoSuchElementException;
29
30 import junit.framework.TestCase;
31
32 import org.apache.commons.logging.Log;
33 import org.apache.commons.logging.LogFactory;
34 import org.apache.hadoop.hbase.Cell;
35 import org.apache.hadoop.hbase.CellScanner;
36 import org.apache.hadoop.hbase.CellUtil;
37 import org.apache.hadoop.hbase.HConstants;
38 import org.apache.hadoop.hbase.KeyValue;
39 import org.apache.hadoop.hbase.Tag;
40 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
41 import org.apache.hadoop.hbase.testclassification.SmallTests;
42 import org.apache.hadoop.hbase.util.Bytes;
43 import org.junit.Test;
44 import org.junit.experimental.categories.Category;
45
46 @Category(SmallTests.class)
47 public class TestResult extends TestCase {
48
49 private static final Log LOG = LogFactory.getLog(TestResult.class.getName());
50
51 static KeyValue[] genKVs(final byte[] row, final byte[] family,
52 final byte[] value,
53 final long timestamp,
54 final int cols) {
55 KeyValue [] kvs = new KeyValue[cols];
56
57 for (int i = 0; i < cols ; i++) {
58 kvs[i] = new KeyValue(
59 row, family, Bytes.toBytes(i),
60 timestamp,
61 Bytes.add(value, Bytes.toBytes(i)));
62 }
63 return kvs;
64 }
65
66 static final byte [] row = Bytes.toBytes("row");
67 static final byte [] family = Bytes.toBytes("family");
68 static final byte [] value = Bytes.toBytes("value");
69
70
71
72
73
74 public void testResultAsCellScanner() throws IOException {
75 Cell [] cells = genKVs(row, family, value, 1, 10);
76 Arrays.sort(cells, KeyValue.COMPARATOR);
77 Result r = Result.create(cells);
78 assertSame(r, cells);
79
80 assertSame(r.cellScanner(), cells);
81 assertSame(r.cellScanner(), cells);
82
83 assertTrue(r == r.cellScanner());
84 }
85
86 private void assertSame(final CellScanner cellScanner, final Cell [] cells) throws IOException {
87 int count = 0;
88 while (cellScanner.advance()) {
89 assertTrue(cells[count].equals(cellScanner.current()));
90 count++;
91 }
92 assertEquals(cells.length, count);
93 }
94
95 public void testBasicGetColumn() throws Exception {
96 KeyValue [] kvs = genKVs(row, family, value, 1, 100);
97
98 Arrays.sort(kvs, KeyValue.COMPARATOR);
99
100 Result r = Result.create(kvs);
101
102 for (int i = 0; i < 100; ++i) {
103 final byte[] qf = Bytes.toBytes(i);
104
105 List<Cell> ks = r.getColumnCells(family, qf);
106 assertEquals(1, ks.size());
107 assertTrue(CellUtil.matchingQualifier(ks.get(0), qf));
108 assertEquals(ks.get(0), r.getColumnLatestCell(family, qf));
109 }
110 }
111
112 public void testCurrentOnEmptyCell() throws IOException {
113 Result r = Result.create(new Cell[0]);
114 assertFalse(r.advance());
115 assertNull(r.current());
116 }
117
118 public void testAdvanceTwiceOnEmptyCell() throws IOException {
119 Result r = Result.create(new Cell[0]);
120 assertFalse(r.advance());
121 try {
122 r.advance();
123 fail("NoSuchElementException should have been thrown!");
124 } catch (NoSuchElementException ex) {
125 LOG.debug("As expected: " + ex.getMessage());
126 }
127 }
128
129 public void testMultiVersionGetColumn() throws Exception {
130 KeyValue [] kvs1 = genKVs(row, family, value, 1, 100);
131 KeyValue [] kvs2 = genKVs(row, family, value, 200, 100);
132
133 KeyValue [] kvs = new KeyValue[kvs1.length+kvs2.length];
134 System.arraycopy(kvs1, 0, kvs, 0, kvs1.length);
135 System.arraycopy(kvs2, 0, kvs, kvs1.length, kvs2.length);
136
137 Arrays.sort(kvs, KeyValue.COMPARATOR);
138
139 Result r = Result.create(kvs);
140 for (int i = 0; i < 100; ++i) {
141 final byte[] qf = Bytes.toBytes(i);
142
143 List<Cell> ks = r.getColumnCells(family, qf);
144 assertEquals(2, ks.size());
145 assertTrue(CellUtil.matchingQualifier(ks.get(0), qf));
146 assertEquals(200, ks.get(0).getTimestamp());
147 assertEquals(ks.get(0), r.getColumnLatestCell(family, qf));
148 }
149 }
150
151 public void testBasicGetValue() throws Exception {
152 KeyValue [] kvs = genKVs(row, family, value, 1, 100);
153
154 Arrays.sort(kvs, KeyValue.COMPARATOR);
155
156 Result r = Result.create(kvs);
157
158 for (int i = 0; i < 100; ++i) {
159 final byte[] qf = Bytes.toBytes(i);
160
161 assertByteEquals(Bytes.add(value, Bytes.toBytes(i)), r.getValue(family, qf));
162 assertTrue(r.containsColumn(family, qf));
163 }
164 }
165
166 public void testMultiVersionGetValue() throws Exception {
167 KeyValue [] kvs1 = genKVs(row, family, value, 1, 100);
168 KeyValue [] kvs2 = genKVs(row, family, value, 200, 100);
169
170 KeyValue [] kvs = new KeyValue[kvs1.length+kvs2.length];
171 System.arraycopy(kvs1, 0, kvs, 0, kvs1.length);
172 System.arraycopy(kvs2, 0, kvs, kvs1.length, kvs2.length);
173
174 Arrays.sort(kvs, KeyValue.COMPARATOR);
175
176 Result r = Result.create(kvs);
177 for (int i = 0; i < 100; ++i) {
178 final byte[] qf = Bytes.toBytes(i);
179
180 assertByteEquals(Bytes.add(value, Bytes.toBytes(i)), r.getValue(family, qf));
181 assertTrue(r.containsColumn(family, qf));
182 }
183 }
184
185 public void testBasicLoadValue() throws Exception {
186 KeyValue [] kvs = genKVs(row, family, value, 1, 100);
187
188 Arrays.sort(kvs, KeyValue.COMPARATOR);
189
190 Result r = Result.create(kvs);
191 ByteBuffer loadValueBuffer = ByteBuffer.allocate(1024);
192
193 for (int i = 0; i < 100; ++i) {
194 final byte[] qf = Bytes.toBytes(i);
195
196 loadValueBuffer.clear();
197 r.loadValue(family, qf, loadValueBuffer);
198 loadValueBuffer.flip();
199 assertEquals(ByteBuffer.wrap(Bytes.add(value, Bytes.toBytes(i))), loadValueBuffer);
200 assertEquals(ByteBuffer.wrap(Bytes.add(value, Bytes.toBytes(i))),
201 r.getValueAsByteBuffer(family, qf));
202 }
203 }
204
205 public void testMultiVersionLoadValue() throws Exception {
206 KeyValue [] kvs1 = genKVs(row, family, value, 1, 100);
207 KeyValue [] kvs2 = genKVs(row, family, value, 200, 100);
208
209 KeyValue [] kvs = new KeyValue[kvs1.length+kvs2.length];
210 System.arraycopy(kvs1, 0, kvs, 0, kvs1.length);
211 System.arraycopy(kvs2, 0, kvs, kvs1.length, kvs2.length);
212
213 Arrays.sort(kvs, KeyValue.COMPARATOR);
214
215 ByteBuffer loadValueBuffer = ByteBuffer.allocate(1024);
216
217 Result r = Result.create(kvs);
218 for (int i = 0; i < 100; ++i) {
219 final byte[] qf = Bytes.toBytes(i);
220
221 loadValueBuffer.clear();
222 r.loadValue(family, qf, loadValueBuffer);
223 loadValueBuffer.flip();
224 assertEquals(ByteBuffer.wrap(Bytes.add(value, Bytes.toBytes(i))), loadValueBuffer);
225 assertEquals(ByteBuffer.wrap(Bytes.add(value, Bytes.toBytes(i))),
226 r.getValueAsByteBuffer(family, qf));
227 }
228 }
229
230
231
232
233 public void testCompareResults() throws Exception {
234 byte [] value1 = Bytes.toBytes("value1");
235 byte [] qual = Bytes.toBytes("qual");
236
237 KeyValue kv1 = new KeyValue(row, family, qual, value);
238 KeyValue kv2 = new KeyValue(row, family, qual, value1);
239
240 Result r1 = Result.create(new KeyValue[] {kv1});
241 Result r2 = Result.create(new KeyValue[] {kv2});
242
243 Result.compareResults(r1, r1);
244 try {
245
246 Result.compareResults(r1, r2);
247 fail();
248 } catch (Exception x) {
249 assertTrue(x.getMessage().startsWith("This result was different:"));
250 }
251 }
252
253
254
255
256
257 @Test
258 public void testCompareResultsWithTags() throws Exception {
259 byte[] qualifier = Bytes.toBytes("q");
260 String tagValue1 = "tagV1";
261 String tagValue2 = "tagV2";
262
263 KeyValue kv1 = new KeyValue(row, family, qualifier, HConstants.LATEST_TIMESTAMP,
264 value, new Tag[] {new Tag((byte) 1, tagValue1), new Tag((byte) 2, tagValue2)});
265
266
267 KeyValue kv2 = new KeyValue(row, family, qualifier, HConstants.LATEST_TIMESTAMP,
268 value);
269
270 Result r1 = Result.create(new KeyValue[] {kv1});
271 Result r2 = Result.create(new KeyValue[] {kv2});
272
273 Result.compareResults(r1, r1);
274
275 try {
276
277 Result.compareResults(r1, r2);
278 fail();
279 } catch (Exception e) {
280 assertTrue(e.getMessage().startsWith("This result was different:"));
281 }
282
283
284 String tagValue3 = "tagV3";
285 KeyValue kv3 = new KeyValue(row, family, qualifier, HConstants.LATEST_TIMESTAMP,
286 value, new Tag[] {new Tag((byte) 1, tagValue3)});
287 Result r3 = Result.create(new KeyValue[] {kv3});
288 try {
289
290 Result.compareResults(r1, r3);
291 fail();
292 } catch (Exception e) {
293 assertTrue(e.getMessage().startsWith("This result was different:"));
294 }
295 }
296
297
298
299
300 public void testEmptyResultIsReadonly() {
301 Result emptyResult = Result.EMPTY_RESULT;
302 Result otherResult = new Result();
303
304 try {
305 emptyResult.copyFrom(otherResult);
306 fail("UnsupportedOperationException should have been thrown!");
307 } catch (UnsupportedOperationException ex) {
308 LOG.debug("As expected: " + ex.getMessage());
309 }
310 try {
311 emptyResult.addResults(ClientProtos.RegionLoadStats.getDefaultInstance());
312 fail("UnsupportedOperationException should have been thrown!");
313 } catch (UnsupportedOperationException ex) {
314 LOG.debug("As expected: " + ex.getMessage());
315 }
316 try {
317 emptyResult.setExists(true);
318 fail("UnsupportedOperationException should have been thrown!");
319 } catch (UnsupportedOperationException ex) {
320 LOG.debug("As expected: " + ex.getMessage());
321 }
322 }
323
324
325
326
327
328
329 public void doReadBenchmark() throws Exception {
330
331 final int n = 5;
332 final int m = 100000000;
333
334 StringBuilder valueSB = new StringBuilder();
335 for (int i = 0; i < 100; i++) {
336 valueSB.append((byte)(Math.random() * 10));
337 }
338
339 StringBuilder rowSB = new StringBuilder();
340 for (int i = 0; i < 50; i++) {
341 rowSB.append((byte)(Math.random() * 10));
342 }
343
344 KeyValue [] kvs = genKVs(Bytes.toBytes(rowSB.toString()), family,
345 Bytes.toBytes(valueSB.toString()), 1, n);
346 Arrays.sort(kvs, KeyValue.COMPARATOR);
347 ByteBuffer loadValueBuffer = ByteBuffer.allocate(1024);
348 Result r = Result.create(kvs);
349
350 byte[][] qfs = new byte[n][Bytes.SIZEOF_INT];
351 for (int i = 0; i < n; ++i) {
352 System.arraycopy(qfs[i], 0, Bytes.toBytes(i), 0, Bytes.SIZEOF_INT);
353 }
354
355
356 for (int k = 0; k < 100000; k++) {
357 for (int i = 0; i < n; ++i) {
358 r.getValue(family, qfs[i]);
359 loadValueBuffer.clear();
360 r.loadValue(family, qfs[i], loadValueBuffer);
361 loadValueBuffer.flip();
362 }
363 }
364
365 System.gc();
366 long start = System.nanoTime();
367 for (int k = 0; k < m; k++) {
368 for (int i = 0; i < n; ++i) {
369 loadValueBuffer.clear();
370 r.loadValue(family, qfs[i], loadValueBuffer);
371 loadValueBuffer.flip();
372 }
373 }
374 long stop = System.nanoTime();
375 System.out.println("loadValue(): " + (stop - start));
376
377 System.gc();
378 start = System.nanoTime();
379 for (int k = 0; k < m; k++) {
380 for (int i = 0; i < n; i++) {
381 r.getValue(family, qfs[i]);
382 }
383 }
384 stop = System.nanoTime();
385 System.out.println("getValue(): " + (stop - start));
386 }
387
388
389
390
391
392
393 public static void main(String[] args) {
394 TestResult testResult = new TestResult();
395 try {
396 testResult.doReadBenchmark();
397 } catch (Exception e) {
398 LOG.error("Unexpected exception", e);
399 }
400 }
401 }