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 static org.junit.Assert.assertEquals;
23
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.List;
27 import java.util.TreeSet;
28 import java.util.Arrays;
29
30 import org.apache.hadoop.hbase.*;
31 import org.apache.hadoop.hbase.regionserver.ScanQueryMatcher.MatchCode;
32 import org.apache.hadoop.hbase.util.Bytes;
33 import org.junit.Test;
34 import org.junit.experimental.categories.Category;
35
36
37 @Category(SmallTests.class)
38 public class TestExplicitColumnTracker {
39
40 private final byte[] col1 = Bytes.toBytes("col1");
41 private final byte[] col2 = Bytes.toBytes("col2");
42 private final byte[] col3 = Bytes.toBytes("col3");
43 private final byte[] col4 = Bytes.toBytes("col4");
44 private final byte[] col5 = Bytes.toBytes("col5");
45
46 private void runTest(int maxVersions,
47 TreeSet<byte[]> trackColumns,
48 List<byte[]> scannerColumns,
49 List<MatchCode> expected, int lookAhead) throws IOException {
50 ColumnTracker exp = new ExplicitColumnTracker(
51 trackColumns, 0, maxVersions, Long.MIN_VALUE, lookAhead);
52
53
54
55 List<ScanQueryMatcher.MatchCode> result = new ArrayList<ScanQueryMatcher.MatchCode>();
56
57 long timestamp = 0;
58
59 for(byte [] col : scannerColumns){
60 result.add(ScanQueryMatcher.checkColumn(exp, col, 0, col.length, ++timestamp,
61 KeyValue.Type.Put.getCode(), false));
62 }
63
64 assertEquals(expected.size(), result.size());
65 for(int i=0; i< expected.size(); i++){
66 assertEquals(expected.get(i), result.get(i));
67 }
68 }
69
70 @Test
71 public void testGet_SingleVersion() throws IOException{
72
73 TreeSet<byte[]> columns = new TreeSet<byte[]>(Bytes.BYTES_COMPARATOR);
74
75 columns.add(col2);
76 columns.add(col4);
77 List<MatchCode> expected = new ArrayList<ScanQueryMatcher.MatchCode>();
78 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
79 expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL);
80 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
81 expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_ROW);
82 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW);
83 int maxVersions = 1;
84
85
86 List<byte[]> scanner = new ArrayList<byte[]>();
87 scanner.add(col1);
88 scanner.add(col2);
89 scanner.add(col3);
90 scanner.add(col4);
91 scanner.add(col5);
92
93 runTest(maxVersions, columns, scanner, expected, 0);
94 }
95
96 @Test
97 public void testGet_MultiVersion() throws IOException{
98
99 TreeSet<byte[]> columns = new TreeSet<byte[]>(Bytes.BYTES_COMPARATOR);
100
101 columns.add(col2);
102 columns.add(col4);
103
104 List<ScanQueryMatcher.MatchCode> expected = new ArrayList<ScanQueryMatcher.MatchCode>();
105 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
106 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
107 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
108
109 expected.add(ScanQueryMatcher.MatchCode.INCLUDE);
110 expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL);
111 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
112
113 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
114 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
115 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
116
117 expected.add(ScanQueryMatcher.MatchCode.INCLUDE);
118 expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_ROW);
119 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW);
120
121 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW);
122 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW);
123 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW);
124 int maxVersions = 2;
125
126
127 List<byte[]> scanner = new ArrayList<byte[]>();
128 scanner.add(col1);
129 scanner.add(col1);
130 scanner.add(col1);
131 scanner.add(col2);
132 scanner.add(col2);
133 scanner.add(col2);
134 scanner.add(col3);
135 scanner.add(col3);
136 scanner.add(col3);
137 scanner.add(col4);
138 scanner.add(col4);
139 scanner.add(col4);
140 scanner.add(col5);
141 scanner.add(col5);
142 scanner.add(col5);
143
144
145 runTest(maxVersions, columns, scanner, expected, 0);
146 }
147
148 @Test
149 public void testGet_MultiVersionWithLookAhead() throws IOException{
150
151 TreeSet<byte[]> columns = new TreeSet<byte[]>(Bytes.BYTES_COMPARATOR);
152
153 columns.add(col2);
154 columns.add(col4);
155
156 List<ScanQueryMatcher.MatchCode> expected = new ArrayList<ScanQueryMatcher.MatchCode>();
157 expected.add(ScanQueryMatcher.MatchCode.SKIP);
158 expected.add(ScanQueryMatcher.MatchCode.SKIP);
159 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
160
161 expected.add(ScanQueryMatcher.MatchCode.INCLUDE);
162 expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL);
163 expected.add(ScanQueryMatcher.MatchCode.SKIP);
164
165 expected.add(ScanQueryMatcher.MatchCode.SKIP);
166 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
167 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
168
169 expected.add(ScanQueryMatcher.MatchCode.INCLUDE);
170 expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_ROW);
171 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW);
172
173 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW);
174 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW);
175 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW);
176 int maxVersions = 2;
177
178
179 List<byte[]> scanner = new ArrayList<byte[]>();
180 scanner.add(col1);
181 scanner.add(col1);
182 scanner.add(col1);
183 scanner.add(col2);
184 scanner.add(col2);
185 scanner.add(col2);
186 scanner.add(col3);
187 scanner.add(col3);
188 scanner.add(col3);
189 scanner.add(col4);
190 scanner.add(col4);
191 scanner.add(col4);
192 scanner.add(col5);
193 scanner.add(col5);
194 scanner.add(col5);
195
196
197 runTest(maxVersions, columns, scanner, expected, 2);
198 }
199
200
201
202
203 @Test
204 public void testStackOverflow() throws IOException{
205 int maxVersions = 1;
206 TreeSet<byte[]> columns = new TreeSet<byte[]>(Bytes.BYTES_COMPARATOR);
207 for (int i = 0; i < 100000; i++) {
208 columns.add(Bytes.toBytes("col"+i));
209 }
210
211 ColumnTracker explicit = new ExplicitColumnTracker(columns, 0, maxVersions,
212 Long.MIN_VALUE, 0);
213 for (int i = 0; i < 100000; i+=2) {
214 byte [] col = Bytes.toBytes("col"+i);
215 ScanQueryMatcher.checkColumn(explicit, col, 0, col.length, 1, KeyValue.Type.Put.getCode(),
216 false);
217 }
218 explicit.reset();
219
220 for (int i = 1; i < 100000; i+=2) {
221 byte [] col = Bytes.toBytes("col"+i);
222 ScanQueryMatcher.checkColumn(explicit, col, 0, col.length, 1, KeyValue.Type.Put.getCode(),
223 false);
224 }
225 }
226
227
228
229
230 @Test
231 public void testInfiniteLoop() throws IOException {
232 TreeSet<byte[]> columns = new TreeSet<byte[]>(Bytes.BYTES_COMPARATOR);
233 columns.addAll(Arrays.asList(new byte[][] {
234 col2, col3, col5 }));
235 List<byte[]> scanner = Arrays.<byte[]>asList(
236 new byte[][] { col1, col4 });
237 List<ScanQueryMatcher.MatchCode> expected = Arrays.<ScanQueryMatcher.MatchCode>asList(
238 new ScanQueryMatcher.MatchCode[] {
239 ScanQueryMatcher.MatchCode.SEEK_NEXT_COL,
240 ScanQueryMatcher.MatchCode.SEEK_NEXT_COL });
241 runTest(1, columns, scanner, expected, 0);
242 }
243
244 }
245