View Javadoc

1   /*
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  
20  package org.apache.hadoop.hbase.client;
21  
22  import static org.apache.hadoop.hbase.HBaseTestCase.assertByteEquals;
23  
24  import java.nio.ByteBuffer;
25  import java.util.Arrays;
26  import java.util.List;
27  
28  import junit.framework.TestCase;
29  
30  import org.apache.commons.logging.Log;
31  import org.apache.commons.logging.LogFactory;
32  import org.apache.hadoop.hbase.Cell;
33  import org.apache.hadoop.hbase.CellUtil;
34  import org.apache.hadoop.hbase.KeyValue;
35  import org.apache.hadoop.hbase.SmallTests;
36  import org.apache.hadoop.hbase.util.Bytes;
37  import org.junit.experimental.categories.Category;
38  
39  @Category(SmallTests.class)
40  public class TestResult extends TestCase {
41  
42    private static final Log LOG = LogFactory.getLog(TestResult.class.getName());
43  
44    static KeyValue[] genKVs(final byte[] row, final byte[] family,
45                             final byte[] value,
46                      final long timestamp,
47                      final int cols) {
48      KeyValue [] kvs = new KeyValue[cols];
49  
50      for (int i = 0; i < cols ; i++) {
51        kvs[i] = new KeyValue(
52            row, family, Bytes.toBytes(i),
53            timestamp,
54            Bytes.add(value, Bytes.toBytes(i)));
55      }
56      return kvs;
57    }
58  
59    static final byte [] row = Bytes.toBytes("row");
60    static final byte [] family = Bytes.toBytes("family");
61    static final byte [] value = Bytes.toBytes("value");
62  
63    public void testBasicGetColumn() throws Exception {
64      KeyValue [] kvs = genKVs(row, family, value, 1, 100);
65  
66      Arrays.sort(kvs, KeyValue.COMPARATOR);
67  
68      Result r = Result.create(kvs);
69  
70      for (int i = 0; i < 100; ++i) {
71        final byte[] qf = Bytes.toBytes(i);
72  
73        List<Cell> ks = r.getColumnCells(family, qf);
74        assertEquals(1, ks.size());
75        assertTrue(CellUtil.matchingQualifier(ks.get(0), qf));
76        assertEquals(ks.get(0), r.getColumnLatestCell(family, qf));
77      }
78    }
79  
80    public void testMultiVersionGetColumn() throws Exception {
81      KeyValue [] kvs1 = genKVs(row, family, value, 1, 100);
82      KeyValue [] kvs2 = genKVs(row, family, value, 200, 100);
83  
84      KeyValue [] kvs = new KeyValue[kvs1.length+kvs2.length];
85      System.arraycopy(kvs1, 0, kvs, 0, kvs1.length);
86      System.arraycopy(kvs2, 0, kvs, kvs1.length, kvs2.length);
87  
88      Arrays.sort(kvs, KeyValue.COMPARATOR);
89  
90      Result r = Result.create(kvs);
91      for (int i = 0; i < 100; ++i) {
92        final byte[] qf = Bytes.toBytes(i);
93  
94        List<Cell> ks = r.getColumnCells(family, qf);
95        assertEquals(2, ks.size());
96        assertTrue(CellUtil.matchingQualifier(ks.get(0), qf));
97        assertEquals(200, ks.get(0).getTimestamp());
98        assertEquals(ks.get(0), r.getColumnLatestCell(family, qf));
99      }
100   }
101 
102   public void testBasicGetValue() throws Exception {
103     KeyValue [] kvs = genKVs(row, family, value, 1, 100);
104 
105     Arrays.sort(kvs, KeyValue.COMPARATOR);
106 
107     Result r = Result.create(kvs);
108 
109     for (int i = 0; i < 100; ++i) {
110       final byte[] qf = Bytes.toBytes(i);
111 
112       assertByteEquals(Bytes.add(value, Bytes.toBytes(i)), r.getValue(family, qf));
113       assertTrue(r.containsColumn(family, qf));
114     }
115   }
116 
117   public void testMultiVersionGetValue() throws Exception {
118     KeyValue [] kvs1 = genKVs(row, family, value, 1, 100);
119     KeyValue [] kvs2 = genKVs(row, family, value, 200, 100);
120 
121     KeyValue [] kvs = new KeyValue[kvs1.length+kvs2.length];
122     System.arraycopy(kvs1, 0, kvs, 0, kvs1.length);
123     System.arraycopy(kvs2, 0, kvs, kvs1.length, kvs2.length);
124 
125     Arrays.sort(kvs, KeyValue.COMPARATOR);
126 
127     Result r = Result.create(kvs);
128     for (int i = 0; i < 100; ++i) {
129       final byte[] qf = Bytes.toBytes(i);
130 
131       assertByteEquals(Bytes.add(value, Bytes.toBytes(i)), r.getValue(family, qf));
132       assertTrue(r.containsColumn(family, qf));
133     }
134   }
135 
136   public void testBasicLoadValue() throws Exception {
137     KeyValue [] kvs = genKVs(row, family, value, 1, 100);
138 
139     Arrays.sort(kvs, KeyValue.COMPARATOR);
140 
141     Result r = Result.create(kvs);
142     ByteBuffer loadValueBuffer = ByteBuffer.allocate(1024);
143 
144     for (int i = 0; i < 100; ++i) {
145       final byte[] qf = Bytes.toBytes(i);
146 
147       loadValueBuffer.clear();
148       r.loadValue(family, qf, loadValueBuffer);
149       loadValueBuffer.flip();
150       assertEquals(ByteBuffer.wrap(Bytes.add(value, Bytes.toBytes(i))), loadValueBuffer);
151       assertEquals(ByteBuffer.wrap(Bytes.add(value, Bytes.toBytes(i))),
152           r.getValueAsByteBuffer(family, qf));
153     }
154   }
155 
156   public void testMultiVersionLoadValue() throws Exception {
157     KeyValue [] kvs1 = genKVs(row, family, value, 1, 100);
158     KeyValue [] kvs2 = genKVs(row, family, value, 200, 100);
159 
160     KeyValue [] kvs = new KeyValue[kvs1.length+kvs2.length];
161     System.arraycopy(kvs1, 0, kvs, 0, kvs1.length);
162     System.arraycopy(kvs2, 0, kvs, kvs1.length, kvs2.length);
163 
164     Arrays.sort(kvs, KeyValue.COMPARATOR);
165 
166     ByteBuffer loadValueBuffer = ByteBuffer.allocate(1024);
167 
168     Result r = Result.create(kvs);
169     for (int i = 0; i < 100; ++i) {
170       final byte[] qf = Bytes.toBytes(i);
171 
172       loadValueBuffer.clear();
173       r.loadValue(family, qf, loadValueBuffer);
174       loadValueBuffer.flip();
175       assertEquals(ByteBuffer.wrap(Bytes.add(value, Bytes.toBytes(i))), loadValueBuffer);
176       assertEquals(ByteBuffer.wrap(Bytes.add(value, Bytes.toBytes(i))),
177           r.getValueAsByteBuffer(family, qf));
178     }
179   }
180 
181   /**
182    * Verify that Result.compareResults(...) behaves correctly.
183    */
184   public void testCompareResults() throws Exception {
185     byte [] value1 = Bytes.toBytes("value1");
186     byte [] qual = Bytes.toBytes("qual");
187 
188     KeyValue kv1 = new KeyValue(row, family, qual, value);
189     KeyValue kv2 = new KeyValue(row, family, qual, value1);
190 
191     Result r1 = Result.create(new KeyValue[] {kv1});
192     Result r2 = Result.create(new KeyValue[] {kv2});
193     // no exception thrown
194     Result.compareResults(r1, r1);
195     try {
196       // these are different (HBASE-4800)
197       Result.compareResults(r1, r2);
198       fail();
199     } catch (Exception x) {
200       assertTrue(x.getMessage().startsWith("This result was different:"));
201     }
202   }
203 
204 
205   /**
206    * Microbenchmark that compares {@link Result#getValue} and {@link Result#loadValue} performance.
207    *
208    * @throws Exception
209    */
210   public void doReadBenchmark() throws Exception {
211 
212     final int n = 5;
213     final int m = 100000000;
214 
215     StringBuilder valueSB = new StringBuilder();
216     for (int i = 0; i < 100; i++) {
217       valueSB.append((byte)(Math.random() * 10));
218     }
219 
220     StringBuilder rowSB = new StringBuilder();
221     for (int i = 0; i < 50; i++) {
222       rowSB.append((byte)(Math.random() * 10));
223     }
224 
225     KeyValue [] kvs = genKVs(Bytes.toBytes(rowSB.toString()), family,
226         Bytes.toBytes(valueSB.toString()), 1, n);
227     Arrays.sort(kvs, KeyValue.COMPARATOR);
228     ByteBuffer loadValueBuffer = ByteBuffer.allocate(1024);
229     Result r = Result.create(kvs);
230 
231     byte[][] qfs = new byte[n][Bytes.SIZEOF_INT];
232     for (int i = 0; i < n; ++i) {
233       System.arraycopy(qfs[i], 0, Bytes.toBytes(i), 0, Bytes.SIZEOF_INT);
234     }
235 
236     // warm up
237     for (int k = 0; k < 100000; k++) {
238       for (int i = 0; i < n; ++i) {
239         r.getValue(family, qfs[i]);
240         loadValueBuffer.clear();
241         r.loadValue(family, qfs[i], loadValueBuffer);
242         loadValueBuffer.flip();
243       }
244     }
245 
246     System.gc();
247     long start = System.nanoTime();
248     for (int k = 0; k < m; k++) {
249       for (int i = 0; i < n; ++i) {
250         loadValueBuffer.clear();
251         r.loadValue(family, qfs[i], loadValueBuffer);
252         loadValueBuffer.flip();
253       }
254     }
255     long stop = System.nanoTime();
256     System.out.println("loadValue(): " + (stop - start));
257 
258     System.gc();
259     start = System.nanoTime();
260     for (int k = 0; k < m; k++) {
261       for (int i = 0; i < n; i++) {
262         r.getValue(family, qfs[i]);
263       }
264     }
265     stop = System.nanoTime();
266     System.out.println("getValue():  " + (stop - start));
267   }
268 
269   /**
270    * Calls non-functional test methods.
271    *
272    * @param args
273    */
274   public static void main(String[] args) {
275     TestResult testResult = new TestResult();
276     try {
277       testResult.doReadBenchmark();
278     } catch (Exception e) {
279       LOG.error("Unexpected exception", e);
280     }
281   }
282 }