1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.regionserver;
21
22 import java.io.IOException;
23 import java.util.ArrayList;
24 import java.util.List;
25 import java.util.NavigableSet;
26
27 import static org.apache.hadoop.hbase.regionserver.ScanQueryMatcher.MatchCode.*;
28
29 import org.apache.hadoop.hbase.HBaseTestCase;
30 import org.apache.hadoop.hbase.HConstants;
31 import org.apache.hadoop.hbase.KeyValue;
32 import org.apache.hadoop.hbase.KeyValue.KVComparator;
33 import org.apache.hadoop.hbase.KeyValue.Type;
34 import org.apache.hadoop.hbase.SmallTests;
35 import org.apache.hadoop.hbase.client.Get;
36 import org.apache.hadoop.hbase.client.Scan;
37 import org.apache.hadoop.hbase.regionserver.ScanQueryMatcher.MatchCode;
38 import org.apache.hadoop.hbase.util.Bytes;
39 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
40 import org.junit.experimental.categories.Category;
41
42 @Category(SmallTests.class)
43 public class TestQueryMatcher extends HBaseTestCase {
44 private static final boolean PRINT = false;
45
46 private byte[] row1;
47 private byte[] row2;
48 private byte[] row3;
49 private byte[] fam1;
50 private byte[] fam2;
51 private byte[] col1;
52 private byte[] col2;
53 private byte[] col3;
54 private byte[] col4;
55 private byte[] col5;
56
57 private byte[] data;
58
59 private Get get;
60
61 long ttl = Long.MAX_VALUE;
62 KVComparator rowComparator;
63 private Scan scan;
64
65 public void setUp() throws Exception {
66 super.setUp();
67 row1 = Bytes.toBytes("row1");
68 row2 = Bytes.toBytes("row2");
69 row3 = Bytes.toBytes("row3");
70 fam1 = Bytes.toBytes("fam1");
71 fam2 = Bytes.toBytes("fam2");
72 col1 = Bytes.toBytes("col1");
73 col2 = Bytes.toBytes("col2");
74 col3 = Bytes.toBytes("col3");
75 col4 = Bytes.toBytes("col4");
76 col5 = Bytes.toBytes("col5");
77
78 data = Bytes.toBytes("data");
79
80
81 get = new Get(row1);
82 get.addFamily(fam1);
83 get.addColumn(fam2, col2);
84 get.addColumn(fam2, col4);
85 get.addColumn(fam2, col5);
86 this.scan = new Scan(get);
87
88 rowComparator = KeyValue.COMPARATOR;
89
90 }
91
92 public void testMatch_ExplicitColumns()
93 throws IOException {
94
95
96
97
98 List<MatchCode> expected = new ArrayList<ScanQueryMatcher.MatchCode>();
99 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
100 expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL);
101 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
102 expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL);
103 expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_ROW);
104 expected.add(ScanQueryMatcher.MatchCode.DONE);
105
106
107
108 ScanQueryMatcher qm = new ScanQueryMatcher(scan, new ScanInfo(fam2,
109 0, 1, ttl, false, 0, rowComparator), get.getFamilyMap().get(fam2),
110 EnvironmentEdgeManager.currentTimeMillis() - ttl);
111
112 List<KeyValue> memstore = new ArrayList<KeyValue>();
113 memstore.add(new KeyValue(row1, fam2, col1, 1, data));
114 memstore.add(new KeyValue(row1, fam2, col2, 1, data));
115 memstore.add(new KeyValue(row1, fam2, col3, 1, data));
116 memstore.add(new KeyValue(row1, fam2, col4, 1, data));
117 memstore.add(new KeyValue(row1, fam2, col5, 1, data));
118
119 memstore.add(new KeyValue(row2, fam1, col1, data));
120
121 List<ScanQueryMatcher.MatchCode> actual = new ArrayList<ScanQueryMatcher.MatchCode>();
122 KeyValue k = memstore.get(0);
123 qm.setRow(k.getBuffer(), k.getRowOffset(), k.getRowLength());
124
125 for (KeyValue kv : memstore){
126 actual.add(qm.match(kv));
127 }
128
129 assertEquals(expected.size(), actual.size());
130 for(int i=0; i< expected.size(); i++){
131 assertEquals(expected.get(i), actual.get(i));
132 if(PRINT){
133 System.out.println("expected "+expected.get(i)+
134 ", actual " +actual.get(i));
135 }
136 }
137 }
138
139
140 public void testMatch_Wildcard()
141 throws IOException {
142
143
144
145
146 List<MatchCode> expected = new ArrayList<ScanQueryMatcher.MatchCode>();
147 expected.add(ScanQueryMatcher.MatchCode.INCLUDE);
148 expected.add(ScanQueryMatcher.MatchCode.INCLUDE);
149 expected.add(ScanQueryMatcher.MatchCode.INCLUDE);
150 expected.add(ScanQueryMatcher.MatchCode.INCLUDE);
151 expected.add(ScanQueryMatcher.MatchCode.INCLUDE);
152 expected.add(ScanQueryMatcher.MatchCode.DONE);
153
154 ScanQueryMatcher qm = new ScanQueryMatcher(scan, new ScanInfo(fam2,
155 0, 1, ttl, false, 0, rowComparator), null,
156 EnvironmentEdgeManager.currentTimeMillis() - ttl);
157
158 List<KeyValue> memstore = new ArrayList<KeyValue>();
159 memstore.add(new KeyValue(row1, fam2, col1, 1, data));
160 memstore.add(new KeyValue(row1, fam2, col2, 1, data));
161 memstore.add(new KeyValue(row1, fam2, col3, 1, data));
162 memstore.add(new KeyValue(row1, fam2, col4, 1, data));
163 memstore.add(new KeyValue(row1, fam2, col5, 1, data));
164 memstore.add(new KeyValue(row2, fam1, col1, 1, data));
165
166 List<ScanQueryMatcher.MatchCode> actual = new ArrayList<ScanQueryMatcher.MatchCode>();
167
168 KeyValue k = memstore.get(0);
169 qm.setRow(k.getBuffer(), k.getRowOffset(), k.getRowLength());
170
171 for(KeyValue kv : memstore) {
172 actual.add(qm.match(kv));
173 }
174
175 assertEquals(expected.size(), actual.size());
176 for(int i=0; i< expected.size(); i++){
177 assertEquals(expected.get(i), actual.get(i));
178 if(PRINT){
179 System.out.println("expected "+expected.get(i)+
180 ", actual " +actual.get(i));
181 }
182 }
183 }
184
185
186
187
188
189
190
191
192
193
194 public void testMatch_ExpiredExplicit()
195 throws IOException {
196
197 long testTTL = 1000;
198 MatchCode [] expected = new MatchCode[] {
199 ScanQueryMatcher.MatchCode.SEEK_NEXT_COL,
200 ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL,
201 ScanQueryMatcher.MatchCode.SEEK_NEXT_COL,
202 ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL,
203 ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW,
204 ScanQueryMatcher.MatchCode.DONE
205 };
206
207 long now = EnvironmentEdgeManager.currentTimeMillis();
208 ScanQueryMatcher qm = new ScanQueryMatcher(scan, new ScanInfo(fam2,
209 0, 1, testTTL, false, 0, rowComparator), get.getFamilyMap().get(fam2),
210 now - testTTL);
211
212 KeyValue [] kvs = new KeyValue[] {
213 new KeyValue(row1, fam2, col1, now-100, data),
214 new KeyValue(row1, fam2, col2, now-50, data),
215 new KeyValue(row1, fam2, col3, now-5000, data),
216 new KeyValue(row1, fam2, col4, now-500, data),
217 new KeyValue(row1, fam2, col5, now-10000, data),
218 new KeyValue(row2, fam1, col1, now-10, data)
219 };
220
221 KeyValue k = kvs[0];
222 qm.setRow(k.getBuffer(), k.getRowOffset(), k.getRowLength());
223
224 List<MatchCode> actual = new ArrayList<MatchCode>(kvs.length);
225 for (KeyValue kv : kvs) {
226 actual.add( qm.match(kv) );
227 }
228
229 assertEquals(expected.length, actual.size());
230 for (int i=0; i<expected.length; i++) {
231 if(PRINT){
232 System.out.println("expected "+expected[i]+
233 ", actual " +actual.get(i));
234 }
235 assertEquals(expected[i], actual.get(i));
236 }
237 }
238
239
240
241
242
243
244
245
246
247
248 public void testMatch_ExpiredWildcard()
249 throws IOException {
250
251 long testTTL = 1000;
252 MatchCode [] expected = new MatchCode[] {
253 ScanQueryMatcher.MatchCode.INCLUDE,
254 ScanQueryMatcher.MatchCode.INCLUDE,
255 ScanQueryMatcher.MatchCode.SEEK_NEXT_COL,
256 ScanQueryMatcher.MatchCode.INCLUDE,
257 ScanQueryMatcher.MatchCode.SEEK_NEXT_COL,
258 ScanQueryMatcher.MatchCode.DONE
259 };
260
261 long now = EnvironmentEdgeManager.currentTimeMillis();
262 ScanQueryMatcher qm = new ScanQueryMatcher(scan, new ScanInfo(fam2,
263 0, 1, testTTL, false, 0, rowComparator), null,
264 now - testTTL);
265
266 KeyValue [] kvs = new KeyValue[] {
267 new KeyValue(row1, fam2, col1, now-100, data),
268 new KeyValue(row1, fam2, col2, now-50, data),
269 new KeyValue(row1, fam2, col3, now-5000, data),
270 new KeyValue(row1, fam2, col4, now-500, data),
271 new KeyValue(row1, fam2, col5, now-10000, data),
272 new KeyValue(row2, fam1, col1, now-10, data)
273 };
274 KeyValue k = kvs[0];
275 qm.setRow(k.getBuffer(), k.getRowOffset(), k.getRowLength());
276
277 List<ScanQueryMatcher.MatchCode> actual =
278 new ArrayList<ScanQueryMatcher.MatchCode>(kvs.length);
279 for (KeyValue kv : kvs) {
280 actual.add( qm.match(kv) );
281 }
282
283 assertEquals(expected.length, actual.size());
284 for (int i=0; i<expected.length; i++) {
285 if(PRINT){
286 System.out.println("expected "+expected[i]+
287 ", actual " +actual.get(i));
288 }
289 assertEquals(expected[i], actual.get(i));
290 }
291 }
292
293 public void testMatch_PartialRangeDropDeletes() throws Exception {
294 long now = EnvironmentEdgeManager.currentTimeMillis();
295 ScanInfo scanInfo = new ScanInfo(fam2, 0, 1, ttl, false, 0, rowComparator);
296 NavigableSet<byte[]> cols = get.getFamilyMap().get(fam2);
297
298
299 testDropDeletes(
300 row2, row3, new byte[][] { row1, row2, row2, row3 }, INCLUDE, SKIP, SKIP, INCLUDE);
301 testDropDeletes(row2, row3, new byte[][] { row1, row1, row2 }, INCLUDE, INCLUDE, SKIP);
302 testDropDeletes(row2, row3, new byte[][] { row2, row3, row3 }, SKIP, INCLUDE, INCLUDE);
303 testDropDeletes(row1, row3, new byte[][] { row1, row2, row3 }, SKIP, SKIP, INCLUDE);
304
305 testDropDeletes(HConstants.EMPTY_START_ROW, row3,
306 new byte[][] { row1, row2, row3 }, SKIP, SKIP, INCLUDE);
307 testDropDeletes(row2, HConstants.EMPTY_END_ROW,
308 new byte[][] { row1, row2, row3 }, INCLUDE, SKIP, SKIP);
309 testDropDeletes(HConstants.EMPTY_START_ROW, HConstants.EMPTY_END_ROW,
310 new byte[][] { row1, row2, row3, row3 }, SKIP, SKIP, SKIP, SKIP);
311
312
313 testDropDeletes(row2, row3, new byte[][] { row1, row1, row3 }, INCLUDE, INCLUDE, INCLUDE);
314 testDropDeletes(row2, row3, new byte[][] { row3, row3 }, INCLUDE, INCLUDE);
315 testDropDeletes(row2, row3, new byte[][] { row1, row1 }, INCLUDE, INCLUDE);
316 }
317
318 private void testDropDeletes(
319 byte[] from, byte[] to, byte[][] rows, MatchCode... expected) throws IOException {
320 long now = EnvironmentEdgeManager.currentTimeMillis();
321
322 ScanInfo scanInfo = new ScanInfo(fam2, 0, 1, ttl, false, -1L, rowComparator);
323 NavigableSet<byte[]> cols = get.getFamilyMap().get(fam2);
324
325 ScanQueryMatcher qm = new ScanQueryMatcher(scan, scanInfo, cols, Long.MAX_VALUE,
326 HConstants.OLDEST_TIMESTAMP, HConstants.OLDEST_TIMESTAMP, from, to);
327 List<ScanQueryMatcher.MatchCode> actual =
328 new ArrayList<ScanQueryMatcher.MatchCode>(rows.length);
329 byte[] prevRow = null;
330 for (byte[] row : rows) {
331 if (prevRow == null || !Bytes.equals(prevRow, row)) {
332 qm.setRow(row, 0, (short)row.length);
333 prevRow = row;
334 }
335 actual.add(qm.match(new KeyValue(row, fam2, null, now, Type.Delete)));
336 }
337
338 assertEquals(expected.length, actual.size());
339 for (int i = 0; i < expected.length; i++) {
340 if (PRINT) System.out.println("expected " + expected[i] + ", actual " + actual.get(i));
341 assertEquals(expected[i], actual.get(i));
342 }
343 }
344 }
345