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