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 testAdvanceMultipleOnEmptyCell() throws IOException {
119 Result r = Result.create(new Cell[0]);
120
121
122 for (int i = 0; i < 10; i++) {
123 assertFalse(r.advance());
124 }
125 }
126
127 public void testMultiVersionGetColumn() throws Exception {
128 KeyValue [] kvs1 = genKVs(row, family, value, 1, 100);
129 KeyValue [] kvs2 = genKVs(row, family, value, 200, 100);
130
131 KeyValue [] kvs = new KeyValue[kvs1.length+kvs2.length];
132 System.arraycopy(kvs1, 0, kvs, 0, kvs1.length);
133 System.arraycopy(kvs2, 0, kvs, kvs1.length, kvs2.length);
134
135 Arrays.sort(kvs, KeyValue.COMPARATOR);
136
137 Result r = Result.create(kvs);
138 for (int i = 0; i < 100; ++i) {
139 final byte[] qf = Bytes.toBytes(i);
140
141 List<Cell> ks = r.getColumnCells(family, qf);
142 assertEquals(2, ks.size());
143 assertTrue(CellUtil.matchingQualifier(ks.get(0), qf));
144 assertEquals(200, ks.get(0).getTimestamp());
145 assertEquals(ks.get(0), r.getColumnLatestCell(family, qf));
146 }
147 }
148
149 public void testBasicGetValue() throws Exception {
150 KeyValue [] kvs = genKVs(row, family, value, 1, 100);
151
152 Arrays.sort(kvs, KeyValue.COMPARATOR);
153
154 Result r = Result.create(kvs);
155
156 for (int i = 0; i < 100; ++i) {
157 final byte[] qf = Bytes.toBytes(i);
158
159 assertByteEquals(Bytes.add(value, Bytes.toBytes(i)), r.getValue(family, qf));
160 assertTrue(r.containsColumn(family, qf));
161 }
162 }
163
164 public void testMultiVersionGetValue() throws Exception {
165 KeyValue [] kvs1 = genKVs(row, family, value, 1, 100);
166 KeyValue [] kvs2 = genKVs(row, family, value, 200, 100);
167
168 KeyValue [] kvs = new KeyValue[kvs1.length+kvs2.length];
169 System.arraycopy(kvs1, 0, kvs, 0, kvs1.length);
170 System.arraycopy(kvs2, 0, kvs, kvs1.length, kvs2.length);
171
172 Arrays.sort(kvs, KeyValue.COMPARATOR);
173
174 Result r = Result.create(kvs);
175 for (int i = 0; i < 100; ++i) {
176 final byte[] qf = Bytes.toBytes(i);
177
178 assertByteEquals(Bytes.add(value, Bytes.toBytes(i)), r.getValue(family, qf));
179 assertTrue(r.containsColumn(family, qf));
180 }
181 }
182
183 public void testBasicLoadValue() throws Exception {
184 KeyValue [] kvs = genKVs(row, family, value, 1, 100);
185
186 Arrays.sort(kvs, KeyValue.COMPARATOR);
187
188 Result r = Result.create(kvs);
189 ByteBuffer loadValueBuffer = ByteBuffer.allocate(1024);
190
191 for (int i = 0; i < 100; ++i) {
192 final byte[] qf = Bytes.toBytes(i);
193
194 loadValueBuffer.clear();
195 r.loadValue(family, qf, loadValueBuffer);
196 loadValueBuffer.flip();
197 assertEquals(ByteBuffer.wrap(Bytes.add(value, Bytes.toBytes(i))), loadValueBuffer);
198 assertEquals(ByteBuffer.wrap(Bytes.add(value, Bytes.toBytes(i))),
199 r.getValueAsByteBuffer(family, qf));
200 }
201 }
202
203 public void testMultiVersionLoadValue() throws Exception {
204 KeyValue [] kvs1 = genKVs(row, family, value, 1, 100);
205 KeyValue [] kvs2 = genKVs(row, family, value, 200, 100);
206
207 KeyValue [] kvs = new KeyValue[kvs1.length+kvs2.length];
208 System.arraycopy(kvs1, 0, kvs, 0, kvs1.length);
209 System.arraycopy(kvs2, 0, kvs, kvs1.length, kvs2.length);
210
211 Arrays.sort(kvs, KeyValue.COMPARATOR);
212
213 ByteBuffer loadValueBuffer = ByteBuffer.allocate(1024);
214
215 Result r = Result.create(kvs);
216 for (int i = 0; i < 100; ++i) {
217 final byte[] qf = Bytes.toBytes(i);
218
219 loadValueBuffer.clear();
220 r.loadValue(family, qf, loadValueBuffer);
221 loadValueBuffer.flip();
222 assertEquals(ByteBuffer.wrap(Bytes.add(value, Bytes.toBytes(i))), loadValueBuffer);
223 assertEquals(ByteBuffer.wrap(Bytes.add(value, Bytes.toBytes(i))),
224 r.getValueAsByteBuffer(family, qf));
225 }
226 }
227
228
229
230
231 public void testCompareResults() throws Exception {
232 byte [] value1 = Bytes.toBytes("value1");
233 byte [] qual = Bytes.toBytes("qual");
234
235 KeyValue kv1 = new KeyValue(row, family, qual, value);
236 KeyValue kv2 = new KeyValue(row, family, qual, value1);
237
238 Result r1 = Result.create(new KeyValue[] {kv1});
239 Result r2 = Result.create(new KeyValue[] {kv2});
240
241 Result.compareResults(r1, r1);
242 try {
243
244 Result.compareResults(r1, r2);
245 fail();
246 } catch (Exception x) {
247 assertTrue(x.getMessage().startsWith("This result was different:"));
248 }
249 }
250
251
252
253
254
255 @Test
256 public void testCompareResultsWithTags() throws Exception {
257 byte[] qualifier = Bytes.toBytes("q");
258 String tagValue1 = "tagV1";
259 String tagValue2 = "tagV2";
260
261 KeyValue kv1 = new KeyValue(row, family, qualifier, HConstants.LATEST_TIMESTAMP,
262 value, new Tag[] {new Tag((byte) 1, tagValue1), new Tag((byte) 2, tagValue2)});
263
264
265 KeyValue kv2 = new KeyValue(row, family, qualifier, HConstants.LATEST_TIMESTAMP,
266 value);
267
268 Result r1 = Result.create(new KeyValue[] {kv1});
269 Result r2 = Result.create(new KeyValue[] {kv2});
270
271 Result.compareResults(r1, r1);
272
273 try {
274
275 Result.compareResults(r1, r2);
276 fail();
277 } catch (Exception e) {
278 assertTrue(e.getMessage().startsWith("This result was different:"));
279 }
280
281
282 String tagValue3 = "tagV3";
283 KeyValue kv3 = new KeyValue(row, family, qualifier, HConstants.LATEST_TIMESTAMP,
284 value, new Tag[] {new Tag((byte) 1, tagValue3)});
285 Result r3 = Result.create(new KeyValue[] {kv3});
286 try {
287
288 Result.compareResults(r1, r3);
289 fail();
290 } catch (Exception e) {
291 assertTrue(e.getMessage().startsWith("This result was different:"));
292 }
293 }
294
295
296
297
298 public void testEmptyResultIsReadonly() {
299 Result emptyResult = Result.EMPTY_RESULT;
300 Result otherResult = new Result();
301
302 try {
303 emptyResult.copyFrom(otherResult);
304 fail("UnsupportedOperationException should have been thrown!");
305 } catch (UnsupportedOperationException ex) {
306 LOG.debug("As expected: " + ex.getMessage());
307 }
308 try {
309 emptyResult.addResults(ClientProtos.RegionLoadStats.getDefaultInstance());
310 fail("UnsupportedOperationException should have been thrown!");
311 } catch (UnsupportedOperationException ex) {
312 LOG.debug("As expected: " + ex.getMessage());
313 }
314 try {
315 emptyResult.setExists(true);
316 fail("UnsupportedOperationException should have been thrown!");
317 } catch (UnsupportedOperationException ex) {
318 LOG.debug("As expected: " + ex.getMessage());
319 }
320 }
321
322
323
324
325
326
327 public void doReadBenchmark() throws Exception {
328
329 final int n = 5;
330 final int m = 100000000;
331
332 StringBuilder valueSB = new StringBuilder();
333 for (int i = 0; i < 100; i++) {
334 valueSB.append((byte)(Math.random() * 10));
335 }
336
337 StringBuilder rowSB = new StringBuilder();
338 for (int i = 0; i < 50; i++) {
339 rowSB.append((byte)(Math.random() * 10));
340 }
341
342 KeyValue [] kvs = genKVs(Bytes.toBytes(rowSB.toString()), family,
343 Bytes.toBytes(valueSB.toString()), 1, n);
344 Arrays.sort(kvs, KeyValue.COMPARATOR);
345 ByteBuffer loadValueBuffer = ByteBuffer.allocate(1024);
346 Result r = Result.create(kvs);
347
348 byte[][] qfs = new byte[n][Bytes.SIZEOF_INT];
349 for (int i = 0; i < n; ++i) {
350 System.arraycopy(qfs[i], 0, Bytes.toBytes(i), 0, Bytes.SIZEOF_INT);
351 }
352
353
354 for (int k = 0; k < 100000; k++) {
355 for (int i = 0; i < n; ++i) {
356 r.getValue(family, qfs[i]);
357 loadValueBuffer.clear();
358 r.loadValue(family, qfs[i], loadValueBuffer);
359 loadValueBuffer.flip();
360 }
361 }
362
363 System.gc();
364 long start = System.nanoTime();
365 for (int k = 0; k < m; k++) {
366 for (int i = 0; i < n; ++i) {
367 loadValueBuffer.clear();
368 r.loadValue(family, qfs[i], loadValueBuffer);
369 loadValueBuffer.flip();
370 }
371 }
372 long stop = System.nanoTime();
373 System.out.println("loadValue(): " + (stop - start));
374
375 System.gc();
376 start = System.nanoTime();
377 for (int k = 0; k < m; k++) {
378 for (int i = 0; i < n; i++) {
379 r.getValue(family, qfs[i]);
380 }
381 }
382 stop = System.nanoTime();
383 System.out.println("getValue(): " + (stop - start));
384 }
385
386
387
388
389
390
391 public static void main(String[] args) {
392 TestResult testResult = new TestResult();
393 try {
394 testResult.doReadBenchmark();
395 } catch (Exception e) {
396 LOG.error("Unexpected exception", e);
397 }
398 }
399 }