View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.hadoop.hbase.filter;
20  
21  import static org.junit.Assert.assertEquals;
22  
23  import java.io.IOException;
24  import java.nio.ByteBuffer;
25  import java.util.ArrayList;
26  import java.util.List;
27  
28  import org.apache.commons.logging.Log;
29  import org.apache.commons.logging.LogFactory;
30  import org.apache.hadoop.hbase.Cell;
31  import org.apache.hadoop.hbase.CellUtil;
32  import org.apache.hadoop.hbase.HBaseTestingUtility;
33  import org.apache.hadoop.hbase.testclassification.MediumTests;
34  import org.apache.hadoop.hbase.TableName;
35  import org.apache.hadoop.hbase.client.Durability;
36  import org.apache.hadoop.hbase.client.Put;
37  import org.apache.hadoop.hbase.client.Result;
38  import org.apache.hadoop.hbase.client.ResultScanner;
39  import org.apache.hadoop.hbase.client.Scan;
40  import org.apache.hadoop.hbase.client.Table;
41  import org.apache.hadoop.hbase.util.Bytes;
42  import org.apache.hadoop.hbase.util.Pair;
43  import org.junit.After;
44  import org.junit.AfterClass;
45  import org.junit.Before;
46  import org.junit.BeforeClass;
47  import org.junit.Test;
48  import org.junit.experimental.categories.Category;
49  
50  import com.google.common.collect.Lists;
51  
52  /**
53   */
54  @Category(MediumTests.class)
55  public class TestFuzzyRowAndColumnRangeFilter {
56    private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
57    private static final Log LOG = LogFactory.getLog(TestFuzzyRowAndColumnRangeFilter.class);
58  
59    /**
60     * @throws java.lang.Exception
61     */
62    @BeforeClass
63    public static void setUpBeforeClass() throws Exception {
64      TEST_UTIL.startMiniCluster();
65    }
66  
67    /**
68     * @throws java.lang.Exception
69     */
70    @AfterClass
71    public static void tearDownAfterClass() throws Exception {
72      TEST_UTIL.shutdownMiniCluster();
73    }
74  
75    /**
76     * @throws java.lang.Exception
77     */
78    @Before
79    public void setUp() throws Exception {
80      // Nothing to do.
81    }
82  
83    /**
84     * @throws java.lang.Exception
85     */
86    @After
87    public void tearDown() throws Exception {
88      // Nothing to do.
89    }
90  
91    @Test
92    public void Test() throws Exception {
93      String cf = "f";
94      String table = "TestFuzzyAndColumnRangeFilterClient";
95      Table ht = TEST_UTIL.createTable(TableName.valueOf(table),
96              Bytes.toBytes(cf), Integer.MAX_VALUE);
97  
98      // 10 byte row key - (2 bytes 4 bytes 4 bytes)
99      // 4 byte qualifier
100     // 4 byte value
101 
102     for (int i1 = 0; i1 < 2; i1++) {
103       for (int i2 = 0; i2 < 5; i2++) {
104         byte[] rk = new byte[10];
105 
106         ByteBuffer buf = ByteBuffer.wrap(rk);
107         buf.clear();
108         buf.putShort((short) 2);
109         buf.putInt(i1);
110         buf.putInt(i2);
111 
112         for (int c = 0; c < 5; c++) {
113           byte[] cq = new byte[4];
114           Bytes.putBytes(cq, 0, Bytes.toBytes(c), 0, 4);
115 
116           Put p = new Put(rk);
117           p.setDurability(Durability.SKIP_WAL);
118           p.add(cf.getBytes(), cq, Bytes.toBytes(c));
119           ht.put(p);
120           LOG.info("Inserting: rk: " + Bytes.toStringBinary(rk) + " cq: "
121                   + Bytes.toStringBinary(cq));
122         }
123       }
124     }
125 
126     TEST_UTIL.flush();
127 
128     // test passes
129     runTest(ht, 0, 10);
130 
131     // test fails
132     runTest(ht, 1, 8);
133   }
134 
135   private void runTest(Table hTable, int cqStart, int expectedSize) throws IOException {
136     // [0, 2, ?, ?, ?, ?, 0, 0, 0, 1]
137     byte[] fuzzyKey = new byte[10];
138     ByteBuffer buf = ByteBuffer.wrap(fuzzyKey);
139     buf.clear();
140     buf.putShort((short) 2);
141     for (int i = 0; i < 4; i++)
142       buf.put((byte)63);
143     buf.putInt((short)1);
144 
145     byte[] mask = new byte[] {0 , 0, 1, 1, 1, 1, 0, 0, 0, 0};
146 
147     Pair<byte[], byte[]> pair = new Pair<byte[], byte[]>(fuzzyKey, mask);
148     FuzzyRowFilter fuzzyRowFilter = new FuzzyRowFilter(Lists.newArrayList(pair));
149     ColumnRangeFilter columnRangeFilter = new ColumnRangeFilter(Bytes.toBytes(cqStart), true
150             , Bytes.toBytes(4), true);
151     //regular test
152     runScanner(hTable, expectedSize, fuzzyRowFilter, columnRangeFilter);
153     //reverse filter order test
154     runScanner(hTable, expectedSize, columnRangeFilter, fuzzyRowFilter);
155   }
156 
157   private void runScanner(Table hTable, int expectedSize, Filter... filters) throws IOException {
158     String cf = "f";
159     Scan scan = new Scan();
160     scan.addFamily(cf.getBytes());
161     FilterList filterList = new FilterList(filters);
162     scan.setFilter(filterList);
163 
164     ResultScanner scanner = hTable.getScanner(scan);
165     List<Cell> results = new ArrayList<Cell>();
166     Result result;
167     long timeBeforeScan = System.currentTimeMillis();
168     while ((result = scanner.next()) != null) {
169       for (Cell kv : result.listCells()) {
170         LOG.info("Got rk: " + Bytes.toStringBinary(CellUtil.cloneRow(kv)) + " cq: "
171                 + Bytes.toStringBinary(CellUtil.cloneQualifier(kv)));
172         results.add(kv);
173       }
174     }
175     long scanTime = System.currentTimeMillis() - timeBeforeScan;
176     scanner.close();
177 
178     LOG.info("scan time = " + scanTime + "ms");
179     LOG.info("found " + results.size() + " results");
180 
181     assertEquals(expectedSize, results.size());
182   }
183 }