1 /* 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 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.exceptions.DeserializationException; 29 import org.apache.hadoop.hbase.protobuf.generated.FilterProtos; 30 import org.apache.hadoop.hbase.util.Bytes; 31 32 import com.google.common.base.Preconditions; 33 import com.google.protobuf.InvalidProtocolBufferException; 34 35 /** 36 * A Filter that stops after the given row. There is no "RowStopFilter" because 37 * the Scan spec allows you to specify a stop row. 38 * 39 * Use this filter to include the stop row, eg: [A,Z]. 40 */ 41 @InterfaceAudience.Public 42 @InterfaceStability.Stable 43 public class InclusiveStopFilter extends FilterBase { 44 private byte [] stopRowKey; 45 private boolean done = false; 46 InclusiveStopFilter(final byte [] stopRowKey)47 public InclusiveStopFilter(final byte [] stopRowKey) { 48 this.stopRowKey = stopRowKey; 49 } 50 getStopRowKey()51 public byte[] getStopRowKey() { 52 return this.stopRowKey; 53 } 54 55 @Override filterKeyValue(Cell v)56 public ReturnCode filterKeyValue(Cell v) { 57 if (done) return ReturnCode.NEXT_ROW; 58 return ReturnCode.INCLUDE; 59 } 60 61 // Override here explicitly as the method in super class FilterBase might do a KeyValue recreate. 62 // See HBASE-12068 63 @Override transformCell(Cell v)64 public Cell transformCell(Cell v) { 65 return v; 66 } 67 filterRowKey(byte[] buffer, int offset, int length)68 public boolean filterRowKey(byte[] buffer, int offset, int length) { 69 if (buffer == null) { 70 //noinspection RedundantIfStatement 71 if (this.stopRowKey == null) { 72 return true; //filter... 73 } 74 return false; 75 } 76 // if stopRowKey is <= buffer, then true, filter row. 77 int cmp = Bytes.compareTo(stopRowKey, 0, stopRowKey.length, 78 buffer, offset, length); 79 80 if(cmp < 0) { 81 done = true; 82 } 83 return done; 84 } 85 filterAllRemaining()86 public boolean filterAllRemaining() { 87 return done; 88 } 89 createFilterFromArguments(ArrayList<byte []> filterArguments)90 public static Filter createFilterFromArguments (ArrayList<byte []> filterArguments) { 91 Preconditions.checkArgument(filterArguments.size() == 1, 92 "Expected 1 but got: %s", filterArguments.size()); 93 byte [] stopRowKey = ParseFilter.removeQuotesFromByteArray(filterArguments.get(0)); 94 return new InclusiveStopFilter(stopRowKey); 95 } 96 97 /** 98 * @return The filter serialized using pb 99 */ toByteArray()100 public byte [] toByteArray() { 101 FilterProtos.InclusiveStopFilter.Builder builder = 102 FilterProtos.InclusiveStopFilter.newBuilder(); 103 if (this.stopRowKey != null) builder.setStopRowKey(ByteStringer.wrap(this.stopRowKey)); 104 return builder.build().toByteArray(); 105 } 106 107 /** 108 * @param pbBytes A pb serialized {@link InclusiveStopFilter} instance 109 * @return An instance of {@link InclusiveStopFilter} made from <code>bytes</code> 110 * @throws DeserializationException 111 * @see #toByteArray 112 */ parseFrom(final byte [] pbBytes)113 public static InclusiveStopFilter parseFrom(final byte [] pbBytes) 114 throws DeserializationException { 115 FilterProtos.InclusiveStopFilter proto; 116 try { 117 proto = FilterProtos.InclusiveStopFilter.parseFrom(pbBytes); 118 } catch (InvalidProtocolBufferException e) { 119 throw new DeserializationException(e); 120 } 121 return new InclusiveStopFilter(proto.hasStopRowKey()?proto.getStopRowKey().toByteArray():null); 122 } 123 124 /** 125 * @param other 126 * @return true if and only if the fields of the filter that are serialized 127 * are equal to the corresponding fields in other. Used for testing. 128 */ areSerializedFieldsEqual(Filter o)129 boolean areSerializedFieldsEqual(Filter o) { 130 if (o == this) return true; 131 if (!(o instanceof InclusiveStopFilter)) return false; 132 133 InclusiveStopFilter other = (InclusiveStopFilter)o; 134 return Bytes.equals(this.getStopRowKey(), other.getStopRowKey()); 135 } 136 137 @Override toString()138 public String toString() { 139 return this.getClass().getSimpleName() + " " + Bytes.toStringBinary(this.stopRowKey); 140 } 141 } 142