View Javadoc

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