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.filter;
21
22 import com.google.common.base.Preconditions;
23 import org.apache.hadoop.hbase.classification.InterfaceAudience;
24 import org.apache.hadoop.hbase.Cell;
25 import org.apache.hadoop.hbase.classification.InterfaceStability;
26 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
27 import org.apache.hadoop.hbase.protobuf.generated.FilterProtos;
28 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
29 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.CompareType;
30 import org.apache.hadoop.hbase.util.Bytes;
31
32 import java.util.ArrayList;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 @InterfaceAudience.Public
49 @InterfaceStability.Stable
50 public abstract class CompareFilter extends FilterBase {
51
52
53 @InterfaceAudience.Public
54 @InterfaceStability.Stable
55 public enum CompareOp {
56
57 LESS,
58
59 LESS_OR_EQUAL,
60
61 EQUAL,
62
63 NOT_EQUAL,
64
65 GREATER_OR_EQUAL,
66
67 GREATER,
68
69 NO_OP,
70 }
71
72 protected CompareOp compareOp;
73 protected ByteArrayComparable comparator;
74
75
76
77
78
79
80 public CompareFilter(final CompareOp compareOp,
81 final ByteArrayComparable comparator) {
82 this.compareOp = compareOp;
83 this.comparator = comparator;
84 }
85
86
87
88
89 public CompareOp getOperator() {
90 return compareOp;
91 }
92
93
94
95
96 public ByteArrayComparable getComparator() {
97 return comparator;
98 }
99
100 protected boolean doCompare(final CompareOp compareOp,
101 final ByteArrayComparable comparator, final byte [] data,
102 final int offset, final int length) {
103 if (compareOp == CompareOp.NO_OP) {
104 return true;
105 }
106 int compareResult = comparator.compareTo(data, offset, length);
107 switch (compareOp) {
108 case LESS:
109 return compareResult <= 0;
110 case LESS_OR_EQUAL:
111 return compareResult < 0;
112 case EQUAL:
113 return compareResult != 0;
114 case NOT_EQUAL:
115 return compareResult == 0;
116 case GREATER_OR_EQUAL:
117 return compareResult > 0;
118 case GREATER:
119 return compareResult >= 0;
120 default:
121 throw new RuntimeException("Unknown Compare op " +
122 compareOp.name());
123 }
124 }
125
126
127
128 @Override
129 public Cell transformCell(Cell v) {
130 return v;
131 }
132
133
134 public static ArrayList<Object> extractArguments(ArrayList<byte []> filterArguments) {
135 Preconditions.checkArgument(filterArguments.size() == 2,
136 "Expected 2 but got: %s", filterArguments.size());
137 CompareOp compareOp = ParseFilter.createCompareOp(filterArguments.get(0));
138 ByteArrayComparable comparator = ParseFilter.createComparator(
139 ParseFilter.removeQuotesFromByteArray(filterArguments.get(1)));
140
141 if (comparator instanceof RegexStringComparator ||
142 comparator instanceof SubstringComparator) {
143 if (compareOp != CompareOp.EQUAL &&
144 compareOp != CompareOp.NOT_EQUAL) {
145 throw new IllegalArgumentException ("A regexstring comparator and substring comparator" +
146 " can only be used with EQUAL and NOT_EQUAL");
147 }
148 }
149 ArrayList<Object> arguments = new ArrayList<Object>();
150 arguments.add(compareOp);
151 arguments.add(comparator);
152 return arguments;
153 }
154
155
156
157
158 FilterProtos.CompareFilter convert() {
159 FilterProtos.CompareFilter.Builder builder =
160 FilterProtos.CompareFilter.newBuilder();
161 HBaseProtos.CompareType compareOp = CompareType.valueOf(this.compareOp.name());
162 builder.setCompareOp(compareOp);
163 if (this.comparator != null) builder.setComparator(ProtobufUtil.toComparator(this.comparator));
164 return builder.build();
165 }
166
167
168
169
170
171
172
173 boolean areSerializedFieldsEqual(Filter o) {
174 if (o == this) return true;
175 if (!(o instanceof CompareFilter)) return false;
176
177 CompareFilter other = (CompareFilter)o;
178 return this.getOperator().equals(other.getOperator()) &&
179 (this.getComparator() == other.getComparator()
180 || this.getComparator().areSerializedFieldsEqual(other.getComparator()));
181 }
182
183 @Override
184 public String toString() {
185 return String.format("%s (%s, %s)",
186 this.getClass().getSimpleName(),
187 this.compareOp.name(),
188 Bytes.toStringBinary(this.comparator.getValue()));
189 }
190 }