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
24 import org.apache.hadoop.hbase.classification.InterfaceAudience;
25 import org.apache.hadoop.hbase.CellUtil;
26 import org.apache.hadoop.hbase.HConstants;
27 import org.apache.hadoop.hbase.regionserver.ScanQueryMatcher.MatchCode;
28 import org.apache.hadoop.hbase.util.Bytes;
29
30
31
32
33 @InterfaceAudience.Private
34 public class ScanWildcardColumnTracker implements ColumnTracker {
35 private byte [] columnBuffer = null;
36 private int columnOffset = 0;
37 private int columnLength = 0;
38 private int currentCount = 0;
39 private int maxVersions;
40 private int minVersions;
41
42
43 private long latestTSOfCurrentColumn;
44 private byte latestTypeOfCurrentColumn;
45
46 private long oldestStamp;
47
48
49
50
51
52
53
54
55 public ScanWildcardColumnTracker(int minVersion, int maxVersion,
56 long oldestUnexpiredTS) {
57 this.maxVersions = maxVersion;
58 this.minVersions = minVersion;
59 this.oldestStamp = oldestUnexpiredTS;
60 }
61
62
63
64
65
66 @Override
67 public MatchCode checkColumn(byte[] bytes, int offset, int length, byte type)
68 throws IOException {
69 return MatchCode.INCLUDE;
70 }
71
72
73
74
75
76
77 @Override
78 public ScanQueryMatcher.MatchCode checkVersions(byte[] bytes, int offset, int length,
79 long timestamp, byte type, boolean ignoreCount) throws IOException {
80
81 if (columnBuffer == null) {
82
83 resetBuffer(bytes, offset, length);
84 if (ignoreCount) return ScanQueryMatcher.MatchCode.INCLUDE;
85
86 return checkVersion(type, timestamp);
87 }
88 int cmp = Bytes.compareTo(bytes, offset, length,
89 columnBuffer, columnOffset, columnLength);
90 if (cmp == 0) {
91 if (ignoreCount) return ScanQueryMatcher.MatchCode.INCLUDE;
92
93
94 if (sameAsPreviousTSAndType(timestamp, type)) {
95 return ScanQueryMatcher.MatchCode.SKIP;
96 }
97 return checkVersion(type, timestamp);
98 }
99
100 resetTSAndType();
101
102
103 if (cmp > 0) {
104
105 resetBuffer(bytes, offset, length);
106 if (ignoreCount) return ScanQueryMatcher.MatchCode.INCLUDE;
107 return checkVersion(type, timestamp);
108 }
109
110
111
112
113
114 throw new IOException(
115 "ScanWildcardColumnTracker.checkColumn ran into a column actually " +
116 "smaller than the previous column: " +
117 Bytes.toStringBinary(bytes, offset, length));
118 }
119
120 private void resetBuffer(byte[] bytes, int offset, int length) {
121 columnBuffer = bytes;
122 columnOffset = offset;
123 columnLength = length;
124 currentCount = 0;
125 }
126
127
128
129
130
131
132
133
134
135
136 private MatchCode checkVersion(byte type, long timestamp) {
137 if (!CellUtil.isDelete(type)) {
138 currentCount++;
139 }
140 if (currentCount > maxVersions) {
141 return ScanQueryMatcher.MatchCode.SEEK_NEXT_COL;
142 }
143
144 if (currentCount <= minVersions || !isExpired(timestamp)) {
145 setTSAndType(timestamp, type);
146 return ScanQueryMatcher.MatchCode.INCLUDE;
147 } else {
148 return MatchCode.SEEK_NEXT_COL;
149 }
150
151 }
152
153 @Override
154 public void reset() {
155 columnBuffer = null;
156 resetTSAndType();
157 }
158
159 private void resetTSAndType() {
160 latestTSOfCurrentColumn = HConstants.LATEST_TIMESTAMP;
161 latestTypeOfCurrentColumn = 0;
162 }
163
164 private void setTSAndType(long timestamp, byte type) {
165 latestTSOfCurrentColumn = timestamp;
166 latestTypeOfCurrentColumn = type;
167 }
168
169 private boolean sameAsPreviousTSAndType(long timestamp, byte type) {
170 return timestamp == latestTSOfCurrentColumn && type == latestTypeOfCurrentColumn;
171 }
172
173 private boolean isExpired(long timestamp) {
174 return timestamp < oldestStamp;
175 }
176
177
178
179
180
181
182
183
184 public ColumnCount getColumnHint() {
185 return null;
186 }
187
188
189
190
191
192 @Override
193 public boolean done() {
194 return false;
195 }
196
197 public MatchCode getNextRowOrNextColumn(byte[] bytes, int offset,
198 int qualLength) {
199 return MatchCode.SEEK_NEXT_COL;
200 }
201
202 public boolean isDone(long timestamp) {
203 return minVersions <= 0 && isExpired(timestamp);
204 }
205 }