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