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.filter;
22
23 import org.apache.hadoop.hbase.KeyValue;
24 import org.apache.hadoop.hbase.util.Bytes;
25
26 import java.io.DataOutput;
27 import java.io.IOException;
28 import java.io.DataInput;
29 import java.util.ArrayList;
30
31 import com.google.common.base.Preconditions;
32
33
34
35
36
37
38
39
40
41
42
43
44
45 public class ColumnRangeFilter extends FilterBase {
46 protected byte[] minColumn = null;
47 protected boolean minColumnInclusive = true;
48 protected byte[] maxColumn = null;
49 protected boolean maxColumnInclusive = false;
50
51 public ColumnRangeFilter() {
52 super();
53 }
54
55
56
57
58
59
60
61
62
63
64 public ColumnRangeFilter(final byte[] minColumn, boolean minColumnInclusive,
65 final byte[] maxColumn, boolean maxColumnInclusive) {
66 this.minColumn = minColumn;
67 this.minColumnInclusive = minColumnInclusive;
68 this.maxColumn = maxColumn;
69 this.maxColumnInclusive = maxColumnInclusive;
70 }
71
72
73
74
75 public boolean isMinColumnInclusive() {
76 return minColumnInclusive;
77 }
78
79
80
81
82 public boolean isMaxColumnInclusive() {
83 return maxColumnInclusive;
84 }
85
86
87
88
89 public byte[] getMinColumn() {
90 return this.minColumn;
91 }
92
93
94
95
96 public boolean getMinColumnInclusive() {
97 return this.minColumnInclusive;
98 }
99
100
101
102
103 public byte[] getMaxColumn() {
104 return this.maxColumn;
105 }
106
107
108
109
110 public boolean getMaxColumnInclusive() {
111 return this.maxColumnInclusive;
112 }
113
114 @Override
115 public ReturnCode filterKeyValue(KeyValue kv) {
116 byte[] buffer = kv.getBuffer();
117 int qualifierOffset = kv.getQualifierOffset();
118 int qualifierLength = kv.getQualifierLength();
119 int cmpMin = 1;
120
121 if (this.minColumn != null) {
122 cmpMin = Bytes.compareTo(buffer, qualifierOffset, qualifierLength,
123 this.minColumn, 0, this.minColumn.length);
124 }
125
126 if (cmpMin < 0) {
127 return ReturnCode.SEEK_NEXT_USING_HINT;
128 }
129
130 if (!this.minColumnInclusive && cmpMin == 0) {
131 return ReturnCode.SKIP;
132 }
133
134 if (this.maxColumn == null) {
135 return ReturnCode.INCLUDE;
136 }
137
138 int cmpMax = Bytes.compareTo(buffer, qualifierOffset, qualifierLength,
139 this.maxColumn, 0, this.maxColumn.length);
140
141 if (this.maxColumnInclusive && cmpMax <= 0 ||
142 !this.maxColumnInclusive && cmpMax < 0) {
143 return ReturnCode.INCLUDE;
144 }
145
146 return ReturnCode.NEXT_ROW;
147 }
148
149 public static Filter createFilterFromArguments(ArrayList<byte []> filterArguments) {
150 Preconditions.checkArgument(filterArguments.size() == 4,
151 "Expected 4 but got: %s", filterArguments.size());
152 byte [] minColumn = ParseFilter.removeQuotesFromByteArray(filterArguments.get(0));
153 boolean minColumnInclusive = ParseFilter.convertByteArrayToBoolean(filterArguments.get(1));
154 byte [] maxColumn = ParseFilter.removeQuotesFromByteArray(filterArguments.get(2));
155 boolean maxColumnInclusive = ParseFilter.convertByteArrayToBoolean(filterArguments.get(3));
156
157 if (minColumn.length == 0)
158 minColumn = null;
159 if (maxColumn.length == 0)
160 maxColumn = null;
161 return new ColumnRangeFilter(minColumn, minColumnInclusive,
162 maxColumn, maxColumnInclusive);
163 }
164
165 @Override
166 public void write(DataOutput out) throws IOException {
167
168
169 out.writeBoolean(this.minColumn == null);
170 Bytes.writeByteArray(out, this.minColumn);
171 out.writeBoolean(this.minColumnInclusive);
172
173 out.writeBoolean(this.maxColumn == null);
174 Bytes.writeByteArray(out, this.maxColumn);
175 out.writeBoolean(this.maxColumnInclusive);
176 }
177
178 @Override
179 public void readFields(DataInput in) throws IOException {
180 boolean isMinColumnNull = in.readBoolean();
181 this.minColumn = Bytes.readByteArray(in);
182
183 if (isMinColumnNull) {
184 this.minColumn = null;
185 }
186
187 this.minColumnInclusive = in.readBoolean();
188
189 boolean isMaxColumnNull = in.readBoolean();
190 this.maxColumn = Bytes.readByteArray(in);
191 if (isMaxColumnNull) {
192 this.maxColumn = null;
193 }
194 this.maxColumnInclusive = in.readBoolean();
195 }
196
197
198 @Override
199 public KeyValue getNextKeyHint(KeyValue kv) {
200 return KeyValue.createFirstOnRow(kv.getBuffer(), kv.getRowOffset(), kv
201 .getRowLength(), kv.getBuffer(), kv.getFamilyOffset(), kv
202 .getFamilyLength(), this.minColumn, 0, this.minColumn == null ? 0
203 : this.minColumn.length);
204 }
205
206 @Override
207 public String toString() {
208 return this.getClass().getSimpleName() + " "
209 + (this.minColumnInclusive ? "[" : "(") + Bytes.toStringBinary(this.minColumn)
210 + ", " + Bytes.toStringBinary(this.maxColumn)
211 + (this.maxColumnInclusive ? "]" : ")");
212 }
213 }