View Javadoc

1   /**
2    * Copyright 2010 The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  
21  package org.apache.hadoop.hbase.filter;
22  
23  import org.apache.hadoop.hbase.KeyValue;
24  import org.apache.hadoop.hbase.io.HbaseObjectWritable;
25  
26  import java.io.DataInput;
27  import java.io.DataOutput;
28  import java.io.IOException;
29  import java.util.Arrays;
30  import java.util.ArrayList;
31  
32  import com.google.common.base.Preconditions;
33  /**
34   * This is a generic filter to be used to filter by comparison.  It takes an
35   * operator (equal, greater, not equal, etc) and a byte [] comparator.
36   * <p>
37   * To filter by row key, use {@link RowFilter}.
38   * <p>
39   * To filter by column qualifier, use {@link QualifierFilter}.
40   * <p>
41   * To filter by value, use {@link SingleColumnValueFilter}.
42   * <p>
43   * These filters can be wrapped with {@link SkipFilter} and {@link WhileMatchFilter}
44   * to add more control.
45   * <p>
46   * Multiple filters can be combined using {@link FilterList}.
47   */
48  public abstract class CompareFilter extends FilterBase {
49  
50    /** Comparison operators. */
51    public enum CompareOp {
52      /** less than */
53      LESS,
54      /** less than or equal to */
55      LESS_OR_EQUAL,
56      /** equals */
57      EQUAL,
58      /** not equal */
59      NOT_EQUAL,
60      /** greater than or equal to */
61      GREATER_OR_EQUAL,
62      /** greater than */
63      GREATER,
64      /** no operation */
65      NO_OP,
66    }
67  
68    protected CompareOp compareOp;
69    protected WritableByteArrayComparable comparator;
70  
71    /**
72     * Writable constructor, do not use.
73     */
74    public CompareFilter() {
75    }
76  
77    /**
78     * Constructor.
79     * @param compareOp the compare op for row matching
80     * @param comparator the comparator for row matching
81     */
82    public CompareFilter(final CompareOp compareOp,
83        final WritableByteArrayComparable comparator) {
84      this.compareOp = compareOp;
85      this.comparator = comparator;
86    }
87  
88    /**
89     * @return operator
90     */
91    public CompareOp getOperator() {
92      return compareOp;
93    }
94  
95    /**
96     * @return the comparator
97     */
98    public WritableByteArrayComparable getComparator() {
99      return comparator;
100   }
101 
102   protected boolean doCompare(final CompareOp compareOp,
103       final WritableByteArrayComparable comparator, final byte [] data,
104       final int offset, final int length) {
105       if (compareOp == CompareOp.NO_OP) {
106 	  return true;
107       }
108     int compareResult =
109       comparator.compareTo(Arrays.copyOfRange(data, offset,
110         offset + length));
111     switch (compareOp) {
112       case LESS:
113         return compareResult <= 0;
114       case LESS_OR_EQUAL:
115         return compareResult < 0;
116       case EQUAL:
117         return compareResult != 0;
118       case NOT_EQUAL:
119         return compareResult == 0;
120       case GREATER_OR_EQUAL:
121         return compareResult > 0;
122       case GREATER:
123         return compareResult >= 0;
124       default:
125         throw new RuntimeException("Unknown Compare op " +
126           compareOp.name());
127     }
128   }
129 
130   public static ArrayList extractArguments(ArrayList<byte []> filterArguments) {
131     Preconditions.checkArgument(filterArguments.size() == 2,
132                                 "Expected 2 but got: %s", filterArguments.size());
133     CompareOp compareOp = ParseFilter.createCompareOp(filterArguments.get(0));
134     WritableByteArrayComparable comparator = ParseFilter.createComparator(
135       ParseFilter.removeQuotesFromByteArray(filterArguments.get(1)));
136 
137     if (comparator instanceof RegexStringComparator ||
138         comparator instanceof SubstringComparator) {
139       if (compareOp != CompareOp.EQUAL &&
140           compareOp != CompareOp.NOT_EQUAL) {
141         throw new IllegalArgumentException ("A regexstring comparator and substring comparator" +
142                                             " can only be used with EQUAL and NOT_EQUAL");
143       }
144     }
145     ArrayList arguments = new ArrayList();
146     arguments.add(compareOp);
147     arguments.add(comparator);
148     return arguments;
149   }
150 
151   public void readFields(DataInput in) throws IOException {
152     compareOp = CompareOp.valueOf(in.readUTF());
153     comparator = (WritableByteArrayComparable)
154       HbaseObjectWritable.readObject(in, null);
155   }
156 
157   public void write(DataOutput out) throws IOException {
158     out.writeUTF(compareOp.name());
159     HbaseObjectWritable.writeObject(out, comparator,
160       WritableByteArrayComparable.class, null);
161   }
162 }