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 junit.framework.TestCase;
23  import org.apache.commons.logging.Log;
24  import org.apache.commons.logging.LogFactory;
25  import org.apache.hadoop.hbase.KeyValue;
26  import org.apache.hadoop.hbase.SmallTests;
27  import org.apache.hadoop.hbase.util.Bytes;
28  import org.junit.experimental.categories.Category;
29  
30  import static org.apache.hadoop.hbase.HBaseTestCase.assertByteEquals;
31  
32  import java.nio.ByteBuffer;
33  import java.util.Arrays;
34  import java.util.List;
35  import java.util.Map;
36  import java.util.NavigableMap;
37  
38  @Category(SmallTests.class)
39  public class TestResult extends TestCase {
40  
41    private static final Log LOG = LogFactory.getLog(TestResult.class.getName());
42  
43    static KeyValue[] genKVs(final byte[] row, final byte[] family,
44                             final byte[] value,
45                      final long timestamp,
46                      final int cols) {
47      KeyValue [] kvs = new KeyValue[cols];
48  
49      for (int i = 0; i < cols ; i++) {
50        kvs[i] = new KeyValue(
51            row, family, Bytes.toBytes(i),
52            timestamp,
53            Bytes.add(value, Bytes.toBytes(i)));
54      }
55      return kvs;
56    }
57  
58    static final byte [] row = Bytes.toBytes("row");
59    static final byte [] family = Bytes.toBytes("family");
60    static final byte [] value = Bytes.toBytes("value");
61  
62    public void testBasicGetColumn() throws Exception {
63      KeyValue [] kvs = genKVs(row, family, value, 1, 100);
64  
65      Arrays.sort(kvs, KeyValue.COMPARATOR);
66  
67      Result r = new Result(kvs);
68  
69      for (int i = 0; i < 100; ++i) {
70        final byte[] qf = Bytes.toBytes(i);
71  
72        List<KeyValue> ks = r.getColumn(family, qf);
73        assertEquals(1, ks.size());
74        assertByteEquals(qf, ks.get(0).getQualifier());
75        assertEquals(ks.get(0), r.getColumnLatest(family, qf));
76      }
77    }
78  
79    public void testMultiVersionGetColumn() throws Exception {
80      KeyValue [] kvs1 = genKVs(row, family, value, 1, 100);
81      KeyValue [] kvs2 = genKVs(row, family, value, 200, 100);
82  
83      KeyValue [] kvs = new KeyValue[kvs1.length+kvs2.length];
84      System.arraycopy(kvs1, 0, kvs, 0, kvs1.length);
85      System.arraycopy(kvs2, 0, kvs, kvs1.length, kvs2.length);
86  
87      Arrays.sort(kvs, KeyValue.COMPARATOR);
88  
89      Result r = new Result(kvs);
90      for (int i = 0; i < 100; ++i) {
91        final byte[] qf = Bytes.toBytes(i);
92  
93        List<KeyValue> ks = r.getColumn(family, qf);
94        assertEquals(2, ks.size());
95        assertByteEquals(qf, ks.get(0).getQualifier());
96        assertEquals(200, ks.get(0).getTimestamp());
97        assertEquals(ks.get(0), r.getColumnLatest(family, qf));
98      }
99    }
100 
101   public void testBasicGetValue() throws Exception {
102     KeyValue [] kvs = genKVs(row, family, value, 1, 100);
103 
104     Arrays.sort(kvs, KeyValue.COMPARATOR);
105 
106     Result r = new Result(kvs);
107 
108     for (int i = 0; i < 100; ++i) {
109       final byte[] qf = Bytes.toBytes(i);
110 
111       assertByteEquals(Bytes.add(value, Bytes.toBytes(i)), r.getValue(family, qf));
112       assertTrue(r.containsColumn(family, qf));
113     }
114   }
115 
116   public void testMultiVersionGetValue() throws Exception {
117     KeyValue [] kvs1 = genKVs(row, family, value, 1, 100);
118     KeyValue [] kvs2 = genKVs(row, family, value, 200, 100);
119 
120     KeyValue [] kvs = new KeyValue[kvs1.length+kvs2.length];
121     System.arraycopy(kvs1, 0, kvs, 0, kvs1.length);
122     System.arraycopy(kvs2, 0, kvs, kvs1.length, kvs2.length);
123 
124     Arrays.sort(kvs, KeyValue.COMPARATOR);
125 
126     Result r = new Result(kvs);
127     for (int i = 0; i < 100; ++i) {
128       final byte[] qf = Bytes.toBytes(i);
129 
130       assertByteEquals(Bytes.add(value, Bytes.toBytes(i)), r.getValue(family, qf));
131       assertTrue(r.containsColumn(family, qf));
132     }
133   }
134 
135   public void testBasicLoadValue() throws Exception {
136     KeyValue [] kvs = genKVs(row, family, value, 1, 100);
137 
138     Arrays.sort(kvs, KeyValue.COMPARATOR);
139 
140     Result r = new Result(kvs);
141     ByteBuffer loadValueBuffer = ByteBuffer.allocate(1024);
142 
143     for (int i = 0; i < 100; ++i) {
144       final byte[] qf = Bytes.toBytes(i);
145 
146       loadValueBuffer.clear();
147       r.loadValue(family, qf, loadValueBuffer);
148       loadValueBuffer.flip();
149       assertEquals(ByteBuffer.wrap(Bytes.add(value, Bytes.toBytes(i))), loadValueBuffer);
150       assertEquals(ByteBuffer.wrap(Bytes.add(value, Bytes.toBytes(i))),
151           r.getValueAsByteBuffer(family, qf));
152     }
153   }
154 
155   public void testMultiVersionLoadValue() throws Exception {
156     KeyValue [] kvs1 = genKVs(row, family, value, 1, 100);
157     KeyValue [] kvs2 = genKVs(row, family, value, 200, 100);
158 
159     KeyValue [] kvs = new KeyValue[kvs1.length+kvs2.length];
160     System.arraycopy(kvs1, 0, kvs, 0, kvs1.length);
161     System.arraycopy(kvs2, 0, kvs, kvs1.length, kvs2.length);
162 
163     Arrays.sort(kvs, KeyValue.COMPARATOR);
164 
165     ByteBuffer loadValueBuffer = ByteBuffer.allocate(1024);
166 
167     Result r = new Result(kvs);
168     for (int i = 0; i < 100; ++i) {
169       final byte[] qf = Bytes.toBytes(i);
170 
171       loadValueBuffer.clear();
172       r.loadValue(family, qf, loadValueBuffer);
173       loadValueBuffer.flip();
174       assertEquals(ByteBuffer.wrap(Bytes.add(value, Bytes.toBytes(i))), loadValueBuffer);
175       assertEquals(ByteBuffer.wrap(Bytes.add(value, Bytes.toBytes(i))),
176           r.getValueAsByteBuffer(family, qf));
177     }
178   }
179 
180   /**
181    * Verify that Result.compareResults(...) behaves correctly.
182    */
183   public void testCompareResults() throws Exception {
184     byte [] value1 = Bytes.toBytes("value1");
185     byte [] qual = Bytes.toBytes("qual");
186 
187     KeyValue kv1 = new KeyValue(row, family, qual, value);
188     KeyValue kv2 = new KeyValue(row, family, qual, value1);
189 
190     Result r1 = new Result(new KeyValue[] {kv1});
191     Result r2 = new Result(new KeyValue[] {kv2});
192     // no exception thrown
193     Result.compareResults(r1, r1);
194     try {
195       // these are different (HBASE-4800)
196       Result.compareResults(r1, r2);
197       fail();
198     } catch (Exception x) {
199       assertTrue(x.getMessage().startsWith("This result was different:"));
200     }
201   }
202 
203 
204   /**
205    * Microbenchmark that compares {@link Result#getValue} and {@link Result#loadValue} performance.
206    *
207    * @throws Exception
208    */
209   public void doReadBenchmark() throws Exception {
210 
211     final int n = 5;
212     final int m = 100000000;
213 
214     StringBuilder valueSB = new StringBuilder();
215     for (int i = 0; i < 100; i++) {
216       valueSB.append((byte)(Math.random() * 10));
217     }
218 
219     StringBuilder rowSB = new StringBuilder();
220     for (int i = 0; i < 50; i++) {
221       rowSB.append((byte)(Math.random() * 10));
222     }
223 
224     KeyValue [] kvs = genKVs(Bytes.toBytes(rowSB.toString()), family,
225         Bytes.toBytes(valueSB.toString()), 1, n);
226     Arrays.sort(kvs, KeyValue.COMPARATOR);
227     ByteBuffer loadValueBuffer = ByteBuffer.allocate(1024);
228     Result r = new Result(kvs);
229 
230     byte[][] qfs = new byte[n][Bytes.SIZEOF_INT];
231     for (int i = 0; i < n; ++i) {
232       System.arraycopy(qfs[i], 0, Bytes.toBytes(i), 0, Bytes.SIZEOF_INT);
233     }
234 
235     // warm up
236     for (int k = 0; k < 100000; k++) {
237       for (int i = 0; i < n; ++i) {
238         r.getValue(family, qfs[i]);
239         loadValueBuffer.clear();
240         r.loadValue(family, qfs[i], loadValueBuffer);
241         loadValueBuffer.flip();
242       }
243     }
244 
245     System.gc();
246     long start = System.nanoTime();
247     for (int k = 0; k < m; k++) {
248       for (int i = 0; i < n; ++i) {
249         loadValueBuffer.clear();
250         r.loadValue(family, qfs[i], loadValueBuffer);
251         loadValueBuffer.flip();
252       }
253     }
254     long stop = System.nanoTime();
255     System.out.println("loadValue(): " + (stop - start));
256 
257     System.gc();
258     start = System.nanoTime();
259     for (int k = 0; k < m; k++) {
260       for (int i = 0; i < n; i++) {
261         r.getValue(family, qfs[i]);
262       }
263     }
264     stop = System.nanoTime();
265     System.out.println("getValue():  " + (stop - start));
266   }
267 
268   /**
269    * Calls non-functional test methods.
270    *
271    * @param args
272    */
273   public static void main(String[] args) {
274     TestResult testResult = new TestResult();
275     try {
276       testResult.doReadBenchmark();
277     } catch (Exception e) {
278       LOG.error("Unexpected exception", e);
279     }
280   }
281 }