1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.filter;
19
20 import static org.junit.Assert.*;
21
22 import java.io.IOException;
23 import java.util.ArrayList;
24 import java.util.HashMap;
25 import java.util.HashSet;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Set;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.apache.hadoop.hbase.*;
33 import org.apache.hadoop.hbase.client.HTable;
34 import org.apache.hadoop.hbase.client.Put;
35 import org.apache.hadoop.hbase.client.Result;
36 import org.apache.hadoop.hbase.client.ResultScanner;
37 import org.apache.hadoop.hbase.client.Scan;
38 import org.apache.hadoop.hbase.regionserver.HRegion;
39 import org.apache.hadoop.hbase.regionserver.InternalScanner;
40 import org.apache.hadoop.hbase.util.Bytes;
41 import org.junit.Test;
42 import org.junit.After;
43 import org.junit.AfterClass;
44 import org.junit.Before;
45 import org.junit.BeforeClass;
46 import org.junit.experimental.categories.Category;
47
48
49 class StringRange {
50 private String start = null;
51 private String end = null;
52 private boolean startInclusive = true;
53 private boolean endInclusive = false;
54
55 public StringRange(String start, boolean startInclusive, String end,
56 boolean endInclusive) {
57 this.start = start;
58 this.startInclusive = startInclusive;
59 this.end = end;
60 this.endInclusive = endInclusive;
61 }
62
63 public String getStart() {
64 return this.start;
65 }
66
67 public String getEnd() {
68 return this.end;
69 }
70
71 public boolean isStartInclusive() {
72 return this.startInclusive;
73 }
74
75 public boolean isEndInclusive() {
76 return this.endInclusive;
77 }
78
79 @Override
80 public int hashCode() {
81 int hashCode = 0;
82 if (this.start != null) {
83 hashCode ^= this.start.hashCode();
84 }
85
86 if (this.end != null) {
87 hashCode ^= this.end.hashCode();
88 }
89 return hashCode;
90 }
91
92 @Override
93 public String toString() {
94 String result = (this.startInclusive ? "[" : "(")
95 + (this.start == null ? null : this.start) + ", "
96 + (this.end == null ? null : this.end)
97 + (this.endInclusive ? "]" : ")");
98 return result;
99 }
100
101 public boolean inRange(String value) {
102 boolean afterStart = true;
103 if (this.start != null) {
104 int startCmp = value.compareTo(this.start);
105 afterStart = this.startInclusive ? startCmp >= 0 : startCmp > 0;
106 }
107
108 boolean beforeEnd = true;
109 if (this.end != null) {
110 int endCmp = value.compareTo(this.end);
111 beforeEnd = this.endInclusive ? endCmp <= 0 : endCmp < 0;
112 }
113
114 return afterStart && beforeEnd;
115 }
116
117 @org.junit.Rule
118 public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu =
119 new org.apache.hadoop.hbase.ResourceCheckerJUnitRule();
120 }
121
122
123 @Category(MediumTests.class)
124 public class TestColumnRangeFilter {
125
126 private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
127
128 private final Log LOG = LogFactory.getLog(this.getClass());
129
130
131
132
133 @BeforeClass
134 public static void setUpBeforeClass() throws Exception {
135 TEST_UTIL.startMiniCluster();
136 }
137
138
139
140
141 @AfterClass
142 public static void tearDownAfterClass() throws Exception {
143 TEST_UTIL.shutdownMiniCluster();
144 }
145
146
147
148
149 @Before
150 public void setUp() throws Exception {
151
152 }
153
154
155
156
157 @After
158 public void tearDown() throws Exception {
159
160 }
161
162 @Test
163 public void TestColumnRangeFilterClient() throws Exception {
164 String family = "Family";
165 String table = "TestColumnRangeFilterClient";
166 HTable ht = TEST_UTIL.createTable(Bytes.toBytes(table),
167 Bytes.toBytes(family), Integer.MAX_VALUE);
168
169 List<String> rows = generateRandomWords(10, 8);
170 long maxTimestamp = 2;
171 List<String> columns = generateRandomWords(20000, 8);
172
173 List<KeyValue> kvList = new ArrayList<KeyValue>();
174
175 Map<StringRange, List<KeyValue>> rangeMap = new HashMap<StringRange, List<KeyValue>>();
176
177 rangeMap.put(new StringRange(null, true, "b", false),
178 new ArrayList<KeyValue>());
179 rangeMap.put(new StringRange("p", true, "q", false),
180 new ArrayList<KeyValue>());
181 rangeMap.put(new StringRange("r", false, "s", true),
182 new ArrayList<KeyValue>());
183 rangeMap.put(new StringRange("z", false, null, false),
184 new ArrayList<KeyValue>());
185 String valueString = "ValueString";
186
187 for (String row : rows) {
188 Put p = new Put(Bytes.toBytes(row));
189 p.setWriteToWAL(false);
190 for (String column : columns) {
191 for (long timestamp = 1; timestamp <= maxTimestamp; timestamp++) {
192 KeyValue kv = KeyValueTestUtil.create(row, family, column, timestamp,
193 valueString);
194 p.add(kv);
195 kvList.add(kv);
196 for (StringRange s : rangeMap.keySet()) {
197 if (s.inRange(column)) {
198 rangeMap.get(s).add(kv);
199 }
200 }
201 }
202 }
203 ht.put(p);
204 }
205
206 TEST_UTIL.flush();
207
208 ColumnRangeFilter filter;
209 Scan scan = new Scan();
210 scan.setMaxVersions();
211 for (StringRange s : rangeMap.keySet()) {
212 filter = new ColumnRangeFilter(s.getStart() == null ? null
213 : Bytes.toBytes(s.getStart()), s.isStartInclusive(),
214 s.getEnd() == null ? null : Bytes.toBytes(s.getEnd()),
215 s.isEndInclusive());
216 scan.setFilter(filter);
217 ResultScanner scanner = ht.getScanner(scan);
218 List<KeyValue> results = new ArrayList<KeyValue>();
219 LOG.info("scan column range: " + s.toString());
220 long timeBeforeScan = System.currentTimeMillis();
221
222 Result result;
223 while ((result = scanner.next()) != null) {
224 for (KeyValue kv : result.list()) {
225 results.add(kv);
226 }
227 }
228 long scanTime = System.currentTimeMillis() - timeBeforeScan;
229 scanner.close();
230 LOG.info("scan time = " + scanTime + "ms");
231 LOG.info("found " + results.size() + " results");
232 LOG.info("Expecting " + rangeMap.get(s).size() + " results");
233
234
235
236
237
238
239
240
241 assertEquals(rangeMap.get(s).size(), results.size());
242 }
243 ht.close();
244 }
245
246 List<String> generateRandomWords(int numberOfWords, int maxLengthOfWords) {
247 Set<String> wordSet = new HashSet<String>();
248 for (int i = 0; i < numberOfWords; i++) {
249 int lengthOfWords = (int) (Math.random() * maxLengthOfWords) + 1;
250 char[] wordChar = new char[lengthOfWords];
251 for (int j = 0; j < wordChar.length; j++) {
252 wordChar[j] = (char) (Math.random() * 26 + 97);
253 }
254 String word = new String(wordChar);
255 wordSet.add(word);
256 }
257 List<String> wordList = new ArrayList<String>(wordSet);
258 return wordList;
259 }
260
261 @org.junit.Rule
262 public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu =
263 new org.apache.hadoop.hbase.ResourceCheckerJUnitRule();
264 }
265