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