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