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.util.ByteStringer;
24 import com.google.protobuf.InvalidProtocolBufferException;
25
26 import org.apache.hadoop.hbase.classification.InterfaceAudience;
27 import org.apache.hadoop.hbase.classification.InterfaceStability;
28 import org.apache.hadoop.hbase.Cell;
29 import org.apache.hadoop.hbase.exceptions.DeserializationException;
30 import org.apache.hadoop.hbase.protobuf.generated.FilterProtos;
31 import org.apache.hadoop.hbase.util.Bytes;
32
33 import java.util.ArrayList;
34
35
36
37
38 @InterfaceAudience.Public
39 @InterfaceStability.Stable
40 public class PrefixFilter extends FilterBase {
41 public static final int MAX_SKIPPED_COMPARE_ROW_NUM = 100;
42 protected byte [] prefix = null;
43 protected boolean passedPrefix = false;
44 protected boolean filterRow = true;
45 protected int skippedCompareRows = 0;
46
47 public PrefixFilter(final byte [] prefix) {
48 this.prefix = prefix;
49 }
50
51 public byte[] getPrefix() {
52 return prefix;
53 }
54
55 public boolean filterRowKey(byte[] buffer, int offset, int length) {
56 if (buffer == null || this.prefix == null)
57 return true;
58 if (length < prefix.length && skippedCompareRows < MAX_SKIPPED_COMPARE_ROW_NUM) {
59 ++skippedCompareRows;
60 return true;
61 }
62 skippedCompareRows = 0;
63
64
65
66
67 int cmp = Bytes.compareTo(buffer, offset, this.prefix.length, this.prefix, 0,
68 this.prefix.length);
69 if ((!isReversed() && cmp > 0) || (isReversed() && cmp < 0)) {
70 passedPrefix = true;
71 }
72 filterRow = (cmp != 0);
73 return filterRow;
74 }
75
76 @Override
77 public ReturnCode filterKeyValue(Cell v) {
78 if (filterRow) return ReturnCode.NEXT_ROW;
79 return ReturnCode.INCLUDE;
80 }
81
82 public boolean filterRow() {
83 return filterRow;
84 }
85
86 public void reset() {
87 filterRow = true;
88 }
89
90 public boolean filterAllRemaining() {
91 return passedPrefix;
92 }
93
94 public static Filter createFilterFromArguments(ArrayList<byte []> filterArguments) {
95 Preconditions.checkArgument(filterArguments.size() == 1,
96 "Expected 1 but got: %s", filterArguments.size());
97 byte [] prefix = ParseFilter.removeQuotesFromByteArray(filterArguments.get(0));
98 return new PrefixFilter(prefix);
99 }
100
101
102
103
104 public byte [] toByteArray() {
105 FilterProtos.PrefixFilter.Builder builder =
106 FilterProtos.PrefixFilter.newBuilder();
107 if (this.prefix != null) builder.setPrefix(ByteStringer.wrap(this.prefix));
108 return builder.build().toByteArray();
109 }
110
111
112
113
114
115
116
117 public static PrefixFilter parseFrom(final byte [] pbBytes)
118 throws DeserializationException {
119 FilterProtos.PrefixFilter proto;
120 try {
121 proto = FilterProtos.PrefixFilter.parseFrom(pbBytes);
122 } catch (InvalidProtocolBufferException e) {
123 throw new DeserializationException(e);
124 }
125 return new PrefixFilter(proto.hasPrefix()?proto.getPrefix().toByteArray():null);
126 }
127
128
129
130
131
132
133 boolean areSerializedFieldsEqual(Filter o) {
134 if (o == this) return true;
135 if (!(o instanceof PrefixFilter)) return false;
136
137 PrefixFilter other = (PrefixFilter)o;
138 return Bytes.equals(this.getPrefix(), other.getPrefix());
139 }
140
141 @Override
142 public String toString() {
143 return this.getClass().getSimpleName() + " " + Bytes.toStringBinary(this.prefix);
144 }
145 }