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.util.Classes;
25
26 import java.io.DataInput;
27 import java.io.DataOutput;
28 import java.io.IOException;
29
30 /**
31 * A wrapper filter that filters an entire row if any of the KeyValue checks do
32 * not pass.
33 * <p>
34 * For example, if all columns in a row represent weights of different things,
35 * with the values being the actual weights, and we want to filter out the
36 * entire row if any of its weights are zero. In this case, we want to prevent
37 * rows from being emitted if a single key is filtered. Combine this filter
38 * with a {@link ValueFilter}:
39 * <p>
40 * <pre>
41 * scan.setFilter(new SkipFilter(new ValueFilter(CompareOp.EQUAL,
42 * new BinaryComparator(Bytes.toBytes(0))));
43 * </code>
44 * Any row which contained a column whose value was 0 will be filtered out.
45 * Without this filter, the other non-zero valued columns in the row would still
46 * be emitted.
47 */
48 public class SkipFilter extends FilterBase {
49 private boolean filterRow = false;
50 private Filter filter;
51
52 public SkipFilter() {
53 super();
54 }
55
56 public SkipFilter(Filter filter) {
57 this.filter = filter;
58 }
59
60 public Filter getFilter() {
61 return filter;
62 }
63
64 public void reset() {
65 filter.reset();
66 filterRow = false;
67 }
68
69 private void changeFR(boolean value) {
70 filterRow = filterRow || value;
71 }
72
73 public ReturnCode filterKeyValue(KeyValue v) {
74 ReturnCode c = filter.filterKeyValue(v);
75 changeFR(c != ReturnCode.INCLUDE);
76 return c;
77 }
78
79 @Override
80 public KeyValue transform(KeyValue v) {
81 return filter.transform(v);
82 }
83
84 public boolean filterRow() {
85 return filterRow;
86 }
87
88 public void write(DataOutput out) throws IOException {
89 out.writeUTF(this.filter.getClass().getName());
90 this.filter.write(out);
91 }
92
93 public void readFields(DataInput in) throws IOException {
94 this.filter = Classes.createForName(in.readUTF());
95 this.filter.readFields(in);
96 }
97
98 public boolean isFamilyEssential(byte[] name) {
99 return FilterBase.isFamilyEssential(this.filter, name);
100 }
101
102 @Override
103 public String toString() {
104 return this.getClass().getSimpleName() + " " + this.filter.toString();
105 }
106 }