1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.hadoop.hbase.hbql.filter;
22
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25 import org.apache.hadoop.hbase.KeyValue;
26 import org.apache.hadoop.hbase.filter.BinaryComparator;
27 import org.apache.hadoop.hbase.filter.CompareFilter;
28 import org.apache.hadoop.hbase.filter.WritableByteArrayComparable;
29 import org.apache.hadoop.hbase.io.HbaseObjectWritable;
30 import org.apache.hadoop.hbase.util.Bytes;
31
32 import java.io.DataInput;
33 import java.io.DataOutput;
34 import java.io.IOException;
35 import java.util.Arrays;
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 public class SingleColumnValueFilter implements InstrumentedFilter {
65 static final Log LOG = LogFactory.getLog(SingleColumnValueFilter.class);
66
67 private boolean verbose = false;
68 private byte[] columnFamily;
69 private byte[] columnQualifier;
70 private CompareFilter.CompareOp compareOp;
71 private WritableByteArrayComparable comparator;
72 private boolean foundColumn = false;
73 private boolean matchedColumn = false;
74 private boolean filterIfMissing = false;
75 private boolean latestVersionOnly = true;
76
77
78
79
80 public SingleColumnValueFilter() {
81 }
82
83
84
85
86
87
88
89
90
91
92
93
94 public SingleColumnValueFilter(final byte[] family, final byte[] qualifier,
95 final CompareFilter.CompareOp compareOp, final byte[] value) {
96 this(family, qualifier, compareOp, new BinaryComparator(value));
97 }
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113 public SingleColumnValueFilter(final byte[] family, final byte[] qualifier,
114 final CompareFilter.CompareOp compareOp, final WritableByteArrayComparable comparator) {
115 this.columnFamily = family;
116 this.columnQualifier = qualifier;
117 this.compareOp = compareOp;
118 this.comparator = comparator;
119 }
120
121 public void setVerbose(final boolean verbose) {
122 this.verbose = verbose;
123 }
124
125 public boolean getVerbose() {
126 return this.verbose;
127 }
128
129 public boolean filterRowKey(byte[] rowKey, int offset, int length) {
130
131
132 return false;
133 }
134
135 public ReturnCode filterKeyValue(KeyValue keyValue) {
136
137 if (this.matchedColumn) {
138
139 return ReturnCode.INCLUDE;
140 }
141 else if (this.latestVersionOnly && this.foundColumn) {
142
143 return ReturnCode.NEXT_ROW;
144 }
145 if (!keyValue.matchingColumn(this.columnFamily, this.columnQualifier)) {
146 return ReturnCode.INCLUDE;
147 }
148 foundColumn = true;
149 if (filterColumnValue(keyValue.getBuffer(),
150 keyValue.getValueOffset(), keyValue.getValueLength())) {
151 return this.latestVersionOnly ? ReturnCode.NEXT_ROW : ReturnCode.INCLUDE;
152 }
153 this.matchedColumn = true;
154 return ReturnCode.INCLUDE;
155 }
156
157 private boolean filterColumnValue(final byte[] data, final int offset,
158 final int length) {
159
160
161 int compareResult = this.comparator.compareTo(Arrays.copyOfRange(data, offset, offset + length));
162
163 if (this.getVerbose())
164 LOG.debug("compareResult=" + compareResult + " " + Bytes.toString(data, offset, length));
165
166 switch (this.compareOp) {
167 case LESS:
168 return compareResult <= 0;
169 case LESS_OR_EQUAL:
170 return compareResult < 0;
171 case EQUAL:
172 return compareResult != 0;
173 case NOT_EQUAL:
174 return compareResult == 0;
175 case GREATER_OR_EQUAL:
176 return compareResult > 0;
177 case GREATER:
178 return compareResult >= 0;
179 default:
180 throw new RuntimeException("Unknown Compare op " + compareOp.name());
181 }
182 }
183
184 public boolean filterAllRemaining() {
185 return false;
186 }
187
188 public boolean filterRow() {
189
190
191 return this.foundColumn ? !this.matchedColumn : this.filterIfMissing;
192 }
193
194 public void reset() {
195 foundColumn = false;
196 matchedColumn = false;
197 }
198
199
200
201
202
203
204
205 public boolean getFilterIfMissing() {
206 return filterIfMissing;
207 }
208
209
210
211
212
213
214
215
216 public void setFilterIfMissing(boolean filterIfMissing) {
217 this.filterIfMissing = filterIfMissing;
218 }
219
220
221
222
223
224
225
226 public boolean getLatestVersionOnly() {
227 return latestVersionOnly;
228 }
229
230
231
232
233
234
235
236 public void setLatestVersionOnly(boolean latestVersionOnly) {
237 this.latestVersionOnly = latestVersionOnly;
238 }
239
240 public void readFields(final DataInput in) throws IOException {
241
242 this.verbose = in.readBoolean();
243
244 this.columnFamily = Bytes.readByteArray(in);
245 if (this.columnFamily.length == 0) {
246 this.columnFamily = null;
247 }
248 this.columnQualifier = Bytes.readByteArray(in);
249 if (this.columnQualifier.length == 0) {
250 this.columnQualifier = null;
251 }
252 this.compareOp = CompareFilter.CompareOp.valueOf(in.readUTF());
253 this.comparator =
254 (WritableByteArrayComparable)HbaseObjectWritable.readObject(in, null);
255 this.foundColumn = in.readBoolean();
256 this.matchedColumn = in.readBoolean();
257 this.filterIfMissing = in.readBoolean();
258 this.latestVersionOnly = in.readBoolean();
259 }
260
261 public void write(final DataOutput out) throws IOException {
262
263 out.writeBoolean(this.getVerbose());
264
265 Bytes.writeByteArray(out, this.columnFamily);
266 Bytes.writeByteArray(out, this.columnQualifier);
267 out.writeUTF(compareOp.name());
268 HbaseObjectWritable.writeObject(out, comparator,
269 WritableByteArrayComparable.class, null);
270 out.writeBoolean(foundColumn);
271 out.writeBoolean(matchedColumn);
272 out.writeBoolean(filterIfMissing);
273 out.writeBoolean(latestVersionOnly);
274 }
275 }