1   package org.apache.hadoop.hbase.filter;
2   
3   import static org.junit.Assert.*;
4   
5   import java.io.IOException;
6   import java.util.ArrayList;
7   import java.util.HashMap;
8   import java.util.HashSet;
9   import java.util.List;
10  import java.util.Map;
11  import java.util.Set;
12  
13  import org.apache.hadoop.hbase.HBaseTestingUtility;
14  import org.apache.hadoop.hbase.HColumnDescriptor;
15  import org.apache.hadoop.hbase.HRegionInfo;
16  import org.apache.hadoop.hbase.HTableDescriptor;
17  import org.apache.hadoop.hbase.KeyValue;
18  import org.apache.hadoop.hbase.KeyValueTestUtil;
19  import org.apache.hadoop.hbase.client.Put;
20  import org.apache.hadoop.hbase.client.Scan;
21  import org.apache.hadoop.hbase.regionserver.HRegion;
22  import org.apache.hadoop.hbase.regionserver.InternalScanner;
23  import org.apache.hadoop.hbase.util.Bytes;
24  import org.junit.Test;
25  
26  public class TestColumnPrefixFilter {
27  
28    private final static HBaseTestingUtility TEST_UTIL = new
29        HBaseTestingUtility();
30  
31    @Test
32    public void testColumnPrefixFilter() throws IOException {
33      String family = "Family";
34      HTableDescriptor htd = new HTableDescriptor("TestColumnPrefixFilter");
35      htd.addFamily(new HColumnDescriptor(family));
36      HRegionInfo info = new HRegionInfo(htd, null, null, false);
37      HRegion region = HRegion.createHRegion(info, HBaseTestingUtility.
38          getTestDir(), TEST_UTIL.getConfiguration());
39  
40      List<String> rows = generateRandomWords(100, "row");
41      List<String> columns = generateRandomWords(10000, "column");
42      long maxTimestamp = 2;
43  
44      List<KeyValue> kvList = new ArrayList<KeyValue>();
45  
46      Map<String, List<KeyValue>> prefixMap = new HashMap<String,
47          List<KeyValue>>();
48  
49      prefixMap.put("p", new ArrayList<KeyValue>());
50      prefixMap.put("s", new ArrayList<KeyValue>());
51  
52      String valueString = "ValueString";
53  
54      for (String row: rows) {
55        Put p = new Put(Bytes.toBytes(row));
56        for (String column: columns) {
57          for (long timestamp = 1; timestamp <= maxTimestamp; timestamp++) {
58            KeyValue kv = KeyValueTestUtil.create(row, family, column, timestamp,
59                valueString);
60            p.add(kv);
61            kvList.add(kv);
62            for (String s: prefixMap.keySet()) {
63              if (column.startsWith(s)) {
64                prefixMap.get(s).add(kv);
65              }
66            }
67          }
68        }
69        region.put(p);
70      }
71  
72      ColumnPrefixFilter filter;
73      Scan scan = new Scan();
74      scan.setMaxVersions();
75      for (String s: prefixMap.keySet()) {
76        filter = new ColumnPrefixFilter(Bytes.toBytes(s));
77  
78        scan.setFilter(filter);
79  
80        InternalScanner scanner = region.getScanner(scan);
81        List<KeyValue> results = new ArrayList<KeyValue>();
82        while(scanner.next(results));
83        assertEquals(prefixMap.get(s).size(), results.size());
84      }
85    }
86  
87    @Test
88    public void testColumnPrefixFilterWithFilterList() throws IOException {
89      String family = "Family";
90      HTableDescriptor htd = new HTableDescriptor("TestColumnPrefixFilter");
91      htd.addFamily(new HColumnDescriptor(family));
92      HRegionInfo info = new HRegionInfo(htd, null, null, false);
93      HRegion region = HRegion.createHRegion(info, HBaseTestingUtility.
94          getTestDir(), TEST_UTIL.getConfiguration());
95  
96      List<String> rows = generateRandomWords(100, "row");
97      List<String> columns = generateRandomWords(10000, "column");
98      long maxTimestamp = 2;
99  
100     List<KeyValue> kvList = new ArrayList<KeyValue>();
101 
102     Map<String, List<KeyValue>> prefixMap = new HashMap<String,
103         List<KeyValue>>();
104 
105     prefixMap.put("p", new ArrayList<KeyValue>());
106     prefixMap.put("s", new ArrayList<KeyValue>());
107 
108     String valueString = "ValueString";
109 
110     for (String row: rows) {
111       Put p = new Put(Bytes.toBytes(row));
112       for (String column: columns) {
113         for (long timestamp = 1; timestamp <= maxTimestamp; timestamp++) {
114           KeyValue kv = KeyValueTestUtil.create(row, family, column, timestamp,
115               valueString);
116           p.add(kv);
117           kvList.add(kv);
118           for (String s: prefixMap.keySet()) {
119             if (column.startsWith(s)) {
120               prefixMap.get(s).add(kv);
121             }
122           }
123         }
124       }
125       region.put(p);
126     }
127 
128     ColumnPrefixFilter filter;
129     Scan scan = new Scan();
130     scan.setMaxVersions();
131     for (String s: prefixMap.keySet()) {
132       filter = new ColumnPrefixFilter(Bytes.toBytes(s));
133 
134       //this is how this test differs from the one above
135       FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL);
136       filterList.addFilter(filter);
137       scan.setFilter(filterList);
138 
139       InternalScanner scanner = region.getScanner(scan);
140       List<KeyValue> results = new ArrayList<KeyValue>();
141       while(scanner.next(results));
142       assertEquals(prefixMap.get(s).size(), results.size());
143     }
144   }
145 
146   List<String> generateRandomWords(int numberOfWords, String suffix) {
147     Set<String> wordSet = new HashSet<String>();
148     for (int i = 0; i < numberOfWords; i++) {
149       int lengthOfWords = (int) (Math.random()*2) + 1;
150       char[] wordChar = new char[lengthOfWords];
151       for (int j = 0; j < wordChar.length; j++) {
152         wordChar[j] = (char) (Math.random() * 26 + 97);
153       }
154       String word;
155       if (suffix == null) {
156         word = new String(wordChar);
157       } else {
158         word = new String(wordChar) + suffix;
159       }
160       wordSet.add(word);
161     }
162     List<String> wordList = new ArrayList<String>(wordSet);
163     return wordList;
164   }
165 }