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.querymatcher;
21
22 import static org.junit.Assert.assertEquals;
23
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.List;
28 import java.util.TreeSet;
29
30 import org.apache.hadoop.hbase.KeyValue;
31 import org.apache.hadoop.hbase.regionserver.querymatcher.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 @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, TreeSet<byte[]> trackColumns, List<byte[]> scannerColumns,
47 List<MatchCode> expected) throws IOException {
48 ColumnTracker exp = new ExplicitColumnTracker(trackColumns, 0, maxVersions, Long.MIN_VALUE);
49
50
51 List<ScanQueryMatcher.MatchCode> result = new ArrayList<ScanQueryMatcher.MatchCode>();
52
53 long timestamp = 0;
54
55 for (byte[] col : scannerColumns) {
56 result.add(ScanQueryMatcher.checkColumn(exp, col, 0, col.length, ++timestamp,
57 KeyValue.Type.Put.getCode(), false));
58 }
59
60 assertEquals(expected.size(), result.size());
61 for (int i = 0; i < expected.size(); i++) {
62 assertEquals(expected.get(i), result.get(i));
63 }
64 }
65
66 @Test
67 public void testGetSingleVersion() throws IOException {
68
69 TreeSet<byte[]> columns = new TreeSet<byte[]>(Bytes.BYTES_COMPARATOR);
70
71 columns.add(col2);
72 columns.add(col4);
73 List<MatchCode> expected = new ArrayList<ScanQueryMatcher.MatchCode>();
74 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
75 expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL);
76 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
77 expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_ROW);
78 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW);
79 int maxVersions = 1;
80
81
82 List<byte[]> scanner = new ArrayList<byte[]>();
83 scanner.add(col1);
84 scanner.add(col2);
85 scanner.add(col3);
86 scanner.add(col4);
87 scanner.add(col5);
88
89 runTest(maxVersions, columns, scanner, expected);
90 }
91
92 @Test
93 public void testGetMultiVersion() throws IOException {
94
95 TreeSet<byte[]> columns = new TreeSet<byte[]>(Bytes.BYTES_COMPARATOR);
96
97 columns.add(col2);
98 columns.add(col4);
99
100 List<ScanQueryMatcher.MatchCode> expected = new ArrayList<ScanQueryMatcher.MatchCode>();
101 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
102 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
103 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
104
105 expected.add(ScanQueryMatcher.MatchCode.INCLUDE);
106 expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_COL);
107 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
108
109 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
110 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
111 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_COL);
112
113 expected.add(ScanQueryMatcher.MatchCode.INCLUDE);
114 expected.add(ScanQueryMatcher.MatchCode.INCLUDE_AND_SEEK_NEXT_ROW);
115 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW);
116
117 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW);
118 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW);
119 expected.add(ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW);
120 int maxVersions = 2;
121
122
123 List<byte[]> scanner = new ArrayList<byte[]>();
124 scanner.add(col1);
125 scanner.add(col1);
126 scanner.add(col1);
127 scanner.add(col2);
128 scanner.add(col2);
129 scanner.add(col2);
130 scanner.add(col3);
131 scanner.add(col3);
132 scanner.add(col3);
133 scanner.add(col4);
134 scanner.add(col4);
135 scanner.add(col4);
136 scanner.add(col5);
137 scanner.add(col5);
138 scanner.add(col5);
139
140
141 runTest(maxVersions, columns, scanner, expected);
142 }
143
144
145
146
147 @Test
148 public void testStackOverflow() throws IOException {
149 int maxVersions = 1;
150 TreeSet<byte[]> columns = new TreeSet<byte[]>(Bytes.BYTES_COMPARATOR);
151 for (int i = 0; i < 100000; i++) {
152 columns.add(Bytes.toBytes("col" + i));
153 }
154
155 ColumnTracker explicit = new ExplicitColumnTracker(columns, 0, maxVersions, Long.MIN_VALUE);
156 for (int i = 0; i < 100000; i += 2) {
157 byte[] col = Bytes.toBytes("col" + i);
158 ScanQueryMatcher.checkColumn(explicit, col, 0, col.length, 1, KeyValue.Type.Put.getCode(),
159 false);
160 }
161 explicit.reset();
162
163 for (int i = 1; i < 100000; i += 2) {
164 byte[] col = Bytes.toBytes("col" + i);
165 ScanQueryMatcher.checkColumn(explicit, col, 0, col.length, 1, KeyValue.Type.Put.getCode(),
166 false);
167 }
168 }
169
170
171
172
173 @Test
174 public void testInfiniteLoop() throws IOException {
175 TreeSet<byte[]> columns = new TreeSet<byte[]>(Bytes.BYTES_COMPARATOR);
176 columns.addAll(Arrays.asList(new byte[][] { col2, col3, col5 }));
177 List<byte[]> scanner = Arrays.<byte[]> asList(new byte[][] { col1, col4 });
178 List<ScanQueryMatcher.MatchCode> expected =
179 Arrays.<ScanQueryMatcher.MatchCode> asList(new ScanQueryMatcher.MatchCode[] {
180 ScanQueryMatcher.MatchCode.SEEK_NEXT_COL, ScanQueryMatcher.MatchCode.SEEK_NEXT_COL });
181 runTest(1, columns, scanner, expected);
182 }
183
184 }